stm32-ada/library/source/f4/stm32-direct_memory_access.ads

231 lines
6.4 KiB
Ada

with STM32.Address_Map;
-- DMA Controller
package STM32.Direct_Memory_Access is
-- LISR, HISR, LIFCR, HIFCR
-- This Register definition is a bit weird,
-- but gives ability to access a variable field
-- that is FEIF5 = ISR(1)(0).Channel(1)(FEIF)
type Channel_Interrupt_Status_Index is (
FEIF, Reserved, DMEIF, TEIF, HTIF, TCIF
);
type Channel_Interrupt_Status is
array (Channel_Interrupt_Status_Index) of Boolean
with Pack, Size => 6;
type Channel_Interrupt_Status_Pair is
array (Integer range 0 .. 1) of Channel_Interrupt_Status
with Pack, Size => 12;
type Two_Channel_Interrupt_Status is record
Channel : Channel_Interrupt_Status_Pair;
Reserved_12 : Integer range 0 .. 2**4 - 1;
end record with Size => 16;
for Two_Channel_Interrupt_Status use record
Channel at 0 range 0 .. 11;
Reserved_12 at 0 range 12 .. 15;
end record;
type Interrupt_Status_Register is
array (Integer range 0 .. 1) of Two_Channel_Interrupt_Status
with Pack, Size => 32;
Pragma Volatile_Full_Access(Interrupt_Status_Register);
-- LI*R is index 0, HI*R is index 1
type Interrupt_Status_Register_Pair is
array (Integer range 0 .. 1) of Interrupt_Status_Register;
-- SxCR
type Transfer_Direction is (
Peripheral_to_Memory, -- Peripheral to Memory Transfer
Memory_to_Peripheral, -- Memory to Peripheral Transfer
Memory_to_Memory -- Memory to Memory Transfer (only available on DMA2)
) with Size => 2;
for Transfer_Direction use (
Peripheral_to_Memory => 2#00#,
Memory_to_Peripheral => 2#01#,
Memory_to_Memory => 2#10#
);
type Data_Size is (
Byte,
Half_Word,
Word
) with Size => 2;
for Data_Size use (
Byte => 2#00#,
Half_Word => 2#01#,
Word => 2#10#
);
subtype Priority_Level is Integer range 0 .. 3;
subtype Target_Memory is Integer range 0 .. 1;
type Burst_Transfer is (
Single,
INCR4,
INCR8,
INCR16
) with Size => 2;
subtype Channel_Number is Integer range 0 .. 15;
-- note: channels 8 .. 15 are only available on F4x3 devices
type Stream_Configuration_Register is record
EN : Boolean := False;
DMEIE : Boolean := False;
TEIE : Boolean := False;
HTIE : Boolean := False;
TCIE : Boolean := False;
PFCTRL : Boolean := False;
DIR : Transfer_Direction := Peripheral_to_Memory;
CIRC : Boolean := False;
PINC : Boolean := False;
MINC : Boolean := False;
PSIZE : Data_Size := Byte;
MSIZE : Data_Size := Byte;
PINCOS : Boolean := False;
PL : Priority_Level := 0;
DBM : Boolean := False;
CT : Target_Memory := 0;
Unused_20 : Unused_1_Bit := 0;
PBURST : Burst_Transfer := Single;
MBURST : Burst_Transfer := Single;
CHSEL : Channel_Number := 0;
Unused_29 : Unused_3_Bits := 0;
end record with Size => 32;
for Stream_Configuration_Register use record
EN at 0 range 0 .. 0;
DMEIE at 0 range 1 .. 1;
TEIE at 0 range 2 .. 2;
HTIE at 0 range 3 .. 3;
TCIE at 0 range 4 .. 4;
PFCTRL at 0 range 5 .. 5;
DIR at 0 range 6 .. 7;
CIRC at 0 range 8 .. 8;
PINC at 0 range 9 .. 9;
MINC at 0 range 10 .. 10;
PSIZE at 0 range 11 .. 12;
MSIZE at 0 range 13 .. 14;
PINCOS at 0 range 15 .. 15;
PL at 0 range 16 .. 17;
DBM at 0 range 18 .. 18;
CT at 0 range 19 .. 19;
Unused_20 at 0 range 20 .. 20;
PBURST at 0 range 21 .. 22;
MBURST at 0 range 23 .. 24;
CHSEL at 0 range 25 .. 28;
Unused_29 at 0 range 29 .. 31;
end record;
-- NDTR
subtype Stream_Number_of_Data_Register is
Interfaces.Unsigned_32 range 0 .. 2**16 - 1;
-- This way high part will always be clear
-- MxAR
type Memory_Address_Register_Pair is
array (Integer range 0 .. 1) of Address_Register
with Size => 64;
-- SxFCR
type FIFO_Threshold is (
Quarter,
Half,
Three_Quarters,
Full
) with Size => 2;
for FIFO_Threshold use (
Quarter => 2#00#,
Half => 2#01#,
Three_Quarters => 2#10#,
Full => 2#11#
);
type FIFO_Status is (
Almost_Empty,
Below_Half,
Above_Half,
Almost_Full,
Empty,
Full
) with Size => 3;
for FIFO_Status use (
Almost_Empty => 2#000#,
Below_Half => 2#001#,
Above_Half => 2#010#,
Almost_Full => 2#011#,
Empty => 2#100#,
Full => 2#101#
);
type FIFO_Control_Register is record
FTH : FIFO_Threshold;
DMDIS : Boolean;
FS : FIFO_Status;
Reserved_6 : Integer range 0 .. 1;
FEIE : Boolean;
Reserved_8 : Integer range 0 .. 2**24 - 1;
end record with Size => 32;
for FIFO_Control_Register use record
FTH at 0 range 0 .. 1;
DMDIS at 0 range 2 .. 2;
FS at 0 range 3 .. 5;
Reserved_6 at 0 range 6 .. 6;
FEIE at 0 range 7 .. 7;
Reserved_8 at 0 range 8 .. 31;
end record;
DMA_Stream_Registers_Size : constant := 8 * 16#18#;
DMA_Streams : constant := 8;
type DMA_Stream_Registers is record
CR : Stream_Configuration_Register;
pragma Volatile_Full_Access(CR);
NDTR : Stream_Number_Of_Data_Register;
pragma Volatile_Full_Access(NDTR);
PAR : Address_Register; -- Address in peripheral and also source in MtM transfer
MAR : Memory_Address_Register_Pair; -- Address in memory to transfer
FCR : FIFO_Control_Register;
pragma Volatile_Full_Access(FCR);
end record with Size => DMA_Stream_Registers_Size, Volatile;
for DMA_Stream_Registers use record
CR at 16#00# range 0 .. 31;
NDTR at 16#04# range 0 .. 31;
PAR at 16#08# range 0 .. 31;
MAR at 16#0C# range 0 .. 63;
FCR at 16#14# range 0 .. 31;
end record;
type DMA_Stream_Array is
array (Integer range 0 .. DMA_Streams - 1) of DMA_Stream_Registers
with Size => DMA_Streams * DMA_Stream_Registers_Size;
type DMA_Registers is record
ISR : Interrupt_Status_Register_Pair;
IFCR : Interrupt_Status_Register_Pair;
S : DMA_Stream_Array;
end record with Volatile;
for DMA_Registers use record
ISR at 16#00# range 0 .. 63;
IFCR at 16#08# range 0 .. 63;
S at 16#10# range 0 .. DMA_Streams * DMA_Stream_Registers_Size - 1;
end record;
DMA1 : DMA_Registers with Volatile, Import, Address => Address_Map.DMA1;
DMA2 : DMA_Registers with Volatile, Import, Address => Address_Map.DMA2;
end STM32.Direct_Memory_Access;