stm32: support SPI on L4 series

This commit is contained in:
Kenneth Bell
2021-04-11 08:28:04 -07:00
committed by Ron Evans
parent b9043b649d
commit 25f3adb47e
9 changed files with 138 additions and 12 deletions
+64
View File
@@ -182,3 +182,67 @@ func enableAltFuncClock(bus unsafe.Pointer) {
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_TIM1EN)
}
}
//---------- SPI related types and code
// SPI on the STM32Fxxx using MODER / alternate function pins
type SPI struct {
Bus *stm32.SPI_Type
AltFuncSelector uint8
}
func (spi SPI) config8Bits() {
// Set rx threshold to 8-bits, so RXNE flag is set for 1 byte
// (common STM32 SPI implementation does 8-bit transfers only)
spi.Bus.CR2.SetBits(stm32.SPI_CR2_FRXTH)
}
// Set baud rate for SPI
func (spi SPI) getBaudRate(config SPIConfig) uint32 {
var conf uint32
// Default
if config.Frequency == 0 {
config.Frequency = 4e6
}
localFrequency := config.Frequency
// set frequency dependent on PCLK prescaler. Since these are rather weird
// speeds due to the CPU freqency, pick a range up to that frquency for
// clients to use more human-understandable numbers, e.g. nearest 100KHz
// These are based on 80MHz peripheral clock frquency
switch {
case localFrequency < 312500:
conf = stm32.SPI_CR1_BR_Div256
case localFrequency < 625000:
conf = stm32.SPI_CR1_BR_Div128
case localFrequency < 1250000:
conf = stm32.SPI_CR1_BR_Div64
case localFrequency < 2500000:
conf = stm32.SPI_CR1_BR_Div32
case localFrequency < 5000000:
conf = stm32.SPI_CR1_BR_Div16
case localFrequency < 10000000:
conf = stm32.SPI_CR1_BR_Div8
// NOTE: many SPI components won't operate reliably (or at all) above 10MHz
// Check the datasheet of the part
case localFrequency < 20000000:
conf = stm32.SPI_CR1_BR_Div4
case localFrequency < 40000000:
conf = stm32.SPI_CR1_BR_Div2
default:
// None of the specific baudrates were selected; choose the lowest speed
conf = stm32.SPI_CR1_BR_Div256
}
return conf << stm32.SPI_CR1_BR_Pos
}
// Configure SPI pins for input output and clock
func (spi SPI) configurePins(config SPIConfig) {
config.SCK.ConfigureAltFunc(PinConfig{Mode: PinModeSPICLK}, spi.AltFuncSelector)
config.SDO.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDO}, spi.AltFuncSelector)
config.SDI.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDI}, spi.AltFuncSelector)
}