//go:build stm32f103 package machine import ( "device/stm32" "unsafe" ) const ( Cycles_1_5 = 0x0 Cycles_7_5 = 0x1 Cycles_13_5 = 0x2 Cycles_28_5 = 0x3 Cycles_41_5 = 0x4 Cycles_55_5 = 0x5 Cycles_71_5 = 0x6 Cycles_239_5 = 0x7 ) // InitADC initializes the registers needed for ADC1. func InitADC() { // Enable ADC clock enableAltFuncClock(unsafe.Pointer(stm32.ADC1)) // set scan mode stm32.ADC1.CR1.SetBits(stm32.ADC_CR1_SCAN) // clear CONT, ALIGN, EXTRIG and EXTSEL bits from CR2 stm32.ADC1.CR2.ClearBits(stm32.ADC_CR2_CONT | stm32.ADC_CR2_ALIGN | stm32.ADC_CR2_EXTTRIG_Msk | stm32.ADC_CR2_EXTSEL_Msk) stm32.ADC1.SQR1.ClearBits(stm32.ADC_SQR1_L_Msk) stm32.ADC1.SQR1.SetBits(2 << stm32.ADC_SQR1_L_Pos) // 2 means 3 conversions // enable stm32.ADC1.CR2.SetBits(stm32.ADC_CR2_ADON) return } // Configure configures an ADC pin to be able to read analog data. func (a ADC) Configure(ADCConfig) { a.Pin.Configure(PinConfig{Mode: PinInputModeAnalog}) // set sample time ch := a.getChannel() if ch > 9 { stm32.ADC1.SMPR1.SetBits(Cycles_28_5 << (ch - 10) * stm32.ADC_SMPR1_SMP11_Pos) } else { stm32.ADC1.SMPR2.SetBits(Cycles_28_5 << (ch * stm32.ADC_SMPR2_SMP1_Pos)) } return } // Get returns the current value of a ADC pin in the range 0..0xffff. // TODO: DMA based implementation. func (a ADC) Get() uint16 { // set rank ch := uint32(a.getChannel()) stm32.ADC1.SQR3.SetBits(ch) // start conversion stm32.ADC1.CR2.SetBits(stm32.ADC_CR2_SWSTART) // wait for conversion to complete for !stm32.ADC1.SR.HasBits(stm32.ADC_SR_EOC) { } // read result as 16 bit value result := uint16(stm32.ADC1.DR.Get()) << 4 // clear flag stm32.ADC1.SR.ClearBits(stm32.ADC_SR_EOC) // clear rank stm32.ADC1.SQR3.ClearBits(ch) return result } func (a ADC) getChannel() uint8 { switch a.Pin { case PA0: return 0 case PA1: return 1 case PA2: return 2 case PA3: return 3 case PA4: return 4 case PA5: return 5 case PA6: return 6 case PA7: return 7 case PB0: return 8 case PB1: return 9 } return 0 }