@@ -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