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;