Skip to content

Commit

Permalink
Workround for GCC PR 99802.
Browse files Browse the repository at this point in the history
Problem found in GCC 11.0.1, also in GNAT CE 2020, so keep change in case
people are still on that compiler.

  * arduino-due/adainclude/startup-set_up_clock.adb: avoid writing
      aggregates to registers (they were being writtn component-by-component):
      instead, write to local variable, then write the variable to
      the register. Also, tidy up loops.
  * stm32f4/adainclude/startup-set_up_clock.adb: likewise.
  * stm32f429i/adainclude/startup-set_up_clock.adb: likewise.
  • Loading branch information
simonjwright committed Mar 30, 2021
1 parent a39a65e commit 11e7225
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 207 deletions.
57 changes: 36 additions & 21 deletions arduino-due/adainclude/startup-set_up_clock.adb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-- Copyright (C) 2016, 2020 Free Software Foundation, Inc.
-- Copyright (C) 2016-2021 Free Software Foundation, Inc.
--
-- This file is part of the Cortex GNAT RTS project. This file is
-- free software; you can redistribute it and/or modify it under
Expand Down Expand Up @@ -45,23 +45,27 @@ begin
end;

-- Select the Main Clock
PMC_Periph.CKGR_MOR := (KEY => 16#37#,
MOSCXTEN => 1, -- main crystal oscillator enable
MOSCRCEN => 1, -- main on-chip rc osc. enable
MOSCXTST => 8, -- startup time
others => <>);
-- XXX shouldn't this give 4 MHz, not 12?
declare
CKGR_MOR : constant CKGR_MOR_Register :=
(KEY => 16#37#,
MOSCXTEN => 1, -- main crystal oscillator enable
MOSCRCEN => 1, -- main on-chip rc osc. enable
MOSCXTST => 8, -- startup time
others => <>);
-- XXX shouldn't this give 4 MHz, not 12?
begin
PMC_Periph.CKGR_MOR := CKGR_MOR;
end;

-- Loop until stable
loop
exit when PMC_Periph.PMC_SR.MOSCXTS /= 0;
exit when PMC_Periph.PMC_SR.MOSCXTS = 1;
end loop;

-- Select the Main oscillator
declare
CKGR_MOR : CKGR_MOR_Register;
CKGR_MOR : CKGR_MOR_Register := PMC_Periph.CKGR_MOR;
begin
CKGR_MOR := PMC_Periph.CKGR_MOR;
CKGR_MOR.KEY := 16#37#;
CKGR_MOR.MOSCSEL := 1;
PMC_Periph.CKGR_MOR := CKGR_MOR;
Expand All @@ -73,18 +77,28 @@ begin
end loop;

-- Disable PLLA (?hardware bugfix?)
PMC_Periph.CKGR_PLLAR := (ONE => 1,
MULA => 0,
DIVA => 0,
others => <>);
declare
CKGR_PLLAR : constant CKGR_PLLAR_Register :=
(ONE => 1,
MULA => 0,
DIVA => 0,
others => <>);
begin
PMC_Periph.CKGR_PLLAR := CKGR_PLLAR;
end;

-- Set PLLA to multiply by 14, count 16#3f#, divide by 1 (=>
-- enable PLL); Main Clock is 12 MHz, => 168 Mhz
PMC_Periph.CKGR_PLLAR := (ONE => 1,
MULA => 13, -- multipler - 1
PLLACOUNT => 16#3f#,
DIVA => 1,
others => <>);
declare
CKGR_PLLAR : constant CKGR_PLLAR_Register :=
(ONE => 1,
MULA => 13, -- multipler - 1
PLLACOUNT => 16#3f#,
DIVA => 1,
others => <>);
begin
PMC_Periph.CKGR_PLLAR := CKGR_PLLAR;
end;

-- Loop until ready
loop
Expand All @@ -95,8 +109,9 @@ begin
PMC_MCKR : PMC_MCKR_Register;
begin
-- Select Main Clock, PRES 0 (no prescaling)
PMC_Periph.PMC_MCKR := (CSS => MAIN_CLK,
others => <>);
PMC_MCKR := (CSS => MAIN_CLK,
others => <>);
PMC_Periph.PMC_MCKR := PMC_MCKR;
-- Loop until ready
loop
exit when PMC_Periph.PMC_SR.MCKRDY /= 0;
Expand Down
148 changes: 55 additions & 93 deletions stm32f4/adainclude/startup-set_up_clock.adb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-- Copyright (C) 2016 Free Software Foundation, Inc.
-- Copyright (C) 2016-2021 Free Software Foundation, Inc.
--
-- This file is part of the Cortex GNAT RTS project. This file is
-- free software; you can redistribute it and/or modify it under
Expand Down Expand Up @@ -28,133 +28,95 @@ procedure Set_Up_Clock is
begin

-- Enable PWR clock
declare
APB1ENR : APB1ENR_Register;
begin
APB1ENR := RCC_Periph.APB1ENR;
APB1ENR.PWREN := 1;
RCC_Periph.APB1ENR := APB1ENR;
end;
RCC_Periph.APB1ENR.PWREN := 1;

-- Set highest voltage for maximum frequency (168 MHz).
-- DocID022152 Rev 6 Table 14.
-- Postpone wait-until-ready until PLL is in use.
declare
CR : STM32F40x.PWR.CR_Register;
begin
CR := PWR_Periph.CR;
CR.VOS := 1;
PWR_Periph.CR := CR;
end;
PWR_Periph.CR.VOS := 1;

