@@ -55,6 +55,31 @@ const struct rcc_clock_scale benchmarkclock = {
5555#define SERIAL_PINS (GPIO8 | GPIO9)
5656#define STM32
5757
58+ #elif defined(STM32L4R5ZI )
59+ #include <libopencm3/stm32/rcc.h>
60+ #include <libopencm3/stm32/gpio.h>
61+ #include <libopencm3/stm32/usart.h>
62+ #include <libopencm3/stm32/flash.h>
63+ #include <libopencm3/stm32/rng.h>
64+ #include <libopencm3/stm32/pwr.h>
65+
66+ #define SERIAL_GPIO GPIOG
67+ #define SERIAL_USART LPUART1
68+ #define SERIAL_PINS (GPIO8 | GPIO7)
69+ #define NUCLEO_L4R5_BOARD
70+
71+ /* Patched function for newer PLL not yet supported by opencm3 */
72+ void _rcc_set_main_pll (uint32_t source , uint32_t pllm , uint32_t plln , uint32_t pllp ,
73+ uint32_t pllq , uint32_t pllr )
74+ {
75+ RCC_PLLCFGR = (RCC_PLLCFGR_PLLM (pllm ) << RCC_PLLCFGR_PLLM_SHIFT ) |
76+ (plln << RCC_PLLCFGR_PLLN_SHIFT ) |
77+ ((pllp & 0x1Fu ) << 27u ) | /* NEWER PLLP */
78+ (source << RCC_PLLCFGR_PLLSRC_SHIFT ) |
79+ (pllq << RCC_PLLCFGR_PLLQ_SHIFT ) |
80+ (pllr << RCC_PLLCFGR_PLLR_SHIFT ) | RCC_PLLCFGR_PLLREN ;
81+ }
82+
5883#else
5984#error Unsupported libopencm3 board
6085#endif
@@ -156,6 +181,69 @@ static void clock_setup(enum clock_mode clock) {
156181 # else
157182# error Unsupported STM32F2 Board
158183 # endif
184+ #elif defined(NUCLEO_L4R5_BOARD )
185+ rcc_periph_clock_enable (RCC_PWR );
186+ rcc_periph_clock_enable (RCC_SYSCFG );
187+ pwr_set_vos_scale (PWR_SCALE1 );
188+ /* The L4R5ZI chip also needs the R1MODE bit in PWR_CR5 register set, but
189+ OpenCM3 doesn't support this yet. But luckily the default value for the bit
190+ is 1. */
191+ switch (clock ) {
192+ case CLOCK_BENCHMARK :
193+ /* Benchmark straight from the HSI16 without prescaling */
194+ rcc_osc_on (RCC_HSI16 );
195+ rcc_wait_for_osc_ready (RCC_HSI16 );
196+ rcc_ahb_frequency = 20000000 ;
197+ rcc_apb1_frequency = 20000000 ;
198+ rcc_apb2_frequency = 20000000 ;
199+ _clock_freq = 20000000 ;
200+ rcc_set_hpre (RCC_CFGR_HPRE_NODIV );
201+ rcc_set_ppre1 (RCC_CFGR_PPRE_NODIV );
202+ rcc_set_ppre2 (RCC_CFGR_PPRE_NODIV );
203+ rcc_osc_off (RCC_PLL );
204+ while (rcc_is_osc_ready (RCC_PLL ));
205+ /* Configure the PLL oscillator (use CUBEMX tool -> scale HSI16 to 20MHz). */
206+ _rcc_set_main_pll (RCC_PLLCFGR_PLLSRC_HSI16 , 1 , 10 , 2 , RCC_PLLCFGR_PLLQ_DIV2 , RCC_PLLCFGR_PLLR_DIV8 );
207+ /* Enable PLL oscillator and wait for it to stabilize. */
208+ rcc_osc_on (RCC_PLL );
209+ flash_dcache_enable ();
210+ flash_icache_enable ();
211+ flash_set_ws (FLASH_ACR_LATENCY_0WS );
212+ flash_prefetch_enable ();
213+ rcc_set_sysclk_source (RCC_CFGR_SW_PLL );
214+ rcc_wait_for_sysclk_status (RCC_PLL );
215+ break ;
216+ case CLOCK_FAST :
217+ default :
218+ rcc_osc_on (RCC_HSI16 );
219+ rcc_wait_for_osc_ready (RCC_HSI16 );
220+ rcc_ahb_frequency = 120000000 ;
221+ rcc_apb1_frequency = 120000000 ;
222+ rcc_apb2_frequency = 120000000 ;
223+ _clock_freq = 120000000 ;
224+ rcc_set_hpre (RCC_CFGR_HPRE_NODIV );
225+ rcc_set_ppre1 (RCC_CFGR_PPRE_NODIV );
226+ rcc_set_ppre2 (RCC_CFGR_PPRE_NODIV );
227+ rcc_osc_off (RCC_PLL );
228+ while (rcc_is_osc_ready (RCC_PLL ));
229+ /* Configure the PLL oscillator (use CUBEMX tool -> scale HSI16 to 120MHz). */
230+ _rcc_set_main_pll (RCC_PLLCFGR_PLLSRC_HSI16 , 1 , 15 , 2 , RCC_PLLCFGR_PLLQ_DIV2 , RCC_PLLCFGR_PLLR_DIV2 );
231+ /* Enable PLL oscillator and wait for it to stabilize. */
232+ rcc_osc_on (RCC_PLL );
233+ rcc_wait_for_osc_ready (RCC_PLL );
234+ flash_dcache_enable ();
235+ flash_icache_enable ();
236+ flash_set_ws (0x05 );
237+ flash_prefetch_enable ();
238+ rcc_set_sysclk_source (RCC_CFGR_SW_PLL );
239+ rcc_wait_for_sysclk_status (RCC_PLL );
240+ break ;
241+ }
242+ rcc_osc_on (RCC_HSI48 ); /* HSI48 must always be on for RNG */
243+ rcc_wait_for_osc_ready (RCC_HSI48 );
244+ rcc_periph_clock_enable (RCC_RNG );
245+ rcc_set_clock48_source (RCC_CCIPR_CLK48SEL_HSI48 );
246+ rng_enable ();
159247 #else
160248#error Unsupported platform
161249 #endif
@@ -171,6 +259,23 @@ void usart_setup() {
171259 #elif defined(NUCLEO_BOARD )
172260 rcc_periph_clock_enable (RCC_GPIOA );
173261 rcc_periph_clock_enable (RCC_USART2 );
262+ #elif defined(NUCLEO_L4R5_BOARD )
263+ rcc_periph_clock_enable (RCC_GPIOG );
264+ rcc_periph_clock_enable (RCC_LPUART1 );
265+
266+ PWR_CR2 |= PWR_CR2_IOSV ;
267+ gpio_set_output_options (SERIAL_GPIO , GPIO_OTYPE_PP , GPIO_OSPEED_100MHZ , SERIAL_PINS );
268+ gpio_set_af (SERIAL_GPIO , GPIO_AF8 , SERIAL_PINS );
269+ gpio_mode_setup (SERIAL_GPIO , GPIO_MODE_AF , GPIO_PUPD_NONE , SERIAL_PINS );
270+ usart_set_baudrate (SERIAL_USART , SERIAL_BAUD );
271+ usart_set_databits (SERIAL_USART , 8 );
272+ usart_set_stopbits (SERIAL_USART , USART_STOPBITS_1 );
273+ usart_set_mode (SERIAL_USART , USART_MODE_TX_RX );
274+ usart_set_parity (SERIAL_USART , USART_PARITY_NONE );
275+ usart_set_flow_control (SERIAL_USART , USART_FLOWCONTROL_NONE );
276+ usart_disable_rx_interrupt (SERIAL_USART );
277+ usart_disable_tx_interrupt (SERIAL_USART );
278+ usart_enable (SERIAL_USART );
174279 #else
175280#error Unsupported platform
176281 #endif
0 commit comments