github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/machine_stm32_adc_f1.go (about) 1 //go:build stm32f103 2 3 package machine 4 5 import ( 6 "device/stm32" 7 "unsafe" 8 ) 9 10 const ( 11 Cycles_1_5 = 0x0 12 Cycles_7_5 = 0x1 13 Cycles_13_5 = 0x2 14 Cycles_28_5 = 0x3 15 Cycles_41_5 = 0x4 16 Cycles_55_5 = 0x5 17 Cycles_71_5 = 0x6 18 Cycles_239_5 = 0x7 19 ) 20 21 // InitADC initializes the registers needed for ADC1. 22 func InitADC() { 23 // Enable ADC clock 24 enableAltFuncClock(unsafe.Pointer(stm32.ADC1)) 25 26 // set scan mode 27 stm32.ADC1.CR1.SetBits(stm32.ADC_CR1_SCAN) 28 29 // clear CONT, ALIGN, EXTRIG and EXTSEL bits from CR2 30 stm32.ADC1.CR2.ClearBits(stm32.ADC_CR2_CONT | stm32.ADC_CR2_ALIGN | stm32.ADC_CR2_EXTTRIG_Msk | stm32.ADC_CR2_EXTSEL_Msk) 31 32 stm32.ADC1.SQR1.ClearBits(stm32.ADC_SQR1_L_Msk) 33 stm32.ADC1.SQR1.SetBits(2 << stm32.ADC_SQR1_L_Pos) // 2 means 3 conversions 34 35 // enable 36 stm32.ADC1.CR2.SetBits(stm32.ADC_CR2_ADON) 37 38 return 39 } 40 41 // Configure configures an ADC pin to be able to read analog data. 42 func (a ADC) Configure(ADCConfig) { 43 a.Pin.Configure(PinConfig{Mode: PinInputModeAnalog}) 44 45 // set sample time 46 ch := a.getChannel() 47 if ch > 9 { 48 stm32.ADC1.SMPR1.SetBits(Cycles_28_5 << (ch - 10) * stm32.ADC_SMPR1_SMP11_Pos) 49 } else { 50 stm32.ADC1.SMPR2.SetBits(Cycles_28_5 << (ch * stm32.ADC_SMPR2_SMP1_Pos)) 51 } 52 53 return 54 } 55 56 // Get returns the current value of a ADC pin in the range 0..0xffff. 57 // TODO: DMA based implementation. 58 func (a ADC) Get() uint16 { 59 // set rank 60 ch := uint32(a.getChannel()) 61 stm32.ADC1.SQR3.SetBits(ch) 62 63 // start conversion 64 stm32.ADC1.CR2.SetBits(stm32.ADC_CR2_SWSTART) 65 66 // wait for conversion to complete 67 for !stm32.ADC1.SR.HasBits(stm32.ADC_SR_EOC) { 68 } 69 70 // read result as 16 bit value 71 result := uint16(stm32.ADC1.DR.Get()) << 4 72 73 // clear flag 74 stm32.ADC1.SR.ClearBits(stm32.ADC_SR_EOC) 75 76 // clear rank 77 stm32.ADC1.SQR3.ClearBits(ch) 78 79 return result 80 } 81 82 func (a ADC) getChannel() uint8 { 83 switch a.Pin { 84 case PA0: 85 return 0 86 case PA1: 87 return 1 88 case PA2: 89 return 2 90 case PA3: 91 return 3 92 case PA4: 93 return 4 94 case PA5: 95 return 5 96 case PA6: 97 return 6 98 case PA7: 99 return 7 100 case PB0: 101 return 8 102 case PB1: 103 return 9 104 } 105 106 return 0 107 }