-- Setup internal high-speed clock and wait for stabilisation.
declare
CR : STM32F40x.RCC.CR_Register;
begin
CR := RCC_Periph.CR;
CR.HSION := 1;
RCC_Periph.CR := CR;
loop
CR := RCC_Periph.CR;
exit when CR.HSIRDY = 1;
end loop;
end;
RCC_Periph.CR.HSION := 1;
loop
exit when RCC_Periph.CR.HSIRDY = 1;
end loop;

-- Setup external high-speed clock and wait for stabilisation.
declare
CR : STM32F40x.RCC.CR_Register;
begin
CR := RCC_Periph.CR;
CR.HSEON := 1;
-- Don't set HSEBYP (i.e. don't bypass external oscillator)
RCC_Periph.CR := CR;
loop
CR := RCC_Periph.CR;
exit when CR.HSERDY = 1;
end loop;
end;
RCC_Periph.CR.HSEON := 1;
-- Don't set HSEBYP (i.e. don't bypass external oscillator)
loop
exit when RCC_Periph.CR.HSERDY = 1;
end loop;

-- Setup internal low-speed clock and wait for stabilisation.
declare
CSR : STM32F40x.RCC.CSR_Register;
begin
CSR := RCC_Periph.CSR;
CSR.LSION := 1;
RCC_Periph.CSR := CSR;
loop
CSR := RCC_Periph.CSR;
exit when CSR.LSIRDY = 1;
end loop;
end;
RCC_Periph.CSR.LSION := 1;
loop
exit when RCC_Periph.CSR.LSIRDY = 1;
end loop;

-- Activate the PLL at 168 MHz.
-- See RM0090 5.1.4 for how to enter overdrive mode and enable
-- SYSCLK of 180 MHz.
declare
CR : STM32F40x.RCC.CR_Register;
PLLCFGR : constant PLLCFGR_Register
:= (PLLM => 8,
PLLN => 336, -- no overdrive: 168 MHz
PLLP => 0, -- *2
PLLSRC => 1, -- HSE
PLLQ => 7,
others => <>);
begin
RCC_Periph.PLLCFGR := (PLLM => 8,
PLLN => 336, -- no overdrive: 168 MHz
PLLP => 0, -- *2
PLLSRC => 1, -- HSE
PLLQ => 7,
others => <>);
CR := RCC_Periph.CR;
CR.PLLON := 1;
RCC_Periph.CR := CR;
loop
CR := RCC_Periph.CR;
exit when CR.PLLRDY = 1;
end loop;
RCC_Periph.PLLCFGR := PLLCFGR;
end;
RCC_Periph.CR.PLLON := 1;
loop
exit when RCC_Periph.CR.PLLRDY = 1;
end loop;

-- Wait until voltage supply scaling is ready (must be after PLL
-- is ready).
declare
CSR : STM32F40x.PWR.CSR_Register;
begin
loop
CSR := PWR_Periph.CSR;
exit when CSR.VOSRDY = 1;
end loop;
end;
loop
exit when PWR_Periph.CSR.VOSRDY = 1;
end loop;

-- Set flash latency to 5 wait states _before_ increasing the clock.
declare
ACR : STM32F40x.FLASH.ACR_Register;
ACR : constant STM32F40x.FLASH.ACR_Register
:= (LATENCY => 5,
PRFTEN => 1,
ICEN => 1,
DCEN => 1,
others => <>);
use type STM32F40x.UInt3;
begin
FLASH_Periph.ACR := (LATENCY => 5,
PRFTEN => 1,
ICEN => 1,
DCEN => 1,
others => <>);
FLASH_Periph.ACR := ACR;

-- Not sure we need to check this.
loop
ACR := FLASH_Periph.ACR;
exit when ACR.LATENCY = 5;
exit when FLASH_Periph.ACR.LATENCY = 5;
end loop;
end;

-- Configure clocks.
RCC_Periph.CFGR :=
(SW => 2, -- clock source is PLL
HPRE => 0, -- AHB prescale = 1
PPRE => (As_Array => True,
Arr => (5, -- APB lo speed prescale (PPRE1) = 4
4)), -- APB hi speed prescale (PPRE2) = 2
MCO1 => 0, -- MCU clock output 1 HSI selected
MCO1PRE => 0, -- MCU clock output 1 prescale = 1
MCO2 => 0, -- MCU clock output 2 SYSCLK selected
MCO2PRE => 7, -- MCU clock output 2 prescale = 5
others => <>);
declare
CFGR : STM32F40x.RCC.CFGR_Register;
CFGR : constant STM32F40x.RCC.CFGR_Register
:= (SW => 2, -- clock source is PLL
HPRE => 0, -- AHB prescale = 1
PPRE => (As_Array => True,
Arr => (5, -- APB lo speed prescale (PPRE1) = 4
4)), -- APB hi speed prescale (PPRE2) = 2
MCO1 => 0, -- MCU clock output 1 HSI selected
MCO1PRE => 0, -- MCU clock output 1 prescale = 1
MCO2 => 0, -- MCU clock output 2 SYSCLK selected
MCO2PRE => 7, -- MCU clock output 2 prescale = 5
others => <>);
use type STM32F40x.UInt2;
begin
RCC_Periph.CFGR := CFGR;

-- Wait until PLL running
loop
CFGR := RCC_Periph.CFGR;
exit when CFGR.SWS = 2; -- PLL running
exit when RCC_Periph.CFGR.SWS = 2;
end loop;
end;

Expand Down
Loading

0 comments on commit 11e7225

Please sign in to comment.