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