diff --git a/examples/sdram/ld/ROM-SDRAM-8M.ld b/examples/sdram_locals/ld/ROM-SDRAM-8M.ld similarity index 100% rename from examples/sdram/ld/ROM-SDRAM-8M.ld rename to examples/sdram_locals/ld/ROM-SDRAM-8M.ld diff --git a/examples/sdram/objects/.keep b/examples/sdram_locals/objects/.keep similarity index 100% rename from examples/sdram/objects/.keep rename to examples/sdram_locals/objects/.keep diff --git a/examples/sdram/sdram_429disco.gpr b/examples/sdram_locals/sdram_429disco.gpr similarity index 100% rename from examples/sdram/sdram_429disco.gpr rename to examples/sdram_locals/sdram_429disco.gpr diff --git a/examples/sdram/source/early_init_sdram.adb b/examples/sdram_locals/source/early_init_sdram.adb similarity index 100% rename from examples/sdram/source/early_init_sdram.adb rename to examples/sdram_locals/source/early_init_sdram.adb diff --git a/examples/sdram/source/sdram.adb b/examples/sdram_locals/source/sdram.adb similarity index 100% rename from examples/sdram/source/sdram.adb rename to examples/sdram_locals/source/sdram.adb diff --git a/examples/sdram/source/start-rom-sdram.s b/examples/sdram_locals/source/start-rom-sdram.s similarity index 100% rename from examples/sdram/source/start-rom-sdram.s rename to examples/sdram_locals/source/start-rom-sdram.s diff --git a/examples/sdram_test/Makefile b/examples/sdram_test/Makefile new file mode 100644 index 0000000..9606ff1 --- /dev/null +++ b/examples/sdram_test/Makefile @@ -0,0 +1,30 @@ +# Here's a example project name +X = sdram_test + +# Supported board list +BOARDS = f429disco + +O = objects + +help : + @echo "Usable targets" + @echo "flash example: $(BOARDS:%=flash_$X_%)" + @echo "build example: $(BOARDS:%=$O/%/$X)" + @echo "build all: all" + +all : $(BOARDS:%=$O/%/$X) + +.PHONY : help all + +$(BOARDS:%=flash_$X_%) : flash_$X_% : $O/%/$X.bin + st-flash --reset write $< 0x8000000 + +$(BOARDS:%=$O/%/$X) : $O/%/$X : %.gpr .FORCE + gprbuild $< + +$(BOARDS:%=$O/%/$X.bin) : $O/%/$X.bin : $O/%/$X + arm-eabi-objcopy -O binary $< $@ + +.PHONY : $(BOARDS:%=flash_$X_%) + +.PHONY : .FORCE diff --git a/examples/sdram_test/f429disco.gpr b/examples/sdram_test/f429disco.gpr new file mode 100644 index 0000000..b574dfc --- /dev/null +++ b/examples/sdram_test/f429disco.gpr @@ -0,0 +1,25 @@ +with "../../stm32f4_library.gpr"; + +project F429disco is + for Languages use("Ada"); + for Main use("sdram_test.adb"); + for Object_Dir use "objects/f429disco"; + for Target use "arm-eabi"; + for Runtime("Ada") use "ravenscar-sfp-stm32f429disco"; + for Source_Dirs use(".", "../common", "../common/f4", "../common/429disco"); + + package Compiler is + for Default_Switches("Ada") use ("-gnatwa.X", "-gnatQ", "-gnatn", "-O2"); + end Compiler; + + package Builder is + for Default_Switches("Ada") use ("-ggdb"); + end Builder; + + package IDE is + for Program_Host use "localhost:4242"; + for Communication_Protocol use "remote"; + for Connection_Tool use "st-util"; + end IDE; + +end F429disco; \ No newline at end of file diff --git a/examples/sdram_test/sdram_test.adb b/examples/sdram_test/sdram_test.adb new file mode 100644 index 0000000..e7a7000 --- /dev/null +++ b/examples/sdram_test/sdram_test.adb @@ -0,0 +1,231 @@ +with STM32.FMC; use STM32.FMC; +with STM32.RCC; use STM32.RCC; +with STM32.GPIO; use STM32.GPIO; +with Chip.Units; use Chip.Units; + +with Ada.Real_Time; use Ada.Real_Time; +procedure SDRAM_Test is + + procedure Send_Command (R : SDRAM.Command_Mode_Register) is + begin + FMC.SDCMR := R; + while FMC.SDSR.BUSY loop + null; + end loop; + end; + + Now: Time := Clock; + +begin + -- 64 Mbit SDRAM IS42S16400J + + -- PB5 CKE1 + -- PB6 NE1 + -- PC0 NWE + -- PD0 D2 + -- PD1 D3 + -- PD8 D13 + -- PD9 D14 + -- PD10 D15 + -- PD14 D0 + -- PD15 D1 + -- PE0 NBL0 + -- PE1 NBL1 + -- PE7 D4 + -- PE8 D5 + -- PE9 D6 + -- PE10 D7 + -- PE11 D8 + -- PE12 D9 + -- PE13 D10 + -- PE14 D11 + -- PE15 D12 + -- PF0 A0 + -- PF1 A1 + -- PF2 A2 + -- PF3 A3 + -- PF4 A4 + -- PF5 A5 + -- PF11 NRAS + -- PF12 A6 + -- PF13 A7 + -- PF14 A8 + -- PF15 A9 + -- PG0 A10 + -- PG1 A11 + -- PG4 BA0 + -- PG5 BA1 + -- PG8 CLK + -- PG15 NCAS + + RCC.AHB3ENR (Index.FMC) := True; + + -- Pins first + + RCC.AHB1ENR (Index.GPIOB .. Index.GPIOG) := (others => True); + + GPIOB.AFR (5 .. 6) := (others => Alternate_Functions.FMC); + GPIOB.MODER (5 .. 6) := (others => Alternate_Mode); + GPIOB.OTYPER (5 .. 6) := (others => Push_Pull_Type); + GPIOB.OSPEEDR (5 .. 6) := (others => Very_High_Speed); + GPIOB.PUPDR (5 .. 6) := (others => No_Pull); + + GPIOC.AFR (0) := Alternate_Functions.FMC; + GPIOC.MODER (0) := Alternate_Mode; + GPIOC.OTYPER (0) := Push_Pull_Type; + GPIOC.OSPEEDR (0) := Very_High_Speed; + GPIOC.PUPDR (0) := No_Pull; + + GPIOD.AFR (8 .. 10) := (others => Alternate_Functions.FMC); + GPIOD.MODER (8 .. 10) := (others => Alternate_Mode); + GPIOD.OTYPER (8 .. 10) := (others => Push_Pull_Type); + GPIOD.OSPEEDR (8 .. 10) := (others => Very_High_Speed); + GPIOD.PUPDR (8 .. 10) := (others => No_Pull); + + GPIOD.AFR (14 .. 15) := (others => Alternate_Functions.FMC); + GPIOD.MODER (14 .. 15) := (others => Alternate_Mode); + GPIOD.OTYPER (14 .. 15) := (others => Push_Pull_Type); + GPIOD.OSPEEDR (14 .. 15) := (others => Very_High_Speed); + GPIOD.PUPDR (14 .. 15) := (others => No_Pull); + + GPIOE.AFR (0 .. 1) := (others => Alternate_Functions.FMC); + GPIOE.MODER (0 .. 1) := (others => Alternate_Mode); + GPIOE.OTYPER (0 .. 1) := (others => Push_Pull_Type); + GPIOE.OSPEEDR (0 .. 1) := (others => Very_High_Speed); + GPIOE.PUPDR (0 .. 1) := (others => No_Pull); + + GPIOE.AFR (7 .. 15) := (others => Alternate_Functions.FMC); + GPIOE.MODER (7 .. 15) := (others => Alternate_Mode); + GPIOE.OTYPER (7 .. 15) := (others => Push_Pull_Type); + GPIOE.OSPEEDR (7 .. 15) := (others => Very_High_Speed); + GPIOE.PUPDR (7 .. 15) := (others => No_Pull); + + GPIOF.AFR (0 .. 5) := (others => Alternate_Functions.FMC); + GPIOF.MODER (0 .. 5) := (others => Alternate_Mode); + GPIOF.OTYPER (0 .. 5) := (others => Push_Pull_Type); + GPIOF.OSPEEDR (0 .. 5) := (others => Very_High_Speed); + GPIOF.PUPDR (0 .. 5) := (others => No_Pull); + + GPIOF.AFR (11 .. 15) := (others => Alternate_Functions.FMC); + GPIOF.MODER (11 .. 15) := (others => Alternate_Mode); + GPIOF.OTYPER (11 .. 15) := (others => Push_Pull_Type); + GPIOF.OSPEEDR (11 .. 15) := (others => Very_High_Speed); + GPIOF.PUPDR (11 .. 15) := (others => No_Pull); + + GPIOG.AFR (0 .. 1) := (others => Alternate_Functions.FMC); + GPIOG.MODER (0 .. 1) := (others => Alternate_Mode); + GPIOG.OTYPER (0 .. 1) := (others => Push_Pull_Type); + GPIOG.OSPEEDR (0 .. 1) := (others => Very_High_Speed); + GPIOG.PUPDR (0 .. 1) := (others => No_Pull); + + GPIOG.AFR (4 .. 5) := (others => Alternate_Functions.FMC); + GPIOG.MODER (4 .. 5) := (others => Alternate_Mode); + GPIOG.OTYPER (4 .. 5) := (others => Push_Pull_Type); + GPIOG.OSPEEDR (4 .. 5) := (others => Very_High_Speed); + GPIOG.PUPDR (4 .. 5) := (others => No_Pull); + + GPIOG.AFR (8) := Alternate_Functions.FMC; + GPIOG.MODER (8) := Alternate_Mode; + GPIOG.OTYPER (8) := Push_Pull_Type; + GPIOG.OSPEEDR (8) := Very_High_Speed; + GPIOG.PUPDR (8) := No_Pull; + + GPIOG.AFR (15) := Alternate_Functions.FMC; + GPIOG.MODER (15) := Alternate_Mode; + GPIOG.OTYPER (15) := Push_Pull_Type; + GPIOG.OSPEEDR (15) := Very_High_Speed; + GPIOG.PUPDR (15) := No_Pull; + + -- 1. SDCRx Registers + + declare + R : SDRAM.Control_Register := FMC.SDCR1; + begin + R.SDCLK := SDRAM.Period_3_HCLK; + R.RBURST := False; + R.RPIPE := 1; + + FMC.SDCR1 := R; + end; + + declare + R : SDRAM.Control_Register := FMC.SDCR2; + begin + R.NC := SDRAM.Column_8_Bits; + R.NR := SDRAM.Row_12_Bits; + R.MWID := Memory_16_Bits; + R.NB := SDRAM.Four_Banks; + R.CAS := 3; + R.WP := False; + + FMC.SDCR2 := R; + end; + + -- 2. SDTRx Registers + + declare + R : SDRAM.Timing_Register := FMC.SDTR1; + begin + R.TRC := 7 - 1; + R.TRP := 2 - 1; + + FMC.SDTR1 := R; + end; + + declare + R : SDRAM.Timing_Register := FMC.SDTR2; + begin + R.TMRD := 2 - 1; + R.TXSR := 7 - 1; + R.TRAS := 4 - 1; + R.TWR := 2 - 1; + R.TRCD := 2 - 1; + + FMC.SDTR2 := R; + end; + + -- 3. Set MODE to 001 and Target Bank Bits + + Send_Command(( + MODE => SDRAM.Clock_Configuration_Enable, + CTB1 => False, + CTB2 => True, + NRFS => 1 - 1, + MRD => 0, + others => <> + )); + + -- 4. Wait 100 us (see SDRAM datasheet) + + Now := Clock + Milliseconds(100); + delay until Now; + + -- 5. Send Precharge All + + Send_Command(( + MODE => SDRAM.PALL, + CTB1 => False, + CTB2 => True, + NRFS => 1 - 1, + MRD => 0, + others => <> + )); + + -- 6. Send Auto-refresh + + Send_Command(( + MODE => SDRAM.Auto_Refresh, + CTB1 => False, + CTB2 => True, + NRFS => 4 - 1, + MRD => 0, + others => <> + )); + + -- 7. Configure MRD and send Load Mode Register + + -- 8. Program refresh rate + + -- 9. Mobile SDRAM configure Extended mode register + +end SDRAM_Test; diff --git a/source/f4/stm32-f429-units.ads b/source/f4/stm32-f429-units.ads index 45d4394..0ab951a 100644 --- a/source/f4/stm32-f429-units.ads +++ b/source/f4/stm32-f429-units.ads @@ -1,6 +1,7 @@ with System; with STM32.Address_Map; with STM32.EXTI; +with STM32.FMC; with STM32.GPIO; with STM32.LTDC; with STM32.RCC; @@ -15,40 +16,43 @@ package STM32.F429.Units is EXTI : STM32.EXTI.EXTI_Registers with Volatile, Import, Address => System'To_Address (STM32.Address_Map.EXTI); + FMC : STM32.FMC.FMC_Registers + with Volatile, Import, Address => System'To_Address (STM32.Address_Map.FMC_FSMC); + --- - GPIOA: STM32.GPIO.GPIO_Registers - with Volatile, Import, Address => System'To_Address(Address_Map.GPIOA); + GPIOA : STM32.GPIO.GPIO_Registers + with Volatile, Import, Address => System'To_Address(Address_Map.GPIOA); - GPIOB: STM32.GPIO.GPIO_Registers - with Volatile, Import, Address => System'To_Address(Address_Map.GPIOB); + GPIOB : STM32.GPIO.GPIO_Registers + with Volatile, Import, Address => System'To_Address(Address_Map.GPIOB); - GPIOC: STM32.GPIO.GPIO_Registers - with Volatile, Import, Address => System'To_Address(Address_Map.GPIOC); + GPIOC : STM32.GPIO.GPIO_Registers + with Volatile, Import, Address => System'To_Address(Address_Map.GPIOC); - GPIOD: STM32.GPIO.GPIO_Registers - with Volatile, Import, Address => System'To_Address(Address_Map.GPIOD); + GPIOD : STM32.GPIO.GPIO_Registers + with Volatile, Import, Address => System'To_Address(Address_Map.GPIOD); - GPIOE: STM32.GPIO.GPIO_Registers - with Volatile, Import, Address => System'To_Address(Address_Map.GPIOE); + GPIOE : STM32.GPIO.GPIO_Registers + with Volatile, Import, Address => System'To_Address(Address_Map.GPIOE); - GPIOF: STM32.GPIO.GPIO_Registers - with Volatile, Import, Address => System'To_Address(Address_Map.GPIOF); + GPIOF : STM32.GPIO.GPIO_Registers + with Volatile, Import, Address => System'To_Address(Address_Map.GPIOF); - GPIOG: STM32.GPIO.GPIO_Registers - with Volatile, Import, Address => System'To_Address(Address_Map.GPIOG); + GPIOG : STM32.GPIO.GPIO_Registers + with Volatile, Import, Address => System'To_Address(Address_Map.GPIOG); - GPIOH: STM32.GPIO.GPIO_Registers - with Volatile, Import, Address => System'To_Address(Address_Map.GPIOH); + GPIOH : STM32.GPIO.GPIO_Registers + with Volatile, Import, Address => System'To_Address(Address_Map.GPIOH); - GPIOI: STM32.GPIO.GPIO_Registers - with Volatile, Import, Address => System'To_Address(Address_Map.GPIOI); + GPIOI : STM32.GPIO.GPIO_Registers + with Volatile, Import, Address => System'To_Address(Address_Map.GPIOI); - GPIOJ: STM32.GPIO.GPIO_Registers - with Volatile, Import, Address => System'To_Address(Address_Map.GPIOJ); + GPIOJ : STM32.GPIO.GPIO_Registers + with Volatile, Import, Address => System'To_Address(Address_Map.GPIOJ); - GPIOK: STM32.GPIO.GPIO_Registers - with Volatile, Import, Address => System'To_Address(Address_Map.GPIOK); + GPIOK : STM32.GPIO.GPIO_Registers + with Volatile, Import, Address => System'To_Address(Address_Map.GPIOK); --- diff --git a/source/f4/stm32-fmc.ads b/source/f4/stm32-fmc.ads index 9326c38..44a7b0c 100644 --- a/source/f4/stm32-fmc.ads +++ b/source/f4/stm32-fmc.ads @@ -357,12 +357,12 @@ package STM32.FMC is ); type Command_Mode_Register is record - MODE : Command_Mode; -- Command mode - CTB2 : Boolean; -- Command target bank 2 - CTB1 : Boolean; -- Command target bank 1 - NRFS : Integer range 0 .. 14; -- Number of refresh cycles minus 1 - MRD : Integer range 0 .. 2**12 - 1; - Reserved : Integer range 0 .. 2**10 - 1; + MODE : Command_Mode := Normal_Mode; -- Command mode + CTB2 : Boolean := False; -- Command target bank 2 + CTB1 : Boolean := False; -- Command target bank 1 + NRFS : Integer range 0 .. 14 := 0; -- Number of refresh cycles minus 1 + MRD : Integer range 0 .. 2**12 - 1 := 0; + Reserved : Integer range 0 .. 2**10 - 1 := 0; end record with Size => 32; for Command_Mode_Register use record MODE at 0 range 0 .. 2; diff --git a/source/f4/stm32-gpio.ads b/source/f4/stm32-gpio.ads index fa680a4..5f1f1be 100644 --- a/source/f4/stm32-gpio.ads +++ b/source/f4/stm32-gpio.ads @@ -157,6 +157,7 @@ package STM32.GPIO is ETH : constant Alternate_Function := 11; + FMC : constant Alternate_Function := 12; FSMC : constant Alternate_Function := 12; SDIO : constant Alternate_Function := 12; OTG_FS_B : constant Alternate_Function := 12;