diff options
Diffstat (limited to 'src/machine/machine_stm32f407.go')
-rw-r--r-- | src/machine/machine_stm32f407.go | 143 |
1 files changed, 38 insertions, 105 deletions
diff --git a/src/machine/machine_stm32f407.go b/src/machine/machine_stm32f407.go index c75e38771..85d9e2b25 100644 --- a/src/machine/machine_stm32f407.go +++ b/src/machine/machine_stm32f407.go @@ -2,51 +2,18 @@ package machine -// Peripheral abstraction layer for the stm32. +// Peripheral abstraction layer for the stm32f4(07) import ( "device/stm32" "runtime/interrupt" + "unsafe" ) func CPUFrequency() uint32 { return 168000000 } -const ( - // Mode Flag - PinOutput PinMode = 0 - PinInput PinMode = PinInputFloating - PinInputFloating PinMode = 1 - PinInputPulldown PinMode = 2 - PinInputPullup PinMode = 3 - - // for UART - PinModeUartTX PinMode = 4 - PinModeUartRX PinMode = 5 - - //GPIOx_MODER - GPIO_MODE_INPUT = 0 - GPIO_MODE_GENERAL_OUTPUT = 1 - GPIO_MODE_ALTERNABTIVE = 2 - GPIO_MODE_ANALOG = 3 - - //GPIOx_OTYPER - GPIO_OUTPUT_MODE_PUSH_PULL = 0 - GPIO_OUTPUT_MODE_OPEN_DRAIN = 1 - - // GPIOx_OSPEEDR - GPIO_SPEED_LOW = 0 - GPIO_SPEED_MID = 1 - GPIO_SPEED_HI = 2 - GPIO_SPEED_VERY_HI = 3 - - // GPIOx_PUPDR - GPIO_FLOATING = 0 - GPIO_PULL_UP = 1 - GPIO_PULL_DOWN = 2 -) - func (p Pin) getPort() *stm32.GPIO_Type { switch p / 16 { case 0: @@ -98,69 +65,33 @@ func (p Pin) enableClock() { } } -// Configure this pin with the given configuration. -func (p Pin) Configure(config PinConfig) { - // Configure the GPIO pin. - p.enableClock() - port := p.getPort() - pin := uint8(p) % 16 - pos := pin * 2 - - if config.Mode == PinInputFloating { - port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_INPUT) << pos))) - port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_FLOATING) << pos))) - } else if config.Mode == PinInputPulldown { - port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_INPUT) << pos))) - port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_PULL_DOWN) << pos))) - } else if config.Mode == PinInputPullup { - port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_INPUT) << pos))) - port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_PULL_UP) << pos))) - } else if config.Mode == PinOutput { - port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_GENERAL_OUTPUT) << pos))) - port.OSPEEDR.Set((uint32(port.OSPEEDR.Get())&^(0x3<<pos) | (uint32(GPIO_SPEED_HI) << pos))) - } else if config.Mode == PinModeUartTX { - port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_ALTERNABTIVE) << pos))) - port.OSPEEDR.Set((uint32(port.OSPEEDR.Get())&^(0x3<<pos) | (uint32(GPIO_SPEED_HI) << pos))) - port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_PULL_UP) << pos))) - p.setAltFunc(0x7) - } else if config.Mode == PinModeUartRX { - port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_ALTERNABTIVE) << pos))) - port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_FLOATING) << pos))) - p.setAltFunc(0x7) - } -} - -func (p Pin) setAltFunc(af uint32) { - port := p.getPort() - pin := uint8(p) % 16 - pos := pin * 4 - if pin >= 8 { - port.AFRH.Set(uint32(port.AFRH.Get())&^(0xF<<pos) | ((af & 0xF) << pos)) - } else { - port.AFRL.Set(uint32(port.AFRL.Get())&^(0xF<<pos) | ((af & 0xF) << pos)) - } -} - -// Set the pin to high or low. -// Warning: only use this on an output pin! -func (p Pin) Set(high bool) { - port := p.getPort() - pin := p % 16 - if high { - port.BSRR.Set(1 << uint8(pin)) - } else { - port.BSRR.Set(1 << uint8(pin+16)) +// Enable peripheral clock +func enableAltFuncClock(bus unsafe.Pointer) { + switch bus { + case unsafe.Pointer(stm32.USART1): + stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_USART1EN) + case unsafe.Pointer(stm32.USART2): + stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART2EN) + case unsafe.Pointer(stm32.I2C1): + stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_I2C1EN) + case unsafe.Pointer(stm32.SPI1): + stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SPI1EN) } } // UART type UART struct { - Buffer *RingBuffer + Buffer *RingBuffer + Bus *stm32.USART_Type + AltFuncSelector stm32.AltFunc } var ( - // Both UART0 and UART1 refer to USART2. - UART0 = UART{Buffer: NewRingBuffer()} + UART0 = UART{ + Buffer: NewRingBuffer(), + Bus: stm32.USART2, + AltFuncSelector: stm32.AF7_USART1_2_3, + } UART1 = &UART0 ) @@ -171,20 +102,22 @@ func (uart UART) Configure(config UARTConfig) { config.BaudRate = 115200 } - // pins - switch config.TX { - default: - // use standard TX/RX pins PA2 and PA3 - UART_TX_PIN.Configure(PinConfig{Mode: PinModeUartTX}) - UART_RX_PIN.Configure(PinConfig{Mode: PinModeUartRX}) + // Set the GPIO pins to defaults if they're not set + if config.TX == 0 && config.RX == 0 { + config.TX = UART_TX_PIN + config.RX = UART_RX_PIN } - // Enable USART2 clock - stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART2EN) + // Enable USART clock + enableAltFuncClock(unsafe.Pointer(uart.Bus)) + + // use standard TX/RX pins PA2 and PA3 + config.TX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTTX}, uart.AltFuncSelector) + config.RX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTRX}, uart.AltFuncSelector) /* Set baud rate(115200) - OVER8 = 0, APB2 = 42mhz + OVER8 = 0, APB1 = 42mhz +----------+--------+ | baudrate | BRR | +----------+--------+ @@ -197,14 +130,14 @@ func (uart UART) Configure(config UARTConfig) { | 115200 | 0x16D | +----------+--------+ */ - stm32.USART2.BRR.Set(0x16c) + uart.Bus.BRR.Set(0x16c) // Enable USART2 port. - stm32.USART2.CR1.Set(stm32.USART_CR1_TE | stm32.USART_CR1_RE | stm32.USART_CR1_RXNEIE | stm32.USART_CR1_UE) + uart.Bus.CR1.Set(stm32.USART_CR1_TE | stm32.USART_CR1_RE | stm32.USART_CR1_RXNEIE | stm32.USART_CR1_UE) - // Enable RX IRQ. + // Enable RX IRQ. TODO: pick the right IRQ_xxx for the bus and the uart intr := interrupt.New(stm32.IRQ_USART2, func(interrupt.Interrupt) { - UART1.Receive(byte((stm32.USART2.DR.Get() & 0xFF))) + UART1.Receive(byte((UART1.Bus.DR.Get() & 0xFF))) }) intr.SetPriority(0xc0) intr.Enable() @@ -212,9 +145,9 @@ func (uart UART) Configure(config UARTConfig) { // WriteByte writes a byte of data to the UART. func (uart UART) WriteByte(c byte) error { - stm32.USART2.DR.Set(uint32(c)) + uart.Bus.DR.Set(uint32(c)) - for !stm32.USART2.SR.HasBits(stm32.USART_SR_TXE) { + for !uart.Bus.SR.HasBits(stm32.USART_SR_TXE) { } return nil } |