diff --git a/GNUmakefile b/GNUmakefile index 8c4f00b2..c15b7724 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -708,6 +708,8 @@ ifneq ($(STM32), 0) @$(MD5SUM) test.hex $(TINYGO) build -size short -o test.hex -target=nucleo-l432kc examples/blinky1 @$(MD5SUM) test.hex + $(TINYGO) build -size short -o test.hex -target=nucleo-l476rg examples/blinky1 + @$(MD5SUM) test.hex $(TINYGO) build -size short -o test.hex -target=nucleo-l552ze examples/blinky1 @$(MD5SUM) test.hex $(TINYGO) build -size short -o test.hex -target=nucleo-wl55jc examples/blinky1 diff --git a/src/machine/board_nucleol476rg.go b/src/machine/board_nucleol476rg.go new file mode 100644 index 00000000..0a173afe --- /dev/null +++ b/src/machine/board_nucleol476rg.go @@ -0,0 +1,105 @@ +//go:build nucleol476rg + +// Schematic: https://www.st.com/resource/en/user_manual/um1724-stm32-nucleo64-boards-mb1136-stmicroelectronics.pdf +// Datasheet: https://www.st.com/resource/en/datasheet/stm32l476je.pdf + +package machine + +import ( + "device/stm32" + "runtime/interrupt" +) + +const ( + // Arduino Pins + A0 = PA0 + A1 = PA1 + A2 = PA4 + A3 = PB0 + A4 = PC1 + A5 = PC0 + + D0 = PA3 + D1 = PA2 + D2 = PA10 + D3 = PB3 + D4 = PB5 + D5 = PB4 + D6 = PB10 + D7 = PA8 + D8 = PA9 + D9 = PC7 + D10 = PB6 + D11 = PA7 + D12 = PA6 + D13 = PA5 + D14 = PB9 + D15 = PB8 +) + +// User LD2: the green LED is a user LED connected to ARDUINO® signal D13 corresponding +// to STM32 I/O PA5 (pin 21) or PB13 (pin 34) depending on the STM32 target. +const ( + LED = LED_BUILTIN + LED_BUILTIN = LED_GREEN + LED_GREEN = PA5 +) + +const ( + // This board does not have a user button, so + // use first GPIO pin by default + BUTTON = PA0 +) + +const ( + // UART pins + // PA2 and PA3 are connected to the ST-Link Virtual Com Port (VCP) + UART_TX_PIN = PA2 + UART_RX_PIN = PA3 + + // I2C pins + // With default solder bridge settings: + // PB8 / Arduino D5 / CN3 Pin 8 is SCL + // PB7 / Arduino D4 / CN3 Pin 7 is SDA + I2C0_SCL_PIN = PB8 + I2C0_SDA_PIN = PB9 + + // SPI pins + SPI1_SCK_PIN = PA5 + SPI1_SDI_PIN = PA6 + SPI1_SDO_PIN = PA7 + SPI0_SCK_PIN = SPI1_SCK_PIN + SPI0_SDI_PIN = SPI1_SDI_PIN + SPI0_SDO_PIN = SPI1_SDO_PIN +) + +var ( + // USART2 is the hardware serial port connected to the onboard ST-LINK + // debugger to be exposed as virtual COM port over USB on Nucleo boards. + UART1 = &_UART1 + _UART1 = UART{ + Buffer: NewRingBuffer(), + Bus: stm32.USART2, + TxAltFuncSelector: AF7_USART1_2_3, + RxAltFuncSelector: AF7_USART1_2_3, + } + DefaultUART = UART1 + + // I2C1 is documented, alias to I2C0 as well + I2C1 = &I2C{ + Bus: stm32.I2C1, + AltFuncSelector: AF4_I2C1_2_3, + } + I2C0 = I2C1 + + // SPI1 is documented, alias to SPI0 as well + SPI1 = &SPI{ + Bus: stm32.SPI1, + AltFuncSelector: AF5_SPI1_2, + } + SPI0 = SPI1 +) + +func init() { + UART1.Interrupt = interrupt.New(stm32.IRQ_USART2, _UART1.handleInterrupt) +} diff --git a/src/machine/machine_stm32l4x6.go b/src/machine/machine_stm32l4x6.go new file mode 100644 index 00000000..cf546303 --- /dev/null +++ b/src/machine/machine_stm32l4x6.go @@ -0,0 +1,25 @@ +//go:build stm32l4x6 + +package machine + +// Peripheral abstraction layer for the stm32l4x6 + +func CPUFrequency() uint32 { + return 80e6 +} + +// Internal use: configured speed of the APB1 and APB2 timers, this should be kept +// in sync with any changes to runtime package which configures the oscillators +// and clock frequencies +const APB1_TIM_FREQ = 80e6 // 80MHz +const APB2_TIM_FREQ = 80e6 // 80MHz + +//---------- I2C related code + +// Gets the value for TIMINGR register +func (i2c *I2C) getFreqRange() uint32 { + // This is a 'magic' value calculated by STM32CubeMX + // for 80MHz PCLK1. + // TODO: Do calculations based on PCLK1 + return 0x10909CEC +} diff --git a/src/runtime/runtime_stm32l4x6.go b/src/runtime/runtime_stm32l4x6.go new file mode 100644 index 00000000..6a56d8bd --- /dev/null +++ b/src/runtime/runtime_stm32l4x6.go @@ -0,0 +1,29 @@ +//go:build stm32 && stm32l4x6 + +package runtime + +import ( + "device/stm32" +) + +/* +clock settings + + +-------------+-----------+ + | LSE | 32.768khz | + | SYSCLK | 80mhz | + | HCLK | 80mhz | + | APB1(PCLK1) | 80mhz | + | APB2(PCLK2) | 80mhz | + +-------------+-----------+ +*/ +const ( + HSE_STARTUP_TIMEOUT = 0x0500 + PLL_M = 1 + PLL_N = 40 + PLL_P = RCC_PLLP_DIV7 + PLL_Q = RCC_PLLQ_DIV2 + PLL_R = RCC_PLLR_DIV2 + + MSIRANGE = stm32.RCC_CR_MSIRANGE_Range4M +) diff --git a/targets/nucleo-l476rg.json b/targets/nucleo-l476rg.json new file mode 100644 index 00000000..73eddee8 --- /dev/null +++ b/targets/nucleo-l476rg.json @@ -0,0 +1,12 @@ +{ + "inherits": ["cortex-m4"], + "build-tags": ["nucleol476rg", "stm32l476", "stm32l4x6", "stm32l4", "stm32"], + "serial": "uart", + "linkerscript": "targets/stm32l4x6.ld", + "extra-files": [ + "src/device/stm32/stm32l4x6.s" + ], + "flash-method": "openocd", + "openocd-interface": "stlink-v2-1", + "openocd-target": "stm32l4x" + } diff --git a/targets/stm32l4x6.ld b/targets/stm32l4x6.ld new file mode 100644 index 00000000..4f1ed773 --- /dev/null +++ b/targets/stm32l4x6.ld @@ -0,0 +1,11 @@ + +MEMORY +{ + FLASH_TEXT (rx) : ORIGIN = 0x08000000, LENGTH = 1024K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 96K + RAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 32K +} + +_stack_size = 4K; + +INCLUDE "targets/arm.ld"