Rework the sdcard branch from master.
This merges the various sdcard handling enhancements into a single commit, the two branches master and sdcard having diverged too much to perform a simple git merge.
This commit is contained in:
parent
a720d04bf1
commit
13ef8db311
|
@ -38,6 +38,8 @@
|
|||
with System;
|
||||
with STM32_SVD.SDIO; use STM32_SVD.SDIO;
|
||||
|
||||
with HAL.SDMMC; use HAL.SDMMC;
|
||||
|
||||
with STM32.DMA;
|
||||
|
||||
package STM32.SDMMC is
|
||||
|
@ -46,175 +48,23 @@ package STM32.SDMMC is
|
|||
(Periph : not null access STM32_SVD.SDIO.SDIO_Peripheral)
|
||||
is limited private;
|
||||
|
||||
type SD_Error is
|
||||
(OK,
|
||||
Error,
|
||||
Timeout_Error,
|
||||
Unsupported_Card,
|
||||
Rx_Overrun,
|
||||
Tx_Underrun,
|
||||
Startbit_Not_Detected,
|
||||
Request_Not_Applicable,
|
||||
CRC_Check_Fail,
|
||||
Illegal_Cmd,
|
||||
Address_Out_Of_Range,
|
||||
Address_Missaligned,
|
||||
Block_Length_Error,
|
||||
Erase_Seq_Error,
|
||||
Bad_Erase_Parameter,
|
||||
Write_Protection_Violation,
|
||||
Lock_Unlock_Failed,
|
||||
Card_ECC_Failed,
|
||||
Card_ECC_Disabled,
|
||||
CC_Error,
|
||||
General_Unknown_Error,
|
||||
Stream_Read_Underrun,
|
||||
Stream_Write_Underrun,
|
||||
CID_CSD_Overwrite,
|
||||
WP_Erase_Skip,
|
||||
Erase_Reset,
|
||||
AKE_SEQ_Error,
|
||||
Invalid_Voltage_Range,
|
||||
DMA_Alignment_Error);
|
||||
|
||||
type Supported_SD_Memory_Cards is
|
||||
(STD_Capacity_SD_Card_V1_1,
|
||||
STD_Capacity_SD_Card_v2_0,
|
||||
High_Capacity_SD_Card,
|
||||
Multimedia_Card,
|
||||
Secure_Digital_IO_Card,
|
||||
High_Speed_Multimedia_Card,
|
||||
Secure_Digital_IO_Combo_Card,
|
||||
High_Capacity_MMC_Card);
|
||||
|
||||
type Card_Specific_Data_Register is record
|
||||
CSD_Structure : UInt8;
|
||||
System_Specification_Version : UInt8;
|
||||
Reserved : UInt8;
|
||||
Data_Read_Access_Time_1 : UInt8;
|
||||
Data_Read_Access_Time_2 : UInt8; -- In CLK Cycles
|
||||
Max_Bus_Clock_Frequency : UInt8;
|
||||
Card_Command_Class : UInt16;
|
||||
Max_Read_Data_Block_Length : UInt8; -- ld (blocksize in bytes)
|
||||
Partial_Block_For_Read_Allowed : Boolean;
|
||||
Write_Block_Missalignment : Boolean;
|
||||
Read_Block_Missalignment : Boolean;
|
||||
DSR_Implemented : Boolean;
|
||||
Reserved_2 : UInt8;
|
||||
Device_Size : UInt32;
|
||||
Max_Read_Current_At_VDD_Min : UInt8;
|
||||
Max_Read_Current_At_VDD_Max : UInt8;
|
||||
Max_Write_Current_At_VDD_Min : UInt8;
|
||||
Max_Write_Current_At_VDD_Max : UInt8;
|
||||
Device_Size_Multiplier : UInt8;
|
||||
Erase_Group_Size : UInt8;
|
||||
Erase_Group_Size_Multiplier : UInt8;
|
||||
Write_Protect_Group_Size : UInt8;
|
||||
Write_Protect_Group_Enable : Boolean;
|
||||
Manufacturer_Default_ECC : UInt8;
|
||||
Write_Speed_Factor : UInt8;
|
||||
Max_Write_Data_Block_Length : UInt8; -- =Max_Read_Data_Block_Length
|
||||
Partial_Blocks_For_Write_Allowed : Boolean;
|
||||
Reserved_3 : UInt8;
|
||||
Content_Protection_Application : Boolean;
|
||||
File_Format_Group : Boolean;
|
||||
Copy_Flag : Boolean;
|
||||
Permanent_Write_Protection : Boolean;
|
||||
Temporary_Write_Protection : Boolean;
|
||||
File_Format : UInt8;
|
||||
ECC_Code : UInt8;
|
||||
CSD_CRC : UInt8;
|
||||
Reserved_4 : UInt8; -- Always 1
|
||||
end record;
|
||||
|
||||
type Card_Revision is record
|
||||
Major : UInt4;
|
||||
Minor : UInt4;
|
||||
end record with Pack;
|
||||
|
||||
type Manufacturing_Year is range 2000 .. 2255;
|
||||
type Manufacturing_Month is
|
||||
(January,
|
||||
February,
|
||||
March,
|
||||
April,
|
||||
May,
|
||||
June,
|
||||
July,
|
||||
August,
|
||||
September,
|
||||
October,
|
||||
November,
|
||||
December) with Size => 4;
|
||||
|
||||
type Manufacturing_Date_Type is record
|
||||
Year : Manufacturing_Year;
|
||||
Month : Manufacturing_Month;
|
||||
end record;
|
||||
|
||||
type Card_Identification_Data_Register is record
|
||||
Manufacturer_ID : UInt8;
|
||||
OEM_Application_ID : String (1 .. 2);
|
||||
Product_Name : String (1 .. 5);
|
||||
Product_Revision : Card_Revision;
|
||||
Product_Serial_Number : UInt32;
|
||||
Reserved_1 : UInt8;
|
||||
Manufacturing_Date : Manufacturing_Date_Type;
|
||||
CID_CRC : UInt8;
|
||||
Reserved_2 : UInt8; -- Always 1
|
||||
end record;
|
||||
|
||||
type Card_Information is record
|
||||
SD_CSD : Card_Specific_Data_Register;
|
||||
SD_CID : Card_Identification_Data_Register;
|
||||
Card_Capacity : Unsigned_64;
|
||||
Card_Block_Size : Unsigned_32;
|
||||
RCA : UInt16; -- SD relative card address
|
||||
Card_Type : Supported_SD_Memory_Cards :=
|
||||
STD_Capacity_SD_Card_V1_1;
|
||||
end record;
|
||||
|
||||
-- Wide bus mode
|
||||
type Wide_Bus_Mode is
|
||||
(
|
||||
-- Default bus mode: SDMMC_D0 is used.
|
||||
Wide_Bus_1B,
|
||||
-- 4-wide bus mode: SDMMC_D[3:0] used.
|
||||
Wide_Bus_4B,
|
||||
-- 8-wide bus mode: SDMMC_D[7:0] used.
|
||||
Wide_Bus_8B)
|
||||
with Size => 2;
|
||||
for Wide_Bus_Mode use
|
||||
(Wide_Bus_1B => 0,
|
||||
Wide_Bus_4B => 1,
|
||||
Wide_Bus_8B => 2);
|
||||
|
||||
function Initialize
|
||||
(This : in out SDMMC_Controller;
|
||||
Info : out Card_Information) return SD_Error;
|
||||
|
||||
function Initialized (This : SDMMC_Controller) return Boolean;
|
||||
|
||||
function Get_Card_Type
|
||||
(This : SDMMC_Controller) return Supported_SD_Memory_Cards
|
||||
with Pre => Initialized (This);
|
||||
|
||||
function Configure_Wide_Bus_Mode
|
||||
(This : in out SDMMC_Controller;
|
||||
Wide_Mode : Wide_Bus_Mode) return SD_Error;
|
||||
SDMMC_CLK : UInt32;
|
||||
Info : out Card_Information) return SD_Error;
|
||||
|
||||
type SD_Data is array (Unsigned_16 range <>) of UInt8
|
||||
type SD_Data is array (UInt16 range <>) of UInt8
|
||||
with Pack;
|
||||
|
||||
function Read_Blocks
|
||||
(This : in out SDMMC_Controller;
|
||||
Addr : Unsigned_64;
|
||||
Addr : UInt64;
|
||||
Data : out SD_Data) return SD_Error
|
||||
with Pre => Data'Length mod 512 = 0;
|
||||
|
||||
function Read_Blocks_DMA
|
||||
(This : in out SDMMC_Controller;
|
||||
Addr : Unsigned_64;
|
||||
Addr : UInt64;
|
||||
DMA : STM32.DMA.DMA_Controller;
|
||||
Stream : STM32.DMA.DMA_Stream_Selector;
|
||||
Data : out SD_Data) return SD_Error
|
||||
|
@ -222,7 +72,7 @@ package STM32.SDMMC is
|
|||
|
||||
function Write_Blocks_DMA
|
||||
(This : in out SDMMC_Controller;
|
||||
Addr : Unsigned_64;
|
||||
Addr : UInt64;
|
||||
DMA : STM32.DMA.DMA_Controller;
|
||||
Stream : STM32.DMA.DMA_Stream_Selector;
|
||||
Data : SD_Data) return SD_Error
|
||||
|
@ -291,117 +141,55 @@ package STM32.SDMMC is
|
|||
|
||||
private
|
||||
|
||||
type SDMMC_Command is new UInt8;
|
||||
|
||||
-- Resets the SD memory card
|
||||
Go_Idle_State : constant SDMMC_Command := 0;
|
||||
|
||||
-- Sends host capacity support information and activates the card's
|
||||
-- initialization process
|
||||
Send_Op_Cond : constant SDMMC_Command := 1;
|
||||
|
||||
-- Asks any card connected to the host to send the CID numbers on the
|
||||
-- CMD line.
|
||||
All_Send_CID : constant SDMMC_Command := 2;
|
||||
|
||||
-- Asks the card to publish a new relative address (RCA).
|
||||
Set_Rel_Addr : constant SDMMC_Command := 3;
|
||||
|
||||
-- Programs the DSR of all cards.
|
||||
Set_DSR : constant SDMMC_Command := 4;
|
||||
|
||||
-- Sends host capacity support information (HCS) and asks the accessed
|
||||
-- card to send its operating condition register (OCR) content in the
|
||||
-- response on the CMD line.
|
||||
SDMMC_Send_Op_Cond : constant SDMMC_Command := 5;
|
||||
|
||||
-- Checks switchable function (mode 0) and switch card function (mode
|
||||
-- 1).
|
||||
HS_Switch : constant SDMMC_Command := 6;
|
||||
|
||||
-- Selects the card by its own relative address and gets deselected by
|
||||
-- any other address
|
||||
Sel_Desel_Card : constant SDMMC_Command := 7;
|
||||
|
||||
-- Sends SD Memory Card interface condition
|
||||
HS_Send_Ext_CSD : constant SDMMC_Command := 8;
|
||||
|
||||
-- Addressed card sends its card specific data
|
||||
Send_CSD : constant SDMMC_Command := 9;
|
||||
|
||||
-- Addressed card sends its card identification (CID) on the CMD line.
|
||||
Send_CID : constant SDMMC_Command := 10;
|
||||
|
||||
Read_Dat_Until_Stop : constant SDMMC_Command := 11;
|
||||
Stop_Transmission : constant SDMMC_Command := 12;
|
||||
Send_Status : constant SDMMC_Command := 13;
|
||||
HS_Bustest_Read : constant SDMMC_Command := 14;
|
||||
Go_Inactive_State : constant SDMMC_Command := 15;
|
||||
Set_Blocklen : constant SDMMC_Command := 16;
|
||||
Read_Single_Block : constant SDMMC_Command := 17;
|
||||
Read_Multi_Block : constant SDMMC_Command := 18;
|
||||
HS_Bustest_Write : constant SDMMC_Command := 19;
|
||||
Write_Dat_Until_Stop : constant SDMMC_Command := 20;
|
||||
Set_Block_Count : constant SDMMC_Command := 23; -- Only for MMC
|
||||
Write_Single_Block : constant SDMMC_Command := 24;
|
||||
Write_Multi_Block : constant SDMMC_Command := 25;
|
||||
Prog_CID : constant SDMMC_Command := 26;
|
||||
Prog_CSD : constant SDMMC_Command := 27;
|
||||
Set_Write_Prot : constant SDMMC_Command := 28;
|
||||
Clr_Write_Prot : constant SDMMC_Command := 29;
|
||||
Send_Write_Prot : constant SDMMC_Command := 30;
|
||||
SD_Erase_Grp_Start : constant SDMMC_Command := 32;
|
||||
SD_Erase_Grp_End : constant SDMMC_Command := 33;
|
||||
Erase_Grp_Start : constant SDMMC_Command := 35;
|
||||
Erase_Grp_End : constant SDMMC_Command := 36;
|
||||
Erase : constant SDMMC_Command := 38;
|
||||
Fast_IO : constant SDMMC_Command := 39;
|
||||
Go_IRQ_State : constant SDMMC_Command := 40;
|
||||
Lock_Unlock : constant SDMMC_Command := 42;
|
||||
App_Cmd : constant SDMMC_Command := 55;
|
||||
Gen_Cmd : constant SDMMC_Command := 56;
|
||||
No_Cmd : constant SDMMC_Command := 64;
|
||||
|
||||
-- SD-Card speciric commands
|
||||
-- App_Cmd should be sent before sending these commands
|
||||
subtype SD_Specific_Command is SDMMC_Command;
|
||||
|
||||
SD_App_Set_Buswidth : constant SD_Specific_Command := 6;
|
||||
SD_App_Status : constant SD_Specific_Command := 13;
|
||||
SD_App_Secure_Read_Multi_Block : constant SD_Specific_Command := 18;
|
||||
SD_App_Send_Num_Write_Blocks : constant SD_Specific_Command := 22;
|
||||
SD_App_Set_Write_Block_Erase_Count : constant SD_Specific_Command := 23;
|
||||
SD_App_Secure_Write_Multi_Block : constant SD_Specific_Command := 25;
|
||||
SD_App_Secure_Erase : constant SD_Specific_Command := 38;
|
||||
SD_App_Op_Cond : constant SD_Specific_Command := 41;
|
||||
SD_App_Get_MKB : constant SD_Specific_Command := 43;
|
||||
SD_App_Get_MID : constant SD_Specific_Command := 44;
|
||||
SD_App_Set_CER_RN1 : constant SD_Specific_Command := 45;
|
||||
SD_App_Get_CER_RN2 : constant SD_Specific_Command := 46;
|
||||
SD_App_Set_CER_RES2 : constant SD_Specific_Command := 47;
|
||||
SD_App_Get_CER_RES1 : constant SD_Specific_Command := 48;
|
||||
SD_App_Change_Secure_Area : constant SD_Specific_Command := 49;
|
||||
SD_App_Send_SCR : constant SD_Specific_Command := 51;
|
||||
|
||||
type Card_Data_Table is array (0 .. 3) of UInt32;
|
||||
|
||||
type SDMMC_Controller
|
||||
(Periph : not null access STM32_SVD.SDIO.SDIO_Peripheral)
|
||||
is limited record
|
||||
CID : Card_Data_Table := (others => 0);
|
||||
CSD : Card_Data_Table := (others => 0);
|
||||
is limited new SDMMC_Driver with record
|
||||
CLK_In : UInt32;
|
||||
RCA : UInt16;
|
||||
Card_Type : Supported_SD_Memory_Cards :=
|
||||
STD_Capacity_SD_Card_V1_1;
|
||||
RCA : UInt32 := 0;
|
||||
Operation : SDMMC_Operation := No_Operation;
|
||||
end record;
|
||||
|
||||
function Initialized (This : SDMMC_Controller) return Boolean
|
||||
is (This.CID /= (0, 0, 0, 0));
|
||||
overriding procedure Delay_Milliseconds
|
||||
(This : SDMMC_Controller;
|
||||
Amount : Natural);
|
||||
|
||||
function Get_Card_Type
|
||||
(This : SDMMC_Controller) return Supported_SD_Memory_Cards
|
||||
is (This.Card_Type);
|
||||
overriding procedure Reset
|
||||
(This : in out SDMMC_Controller;
|
||||
Status : out SD_Error);
|
||||
|
||||
overriding procedure Set_Clock
|
||||
(This : in out SDMMC_Controller;
|
||||
Freq : Natural);
|
||||
|
||||
overriding procedure Set_Bus_Size
|
||||
(This : in out SDMMC_Controller;
|
||||
Mode : Wide_Bus_Mode);
|
||||
|
||||
overriding procedure Send_Cmd
|
||||
(This : in out SDMMC_Controller;
|
||||
Cmd : Cmd_Desc_Type;
|
||||
Arg : UInt32;
|
||||
Status : out SD_Error);
|
||||
|
||||
overriding procedure Read_Cmd
|
||||
(This : in out SDMMC_Controller;
|
||||
Cmd : Cmd_Desc_Type;
|
||||
Arg : UInt32;
|
||||
Buf : out UInt32_Array;
|
||||
Status : out SD_Error);
|
||||
|
||||
overriding procedure Read_Rsp48
|
||||
(This : in out SDMMC_Controller;
|
||||
Rsp : out UInt32);
|
||||
|
||||
overriding procedure Read_Rsp136
|
||||
(This : in out SDMMC_Controller;
|
||||
W0, W1, W2, W3 : out UInt32);
|
||||
|
||||
function Command_Error
|
||||
(Controller : in out SDMMC_Controller) return SD_Error;
|
||||
|
||||
type Data_Direction is (Read, Write);
|
||||
|
||||
|
|
|
@ -37,190 +37,39 @@
|
|||
|
||||
with System;
|
||||
with STM32_SVD.SDMMC; use STM32_SVD.SDMMC;
|
||||
with HAL.SDMMC; use HAL.SDMMC;
|
||||
|
||||
with STM32.DMA;
|
||||
|
||||
package STM32.SDMMC is
|
||||
|
||||
type SDMMC_Controller (Periph : access STM32_SVD.SDMMC.SDMMC_Peripheral) is
|
||||
limited private;
|
||||
|
||||
type SD_Error is
|
||||
(OK,
|
||||
Error,
|
||||
Timeout_Error,
|
||||
Unsupported_Card,
|
||||
Rx_Overrun,
|
||||
Tx_Underrun,
|
||||
Request_Not_Applicable,
|
||||
CRC_Check_Fail,
|
||||
Illegal_Cmd,
|
||||
Address_Out_Of_Range,
|
||||
Address_Missaligned,
|
||||
Block_Length_Error,
|
||||
Erase_Seq_Error,
|
||||
Bad_Erase_Parameter,
|
||||
Write_Protection_Violation,
|
||||
Lock_Unlock_Failed,
|
||||
Card_ECC_Failed,
|
||||
Card_ECC_Disabled,
|
||||
CC_Error,
|
||||
General_Unknown_Error,
|
||||
Stream_Read_Underrun,
|
||||
Stream_Write_Underrun,
|
||||
CID_CSD_Overwrite,
|
||||
WP_Erase_Skip,
|
||||
Erase_Reset,
|
||||
AKE_SEQ_Error,
|
||||
Invalid_Voltage_Range,
|
||||
Startbit_Not_Detected,
|
||||
DMA_Alignment_Error);
|
||||
|
||||
type Supported_SD_Memory_Cards is
|
||||
(STD_Capacity_SD_Card_V1_1,
|
||||
STD_Capacity_SD_Card_v2_0,
|
||||
High_Capacity_SD_Card,
|
||||
Multimedia_Card,
|
||||
Secure_Digital_IO_Card,
|
||||
High_Speed_Multimedia_Card,
|
||||
Secure_Digital_IO_Combo_Card,
|
||||
High_Capacity_MMC_Card);
|
||||
|
||||
type Card_Specific_Data_Register is record
|
||||
CSD_Structure : UInt8;
|
||||
System_Specification_Version : UInt8;
|
||||
Reserved : UInt8;
|
||||
Data_Read_Access_Time_1 : UInt8;
|
||||
Data_Read_Access_Time_2 : UInt8; -- In CLK Cycles
|
||||
Max_Bus_Clock_Frequency : UInt8;
|
||||
Card_Command_Class : UInt16;
|
||||
Max_Read_Data_Block_Length : UInt8;
|
||||
Partial_Block_For_Read_Allowed : Boolean;
|
||||
Write_Block_Missalignment : Boolean;
|
||||
Read_Block_Missalignment : Boolean;
|
||||
DSR_Implemented : Boolean;
|
||||
Reserved_2 : UInt8;
|
||||
Device_Size : UInt32;
|
||||
Max_Read_Current_At_VDD_Min : UInt8;
|
||||
Max_Read_Current_At_VDD_Max : UInt8;
|
||||
Max_Write_Current_At_VDD_Min : UInt8;
|
||||
Max_Write_Current_At_VDD_Max : UInt8;
|
||||
Device_Size_Multiplier : UInt8;
|
||||
Erase_Group_Size : UInt8;
|
||||
Erase_Group_Size_Multiplier : UInt8;
|
||||
Write_Protect_Group_Size : UInt8;
|
||||
Write_Protect_Group_Enable : Boolean;
|
||||
Manufacturer_Default_ECC : UInt8;
|
||||
Write_Speed_Factor : UInt8;
|
||||
Max_Write_Data_Block_Length : UInt8;
|
||||
Partial_Blocks_For_Write_Allowed : Boolean;
|
||||
Reserved_3 : UInt8;
|
||||
Content_Protection_Application : Boolean;
|
||||
File_Format_Group : Boolean;
|
||||
Copy_Flag : Boolean;
|
||||
Permanent_Write_Protection : Boolean;
|
||||
Temporary_Write_Protection : Boolean;
|
||||
File_Format : UInt8;
|
||||
ECC_Code : UInt8;
|
||||
CSD_CRC : UInt8;
|
||||
Reserved_4 : UInt8; -- Always 1
|
||||
end record;
|
||||
|
||||
type Card_Revision is record
|
||||
Major : UInt4;
|
||||
Minor : UInt4;
|
||||
end record with Pack;
|
||||
|
||||
type Manufacturing_Year is range 2000 .. 2255;
|
||||
type Manufacturing_Month is
|
||||
(January,
|
||||
February,
|
||||
March,
|
||||
April,
|
||||
May,
|
||||
June,
|
||||
July,
|
||||
August,
|
||||
September,
|
||||
October,
|
||||
November,
|
||||
December) with Size => 4;
|
||||
|
||||
type Manufacturing_Date_Type is record
|
||||
Year : Manufacturing_Year;
|
||||
Month : Manufacturing_Month;
|
||||
end record;
|
||||
|
||||
type Card_Identification_Data_Register is record
|
||||
Manufacturer_ID : UInt8;
|
||||
OEM_Application_ID : String (1 .. 2);
|
||||
Product_Name : String (1 .. 5);
|
||||
Product_Revision : Card_Revision;
|
||||
Product_Serial_Number : UInt32;
|
||||
Reserved_1 : UInt8;
|
||||
Manufacturing_Date : Manufacturing_Date_Type;
|
||||
CID_CRC : UInt8;
|
||||
Reserved_2 : UInt8; -- Always 1
|
||||
end record;
|
||||
|
||||
type Card_Information is record
|
||||
SD_CSD : Card_Specific_Data_Register;
|
||||
SD_CID : Card_Identification_Data_Register;
|
||||
Card_Capacity : Unsigned_64;
|
||||
Card_Block_Size : Unsigned_32;
|
||||
RCA : UInt16; -- SD relative card address
|
||||
Card_Type : Supported_SD_Memory_Cards :=
|
||||
STD_Capacity_SD_Card_V1_1;
|
||||
end record;
|
||||
|
||||
-- Wide bus mode
|
||||
type Wide_Bus_Mode is
|
||||
(
|
||||
-- Default bus mode: SDMMC_D0 is used.
|
||||
Wide_Bus_1B,
|
||||
-- 4-wide bus mode: SDMMC_D[3:0] used.
|
||||
Wide_Bus_4B,
|
||||
-- 8-wide bus mode: SDMMC_D[7:0] used.
|
||||
Wide_Bus_8B)
|
||||
with Size => 2;
|
||||
for Wide_Bus_Mode use
|
||||
(Wide_Bus_1B => 0,
|
||||
Wide_Bus_4B => 1,
|
||||
Wide_Bus_8B => 2);
|
||||
type SDMMC_Controller (Periph : access STM32_SVD.SDMMC.SDMMC_Peripheral)
|
||||
is limited private;
|
||||
|
||||
function Initialize
|
||||
(This : in out SDMMC_Controller;
|
||||
Info : out Card_Information) return SD_Error;
|
||||
(This : in out SDMMC_Controller;
|
||||
SDMMC_CLK : UInt32;
|
||||
Info : out Card_Information) return SD_Error;
|
||||
|
||||
function Initialized (This : SDMMC_Controller) return Boolean;
|
||||
|
||||
function Get_Card_Type
|
||||
(This : SDMMC_Controller) return Supported_SD_Memory_Cards
|
||||
with Pre => Initialized (This);
|
||||
|
||||
function Configure_Wide_Bus_Mode
|
||||
(This : in out SDMMC_Controller;
|
||||
Wide_Mode : Wide_Bus_Mode) return SD_Error;
|
||||
|
||||
type SD_Data is array (Unsigned_16 range <>) of UInt8
|
||||
type SD_Data is array (UInt16 range <>) of UInt8
|
||||
with Pack;
|
||||
|
||||
function Read_Blocks
|
||||
(This : in out SDMMC_Controller;
|
||||
Addr : Unsigned_64;
|
||||
Addr : UInt64;
|
||||
Data : out SD_Data) return SD_Error
|
||||
with Pre => Data'Length mod 512 = 0;
|
||||
|
||||
function Read_Blocks_DMA
|
||||
(This : in out SDMMC_Controller;
|
||||
Addr : Unsigned_64;
|
||||
Addr : UInt64;
|
||||
DMA : STM32.DMA.DMA_Controller;
|
||||
Stream : STM32.DMA.DMA_Stream_Selector;
|
||||
Data : out SD_Data) return SD_Error;
|
||||
|
||||
function Write_Blocks_DMA
|
||||
(This : in out SDMMC_Controller;
|
||||
Addr : Unsigned_64;
|
||||
Addr : UInt64;
|
||||
DMA : STM32.DMA.DMA_Controller;
|
||||
Stream : STM32.DMA.DMA_Stream_Selector;
|
||||
Data : SD_Data) return SD_Error;
|
||||
|
@ -287,116 +136,55 @@ package STM32.SDMMC is
|
|||
|
||||
private
|
||||
|
||||
type SDMMC_Command is new UInt8;
|
||||
|
||||
-- Resets the SD memory card
|
||||
Go_Idle_State : constant SDMMC_Command := 0;
|
||||
|
||||
-- Sends host capacity support information and activates the card's
|
||||
-- initialization process
|
||||
Send_Op_Cond : constant SDMMC_Command := 1;
|
||||
|
||||
-- Asks any card connected to the host to send the CID numbers on the
|
||||
-- CMD line.
|
||||
All_Send_CID : constant SDMMC_Command := 2;
|
||||
|
||||
-- Asks the card to publish a new relative address (RCA).
|
||||
Set_Rel_Addr : constant SDMMC_Command := 3;
|
||||
|
||||
-- Programs the DSR of all cards.
|
||||
Set_DSR : constant SDMMC_Command := 4;
|
||||
|
||||
-- Sends host capacity support information (HCS) and asks the accessed
|
||||
-- card to send its operating condition register (OCR) content in the
|
||||
-- response on the CMD line.
|
||||
SDMMC_Send_Op_Cond : constant SDMMC_Command := 5;
|
||||
|
||||
-- Checks switchable function (mode 0) and switch card function (mode
|
||||
-- 1).
|
||||
HS_Switch : constant SDMMC_Command := 6;
|
||||
|
||||
-- Selects the card by its own relative address and gets deselected by
|
||||
-- any other address
|
||||
Sel_Desel_Card : constant SDMMC_Command := 7;
|
||||
|
||||
-- Sends SD Memory Card interface condition
|
||||
HS_Send_Ext_CSD : constant SDMMC_Command := 8;
|
||||
|
||||
-- Addressed card sends its card specific data
|
||||
Send_CSD : constant SDMMC_Command := 9;
|
||||
|
||||
-- Addressed card sends its card identification (CID) on the CMD line.
|
||||
Send_CID : constant SDMMC_Command := 10;
|
||||
|
||||
Read_Dat_Until_Stop : constant SDMMC_Command := 11;
|
||||
Stop_Transmission : constant SDMMC_Command := 12;
|
||||
Send_Status : constant SDMMC_Command := 13;
|
||||
HS_Bustest_Read : constant SDMMC_Command := 14;
|
||||
Go_Inactive_State : constant SDMMC_Command := 15;
|
||||
Set_Blocklen : constant SDMMC_Command := 16;
|
||||
Read_Single_Block : constant SDMMC_Command := 17;
|
||||
Read_Multi_Block : constant SDMMC_Command := 18;
|
||||
HS_Bustest_Write : constant SDMMC_Command := 19;
|
||||
Write_Dat_Until_Stop : constant SDMMC_Command := 20;
|
||||
Set_Block_Count : constant SDMMC_Command := 23; -- Only for MMC
|
||||
Write_Single_Block : constant SDMMC_Command := 24;
|
||||
Write_Multi_Block : constant SDMMC_Command := 25;
|
||||
Prog_CID : constant SDMMC_Command := 26;
|
||||
Prog_CSD : constant SDMMC_Command := 27;
|
||||
Set_Write_Prot : constant SDMMC_Command := 28;
|
||||
Clr_Write_Prot : constant SDMMC_Command := 29;
|
||||
Send_Write_Prot : constant SDMMC_Command := 30;
|
||||
SD_Erase_Grp_Start : constant SDMMC_Command := 32;
|
||||
SD_Erase_Grp_End : constant SDMMC_Command := 33;
|
||||
Erase_Grp_Start : constant SDMMC_Command := 35;
|
||||
Erase_Grp_End : constant SDMMC_Command := 36;
|
||||
Erase : constant SDMMC_Command := 38;
|
||||
Fast_IO : constant SDMMC_Command := 39;
|
||||
Go_IRQ_State : constant SDMMC_Command := 40;
|
||||
Lock_Unlock : constant SDMMC_Command := 42;
|
||||
App_Cmd : constant SDMMC_Command := 55;
|
||||
Gen_Cmd : constant SDMMC_Command := 56;
|
||||
No_Cmd : constant SDMMC_Command := 64;
|
||||
|
||||
-- SD-Card speciric commands
|
||||
-- App_Cmd should be sent before sending these commands
|
||||
subtype SD_Specific_Command is SDMMC_Command;
|
||||
|
||||
SD_App_Set_Buswidth : constant SD_Specific_Command := 6;
|
||||
SD_App_Status : constant SD_Specific_Command := 13;
|
||||
SD_App_Secure_Read_Multi_Block : constant SD_Specific_Command := 18;
|
||||
SD_App_Send_Num_Write_Blocks : constant SD_Specific_Command := 22;
|
||||
SD_App_Set_Write_Block_Erase_Count : constant SD_Specific_Command := 23;
|
||||
SD_App_Secure_Write_Multi_Block : constant SD_Specific_Command := 25;
|
||||
SD_App_Secure_Erase : constant SD_Specific_Command := 38;
|
||||
SD_App_Op_Cond : constant SD_Specific_Command := 41;
|
||||
SD_App_Get_MKB : constant SD_Specific_Command := 43;
|
||||
SD_App_Get_MID : constant SD_Specific_Command := 44;
|
||||
SD_App_Set_CER_RN1 : constant SD_Specific_Command := 45;
|
||||
SD_App_Get_CER_RN2 : constant SD_Specific_Command := 46;
|
||||
SD_App_Set_CER_RES2 : constant SD_Specific_Command := 47;
|
||||
SD_App_Get_CER_RES1 : constant SD_Specific_Command := 48;
|
||||
SD_App_Change_Secure_Area : constant SD_Specific_Command := 49;
|
||||
SD_App_Send_SCR : constant SD_Specific_Command := 51;
|
||||
|
||||
type Card_Data_Table is array (0 .. 3) of UInt32;
|
||||
|
||||
type SDMMC_Controller (Periph : access STM32_SVD.SDMMC.SDMMC_Peripheral) is
|
||||
limited record
|
||||
CID : Card_Data_Table := (others => 0);
|
||||
CSD : Card_Data_Table := (others => 0);
|
||||
Card_Type : Supported_SD_Memory_Cards :=
|
||||
STD_Capacity_SD_Card_V1_1;
|
||||
RCA : UInt32 := 0;
|
||||
limited new SDMMC_Driver with record
|
||||
CLK_In : UInt32;
|
||||
RCA : UInt16;
|
||||
Card_Type : Supported_SD_Memory_Cards := STD_Capacity_SD_Card_V1_1;
|
||||
Operation : SDMMC_Operation := No_Operation;
|
||||
end record;
|
||||
|
||||
function Initialized (This : SDMMC_Controller) return Boolean
|
||||
is (This.CID /= (0, 0, 0, 0));
|
||||
overriding procedure Delay_Milliseconds
|
||||
(This : SDMMC_Controller;
|
||||
Amount : Natural);
|
||||
|
||||
function Get_Card_Type
|
||||
(This : SDMMC_Controller) return Supported_SD_Memory_Cards
|
||||
is (This.Card_Type);
|
||||
overriding procedure Reset
|
||||
(This : in out SDMMC_Controller;
|
||||
Status : out SD_Error);
|
||||
|
||||
overriding procedure Set_Clock
|
||||
(This : in out SDMMC_Controller;
|
||||
Freq : Natural);
|
||||
|
||||
overriding procedure Set_Bus_Size
|
||||
(This : in out SDMMC_Controller;
|
||||
Mode : Wide_Bus_Mode);
|
||||
|
||||
overriding procedure Send_Cmd
|
||||
(This : in out SDMMC_Controller;
|
||||
Cmd : Cmd_Desc_Type;
|
||||
Arg : UInt32;
|
||||
Status : out SD_Error);
|
||||
|
||||
overriding procedure Read_Cmd
|
||||
(This : in out SDMMC_Controller;
|
||||
Cmd : Cmd_Desc_Type;
|
||||
Arg : UInt32;
|
||||
Buf : out UInt32_Array;
|
||||
Status : out SD_Error);
|
||||
|
||||
function Command_Error
|
||||
(Controller : in out SDMMC_Controller) return SD_Error;
|
||||
|
||||
overriding procedure Read_Rsp48
|
||||
(This : in out SDMMC_Controller;
|
||||
Rsp : out UInt32);
|
||||
|
||||
overriding procedure Read_Rsp136
|
||||
(This : in out SDMMC_Controller;
|
||||
W0, W1, W2, W3 : out UInt32);
|
||||
|
||||
type Data_Direction is (Read, Write);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,6 @@
|
|||
with "config";
|
||||
with "../../hal/HAL";
|
||||
with "../../middleware/sdmmc";
|
||||
with "../cortex_m/cortex_m4f";
|
||||
|
||||
library project STM32F46_79x is
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
with "config";
|
||||
with "../../hal/HAL";
|
||||
with "../../middleware/sdmmc";
|
||||
with "../cortex_m/cortex_m7";
|
||||
|
||||
library project STM32F7x is
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
with "config";
|
||||
with "../../hal/HAL";
|
||||
with "../../middleware/sdmmc";
|
||||
with "../cortex_m/cortex_m7";
|
||||
|
||||
library project STM32F7x9 is
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
|
||||
with Ada.Real_Time; use Ada.Real_Time;
|
||||
|
||||
with HAL.SDMMC; use HAL.SDMMC;
|
||||
with STM32_SVD.RCC; use STM32_SVD.RCC;
|
||||
|
||||
with STM32.Device; use STM32.Device;
|
||||
with STM32.DMA; use STM32.DMA;
|
||||
with STM32.GPIO; use STM32.GPIO;
|
||||
|
@ -112,6 +115,8 @@ package body SDCard is
|
|||
(PC8, PC9, PC10, PC11, PC12, PD2);
|
||||
|
||||
begin
|
||||
RCC_Periph.DCKCFGR.SDMMCSEL := True; -- SDMMC uses the SYSCLK
|
||||
|
||||
-- Enable the SDIO clock
|
||||
Enable_Clock (SDMMC_Controller (Controller.Device.all));
|
||||
Reset (SDMMC_Controller (Controller.Device.all));
|
||||
|
@ -215,7 +220,9 @@ package body SDCard is
|
|||
end if;
|
||||
|
||||
Ret := STM32.SDMMC.Initialize
|
||||
(Controller.Device.all, Controller.Info);
|
||||
(Controller.Device.all,
|
||||
System_Clock_Frequencies.SYSCLK,
|
||||
Controller.Info);
|
||||
|
||||
if Ret = OK then
|
||||
Controller.Has_Info := True;
|
||||
|
@ -230,16 +237,11 @@ package body SDCard is
|
|||
|
||||
function Get_Card_Information
|
||||
(Controller : in out SDCard_Controller)
|
||||
return STM32.SDMMC.Card_Information
|
||||
return Card_Information
|
||||
is
|
||||
begin
|
||||
Ensure_Card_Informations (Controller);
|
||||
|
||||
if not Controller.Has_Info then
|
||||
-- Issue reading the SD-card information
|
||||
Ensure_Card_Informations (Controller);
|
||||
end if;
|
||||
|
||||
if not Controller.Has_Info then
|
||||
raise Device_Error;
|
||||
end if;
|
||||
|
@ -253,7 +255,7 @@ package body SDCard is
|
|||
|
||||
function Block_Size
|
||||
(Controller : in out SDCard_Controller)
|
||||
return Unsigned_32
|
||||
return UInt32
|
||||
is
|
||||
begin
|
||||
Ensure_Card_Informations (Controller);
|
||||
|
@ -471,7 +473,7 @@ package body SDCard is
|
|||
|
||||
overriding function Write
|
||||
(Controller : in out SDCard_Controller;
|
||||
Block_Number : UInt32;
|
||||
Block_Number : UInt64;
|
||||
Data : Block) return Boolean
|
||||
is
|
||||
Ret : SD_Error;
|
||||
|
@ -490,8 +492,7 @@ package body SDCard is
|
|||
Clear_All_Status (SD_DMA, SD_DMA_Tx_Stream);
|
||||
Ret := Write_Blocks_DMA
|
||||
(Controller.Device.all,
|
||||
Unsigned_64 (Block_Number) *
|
||||
Unsigned_64 (Controller.Info.Card_Block_Size),
|
||||
Block_Number * UInt64 (Controller.Info.Card_Block_Size),
|
||||
SD_DMA,
|
||||
SD_DMA_Tx_Stream,
|
||||
SD_Data (Data));
|
||||
|
@ -537,7 +538,7 @@ package body SDCard is
|
|||
|
||||
overriding function Read
|
||||
(Controller : in out SDCard_Controller;
|
||||
Block_Number : UInt32;
|
||||
Block_Number : UInt64;
|
||||
Data : out Block) return Boolean
|
||||
is
|
||||
Ret : Boolean;
|
||||
|
@ -555,8 +556,7 @@ package body SDCard is
|
|||
|
||||
SD_Err := Read_Blocks_DMA
|
||||
(Controller.Device.all,
|
||||
Unsigned_64 (Block_Number) *
|
||||
Unsigned_64 (Controller.Info.Card_Block_Size),
|
||||
Block_Number * UInt64 (Controller.Info.Card_Block_Size),
|
||||
SD_DMA,
|
||||
SD_DMA_Rx_Stream,
|
||||
SD_Data (Data));
|
||||
|
|
|
@ -29,9 +29,9 @@
|
|||
-- --
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
with Interfaces; use Interfaces;
|
||||
with Ada.Interrupts.Names;
|
||||
|
||||
with HAL.SDMMC;
|
||||
with STM32.SDMMC;
|
||||
|
||||
with HAL; use HAL;
|
||||
|
@ -62,31 +62,29 @@ package SDCard is
|
|||
|
||||
function Get_Card_Information
|
||||
(Controller : in out SDCard_Controller)
|
||||
return STM32.SDMMC.Card_Information
|
||||
return HAL.SDMMC.Card_Information
|
||||
with Pre => Controller.Card_Present;
|
||||
-- Retrieves the card informations
|
||||
|
||||
function Block_Size
|
||||
(Controller : in out SDCard_Controller)
|
||||
return Unsigned_32;
|
||||
return UInt32;
|
||||
-- The insterted card block size. 512 Bytes for sd-cards
|
||||
|
||||
overriding function Read
|
||||
(Controller : in out SDCard_Controller;
|
||||
Block_Number : UInt32;
|
||||
Block_Number : UInt64;
|
||||
Data : out Block) return Boolean
|
||||
with Pre => (Data'Size mod Controller.Block_Size) = 0
|
||||
and then Data'Size < 2 ** 16;
|
||||
with Pre => Data'Size < 2 ** 16;
|
||||
-- Reads Data.
|
||||
-- Data size needs to be a multiple of the card's block size and maximum
|
||||
-- length is 2**16
|
||||
|
||||
overriding function Write
|
||||
(Controller : in out SDCard_Controller;
|
||||
Block_Number : UInt32;
|
||||
Block_Number : UInt64;
|
||||
Data : Block) return Boolean
|
||||
with Pre => (Data'Size mod Controller.Block_Size) = 0
|
||||
and then Data'Size < 2 ** 16;
|
||||
with Pre => Data'Size < 2 ** 16;
|
||||
-- Writes Data.
|
||||
-- Data size needs to be a multiple of the card's block size and maximum
|
||||
-- length is 2**16
|
||||
|
@ -96,7 +94,7 @@ private
|
|||
type SDCard_Controller
|
||||
(Device : not null access STM32.SDMMC.SDMMC_Controller) is
|
||||
limited new HAL.Block_Drivers.Block_Driver with record
|
||||
Info : STM32.SDMMC.Card_Information;
|
||||
Info : HAL.SDMMC.Card_Information;
|
||||
Has_Info : Boolean := False;
|
||||
Card_Detected : Boolean := False;
|
||||
end record;
|
||||
|
|
|
@ -28,12 +28,16 @@
|
|||
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --
|
||||
-- --
|
||||
-- This file is based on: --
|
||||
-- @file stm32f746g_discovery_sd.c --
|
||||
-- @file stm32f769i_discovery_sd.c --
|
||||
-- @author MCD Application Team --
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
with Ada.Real_Time; use Ada.Real_Time;
|
||||
|
||||
with HAL.SDMMC; use HAL.SDMMC;
|
||||
|
||||
with STM32_SVD.RCC; use STM32_SVD.RCC;
|
||||
|
||||
with STM32.Device; use STM32.Device;
|
||||
with STM32.DMA; use STM32.DMA;
|
||||
with STM32.GPIO; use STM32.GPIO;
|
||||
|
@ -42,14 +46,14 @@ with Cortex_M.Cache;
|
|||
|
||||
package body SDCard is
|
||||
|
||||
SD_Detect_Pin : constant STM32.GPIO.GPIO_Point :=
|
||||
PC13;
|
||||
SD_Detect_Pin : STM32.GPIO.GPIO_Point renames PC13;
|
||||
|
||||
SD_DMA : DMA_Controller renames DMA_2;
|
||||
SD_DMA_Rx_Stream : DMA_Stream_Selector renames Stream_3;
|
||||
SD_DMA_Rx_Channel : DMA_Channel_Selector renames Channel_4;
|
||||
SD_DMA_Tx_Stream : DMA_Stream_Selector renames Stream_6;
|
||||
SD_DMA_Tx_Channel : DMA_Channel_Selector renames Channel_4;
|
||||
SD_Pins : constant STM32.GPIO.GPIO_Points :=
|
||||
SD_Pins : constant GPIO_Points :=
|
||||
(PC8, PC9, PC10, PC11, PC12, PD2);
|
||||
|
||||
procedure Ensure_Card_Informations
|
||||
|
@ -113,7 +117,10 @@ package body SDCard is
|
|||
procedure Initialize
|
||||
(Controller : in out SDCard_Controller)
|
||||
is
|
||||
|
||||
begin
|
||||
RCC_Periph.DKCFGR2.SDMMCSEL := True; -- SDMMC uses the SYSCLK
|
||||
|
||||
-- Enable the SDIO clock
|
||||
Enable_Clock (SDMMC_Controller (Controller.Device.all));
|
||||
Reset (SDMMC_Controller (Controller.Device.all));
|
||||
|
@ -216,8 +223,13 @@ package body SDCard is
|
|||
return;
|
||||
end if;
|
||||
|
||||
Enable_Clock (SDMMC_Controller (Controller.Device.all));
|
||||
Reset (SDMMC_Controller (Controller.Device.all));
|
||||
|
||||
Ret := STM32.SDMMC.Initialize
|
||||
(Controller.Device.all, Controller.Info);
|
||||
(Controller.Device.all,
|
||||
System_Clock_Frequencies.SYSCLK,
|
||||
Controller.Info);
|
||||
|
||||
if Ret = OK then
|
||||
Controller.Has_Info := True;
|
||||
|
@ -232,16 +244,11 @@ package body SDCard is
|
|||
|
||||
function Get_Card_Information
|
||||
(Controller : in out SDCard_Controller)
|
||||
return STM32.SDMMC.Card_Information
|
||||
return Card_Information
|
||||
is
|
||||
begin
|
||||
Ensure_Card_Informations (Controller);
|
||||
|
||||
if not Controller.Has_Info then
|
||||
-- Issue reading the SD-card information
|
||||
Ensure_Card_Informations (Controller);
|
||||
end if;
|
||||
|
||||
if not Controller.Has_Info then
|
||||
raise Device_Error;
|
||||
end if;
|
||||
|
@ -255,7 +262,7 @@ package body SDCard is
|
|||
|
||||
function Block_Size
|
||||
(Controller : in out SDCard_Controller)
|
||||
return Unsigned_32
|
||||
return UInt32
|
||||
is
|
||||
begin
|
||||
Ensure_Card_Informations (Controller);
|
||||
|
@ -458,6 +465,7 @@ package body SDCard is
|
|||
elsif Get_Flag (Device.all, TX_Underrun) then
|
||||
Clear_Flag (Device.all, TX_Underrun);
|
||||
SD_Status := Tx_Underrun;
|
||||
|
||||
end if;
|
||||
|
||||
for Int in SDMMC_Interrupts loop
|
||||
|
@ -473,7 +481,7 @@ package body SDCard is
|
|||
|
||||
overriding function Write
|
||||
(Controller : in out SDCard_Controller;
|
||||
Block_Number : UInt32;
|
||||
Block_Number : UInt64;
|
||||
Data : Block) return Boolean
|
||||
is
|
||||
Ret : SD_Error;
|
||||
|
@ -492,8 +500,7 @@ package body SDCard is
|
|||
Clear_All_Status (SD_DMA, SD_DMA_Tx_Stream);
|
||||
Ret := Write_Blocks_DMA
|
||||
(Controller.Device.all,
|
||||
Unsigned_64 (Block_Number) *
|
||||
Unsigned_64 (Controller.Info.Card_Block_Size),
|
||||
Block_Number * UInt64 (Controller.Info.Card_Block_Size),
|
||||
SD_DMA,
|
||||
SD_DMA_Tx_Stream,
|
||||
SD_Data (Data));
|
||||
|
@ -539,7 +546,7 @@ package body SDCard is
|
|||
|
||||
overriding function Read
|
||||
(Controller : in out SDCard_Controller;
|
||||
Block_Number : UInt32;
|
||||
Block_Number : UInt64;
|
||||
Data : out Block) return Boolean
|
||||
is
|
||||
Ret : Boolean;
|
||||
|
@ -552,13 +559,12 @@ package body SDCard is
|
|||
SDMMC_Interrupt_Handler.Set_Transfer_State (Controller);
|
||||
|
||||
Cortex_M.Cache.Clean_DCache
|
||||
(Start => Data'Address,
|
||||
(Start => Data (Data'First)'Address,
|
||||
Len => Data'Length);
|
||||
|
||||
SD_Err := Read_Blocks_DMA
|
||||
(Controller.Device.all,
|
||||
Unsigned_64 (Block_Number) *
|
||||
Unsigned_64 (Controller.Info.Card_Block_Size),
|
||||
Block_Number * UInt64 (Controller.Info.Card_Block_Size),
|
||||
SD_DMA,
|
||||
SD_DMA_Rx_Stream,
|
||||
SD_Data (Data));
|
||||
|
@ -572,7 +578,12 @@ package body SDCard is
|
|||
end if;
|
||||
|
||||
SDMMC_Interrupt_Handler.Wait_Transfer (SD_Err);
|
||||
DMA_Interrupt_Handler.Wait_Transfer (DMA_Err);
|
||||
if SD_Err = OK then
|
||||
DMA_Interrupt_Handler.Wait_Transfer (DMA_Err);
|
||||
else
|
||||
DMA_Interrupt_Handler.Clear_Transfer_State;
|
||||
Abort_Transfer (SD_DMA, SD_DMA_Rx_Stream, DMA_Err);
|
||||
end if;
|
||||
|
||||
loop
|
||||
exit when not Get_Flag (Controller.Device.all, RX_Active);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- --
|
||||
-- Copyright (C) 2016, AdaCore --
|
||||
-- Copyright (C) 2016-2017, AdaCore --
|
||||
-- --
|
||||
-- Redistribution and use in source and binary forms, with or without --
|
||||
-- modification, are permitted provided that the following conditions are --
|
||||
|
@ -32,9 +32,9 @@
|
|||
-- @author MCD Application Team --
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
with Interfaces; use Interfaces;
|
||||
with Ada.Interrupts.Names;
|
||||
|
||||
with HAL.SDMMC;
|
||||
with STM32.SDMMC;
|
||||
|
||||
with HAL; use HAL;
|
||||
|
@ -65,31 +65,29 @@ package SDCard is
|
|||
|
||||
function Get_Card_Information
|
||||
(Controller : in out SDCard_Controller)
|
||||
return STM32.SDMMC.Card_Information
|
||||
return HAL.SDMMC.Card_Information
|
||||
with Pre => Controller.Card_Present;
|
||||
-- Retrieves the card informations
|
||||
|
||||
function Block_Size
|
||||
(Controller : in out SDCard_Controller)
|
||||
return Unsigned_32;
|
||||
return UInt32;
|
||||
-- The insterted card block size. 512 Bytes for sd-cards
|
||||
|
||||
overriding function Read
|
||||
(Controller : in out SDCard_Controller;
|
||||
Block_Number : UInt32;
|
||||
Block_Number : UInt64;
|
||||
Data : out Block) return Boolean
|
||||
with Pre => (Data'Size mod Controller.Block_Size) = 0
|
||||
and then Data'Size < 2 ** 16;
|
||||
with Pre => Data'Size < 2 ** 16;
|
||||
-- Reads Data.
|
||||
-- Data size needs to be a multiple of the card's block size and maximum
|
||||
-- length is 2**16
|
||||
|
||||
overriding function Write
|
||||
(Controller : in out SDCard_Controller;
|
||||
Block_Number : UInt32;
|
||||
Block_Number : UInt64;
|
||||
Data : Block) return Boolean
|
||||
with Pre => (Data'Size mod Controller.Block_Size) = 0
|
||||
and then Data'Size < 2 ** 16;
|
||||
with Pre => Data'Size < 2 ** 16;
|
||||
-- Writes Data.
|
||||
-- Data size needs to be a multiple of the card's block size and maximum
|
||||
-- length is 2**16
|
||||
|
@ -99,7 +97,7 @@ private
|
|||
type SDCard_Controller
|
||||
(Device : not null access STM32.SDMMC.SDMMC_Controller) is
|
||||
limited new HAL.Block_Drivers.Block_Driver with record
|
||||
Info : STM32.SDMMC.Card_Information;
|
||||
Info : HAL.SDMMC.Card_Information;
|
||||
Has_Info : Boolean := False;
|
||||
Card_Detected : Boolean := False;
|
||||
end record;
|
||||
|
|
|
@ -34,6 +34,10 @@
|
|||
|
||||
with Ada.Real_Time; use Ada.Real_Time;
|
||||
|
||||
with HAL.SDMMC; use HAL.SDMMC;
|
||||
|
||||
with STM32_SVD.RCC; use STM32_SVD.RCC;
|
||||
|
||||
with STM32.Device; use STM32.Device;
|
||||
with STM32.DMA; use STM32.DMA;
|
||||
with STM32.GPIO; use STM32.GPIO;
|
||||
|
@ -51,7 +55,7 @@ package body SDCard is
|
|||
SD_DMA_Tx_Channel : DMA_Channel_Selector renames Channel_11;
|
||||
|
||||
procedure Ensure_Card_Informations
|
||||
(Controller : in out SDCard_Controller) with Inline_Always;
|
||||
(This : in out SDCard_Controller) with Inline_Always;
|
||||
-- Make sure the sdcard information is read and stored in the Controller
|
||||
-- structure
|
||||
|
||||
|
@ -91,7 +95,7 @@ package body SDCard is
|
|||
protected SDMMC_Interrupt_Handler is
|
||||
pragma Interrupt_Priority (250);
|
||||
|
||||
procedure Set_Transfer_State (Controller : SDCard_Controller);
|
||||
procedure Set_Transfer_State (This : SDCard_Controller);
|
||||
procedure Clear_Transfer_State;
|
||||
entry Wait_Transfer (Status : out SD_Error);
|
||||
|
||||
|
@ -109,7 +113,7 @@ package body SDCard is
|
|||
----------------
|
||||
|
||||
procedure Initialize
|
||||
(Controller : in out SDCard_Controller)
|
||||
(This : in out SDCard_Controller)
|
||||
is
|
||||
SD_Pins_AF_10 : constant STM32.GPIO.GPIO_Points :=
|
||||
(PB3, PB4);
|
||||
|
@ -117,9 +121,11 @@ package body SDCard is
|
|||
(PD6, PD7, PG9, PG10);
|
||||
|
||||
begin
|
||||
RCC_Periph.DKCFGR2.SDMMC2SEL := True; -- SDMMC uses the SYSCLK
|
||||
|
||||
-- Enable the SDIO clock
|
||||
Enable_Clock (SDMMC_Controller (Controller.Device.all));
|
||||
Reset (SDMMC_Controller (Controller.Device.all));
|
||||
Enable_Clock (SDMMC_Controller (This.Device.all));
|
||||
Reset (SDMMC_Controller (This.Device.all));
|
||||
|
||||
-- Enable the DMA2 clock
|
||||
Enable_Clock (SD_DMA);
|
||||
|
@ -134,9 +140,6 @@ package body SDCard is
|
|||
Output_Type => Push_Pull,
|
||||
Speed => Speed_High,
|
||||
Resistors => Pull_Up));
|
||||
-- ??? no GPIO_AF10_SDMMC or AF11 names for now. Waiting for AF
|
||||
-- functions to be moved outside of STM32.GPIO (that is common to
|
||||
-- all STM32)
|
||||
Configure_Alternate_Function (SD_Pins_AF_10, GPIO_AF_SDMMC2_10);
|
||||
Configure_Alternate_Function (SD_Pins_AF_11, GPIO_AF_SDMMC2_11);
|
||||
|
||||
|
@ -190,24 +193,24 @@ package body SDCard is
|
|||
------------------
|
||||
|
||||
function Card_Present
|
||||
(Controller : in out SDCard_Controller) return Boolean
|
||||
(This : in out SDCard_Controller) return Boolean
|
||||
is
|
||||
begin
|
||||
if STM32.GPIO.Set (SD_Detect_Pin) then
|
||||
-- No card
|
||||
Controller.Has_Info := False;
|
||||
Controller.Card_Detected := False;
|
||||
This.Has_Info := False;
|
||||
This.Card_Detected := False;
|
||||
else
|
||||
-- Card detected. Just wait a bit to unbounce the signal from the
|
||||
-- detect pin
|
||||
if not Controller.Card_Detected then
|
||||
if not This.Card_Detected then
|
||||
delay until Clock + Milliseconds (50);
|
||||
end if;
|
||||
|
||||
Controller.Card_Detected := not STM32.GPIO.Set (SD_Detect_Pin);
|
||||
This.Card_Detected := not STM32.GPIO.Set (SD_Detect_Pin);
|
||||
end if;
|
||||
|
||||
return Controller.Card_Detected;
|
||||
return This.Card_Detected;
|
||||
end Card_Present;
|
||||
|
||||
------------------------------
|
||||
|
@ -215,21 +218,26 @@ package body SDCard is
|
|||
------------------------------
|
||||
|
||||
procedure Ensure_Card_Informations
|
||||
(Controller : in out SDCard_Controller)
|
||||
(This : in out SDCard_Controller)
|
||||
is
|
||||
Ret : SD_Error;
|
||||
begin
|
||||
if Controller.Has_Info then
|
||||
if This.Has_Info then
|
||||
return;
|
||||
end if;
|
||||
|
||||
Enable_Clock (SDMMC_Controller (This.Device.all));
|
||||
Reset (SDMMC_Controller (This.Device.all));
|
||||
|
||||
Ret := STM32.SDMMC.Initialize
|
||||
(Controller.Device.all, Controller.Info);
|
||||
(This.Device.all,
|
||||
System_Clock_Frequencies.SYSCLK,
|
||||
This.Info);
|
||||
|
||||
if Ret = OK then
|
||||
Controller.Has_Info := True;
|
||||
This.Has_Info := True;
|
||||
else
|
||||
Controller.Has_Info := False;
|
||||
This.Has_Info := False;
|
||||
end if;
|
||||
end Ensure_Card_Informations;
|
||||
|
||||
|
@ -238,22 +246,17 @@ package body SDCard is
|
|||
--------------------------
|
||||
|
||||
function Get_Card_Information
|
||||
(Controller : in out SDCard_Controller)
|
||||
return STM32.SDMMC.Card_Information
|
||||
(This : in out SDCard_Controller)
|
||||
return Card_Information
|
||||
is
|
||||
begin
|
||||
Ensure_Card_Informations (Controller);
|
||||
Ensure_Card_Informations (This);
|
||||
|
||||
if not Controller.Has_Info then
|
||||
-- Issue reading the SD-card information
|
||||
Ensure_Card_Informations (Controller);
|
||||
end if;
|
||||
|
||||
if not Controller.Has_Info then
|
||||
if not This.Has_Info then
|
||||
raise Device_Error;
|
||||
end if;
|
||||
|
||||
return Controller.Info;
|
||||
return This.Info;
|
||||
end Get_Card_Information;
|
||||
|
||||
----------------
|
||||
|
@ -261,13 +264,13 @@ package body SDCard is
|
|||
----------------
|
||||
|
||||
function Block_Size
|
||||
(Controller : in out SDCard_Controller)
|
||||
return Unsigned_32
|
||||
(This : in out SDCard_Controller)
|
||||
return UInt32
|
||||
is
|
||||
begin
|
||||
Ensure_Card_Informations (Controller);
|
||||
Ensure_Card_Informations (This);
|
||||
|
||||
return Controller.Info.Card_Block_Size;
|
||||
return This.Info.Card_Block_Size;
|
||||
end Block_Size;
|
||||
|
||||
---------------------------
|
||||
|
@ -419,11 +422,11 @@ package body SDCard is
|
|||
-- Set_Transferring --
|
||||
----------------------
|
||||
|
||||
procedure Set_Transfer_State (Controller : SDCard_Controller)
|
||||
procedure Set_Transfer_State (This : SDCard_Controller)
|
||||
is
|
||||
begin
|
||||
Finished := False;
|
||||
Device := Controller.Device.all'Unchecked_Access;
|
||||
Device := This.Device.all'Unchecked_Access;
|
||||
end Set_Transfer_State;
|
||||
|
||||
--------------------------
|
||||
|
@ -465,6 +468,7 @@ package body SDCard is
|
|||
elsif Get_Flag (Device.all, TX_Underrun) then
|
||||
Clear_Flag (Device.all, TX_Underrun);
|
||||
SD_Status := Tx_Underrun;
|
||||
|
||||
end if;
|
||||
|
||||
for Int in SDMMC_Interrupts loop
|
||||
|
@ -479,14 +483,14 @@ package body SDCard is
|
|||
-----------
|
||||
|
||||
overriding function Write
|
||||
(Controller : in out SDCard_Controller;
|
||||
Block_Number : UInt32;
|
||||
(This : in out SDCard_Controller;
|
||||
Block_Number : UInt64;
|
||||
Data : Block) return Boolean
|
||||
is
|
||||
Ret : SD_Error;
|
||||
DMA_Err : DMA_Error_Code;
|
||||
begin
|
||||
Ensure_Card_Informations (Controller);
|
||||
Ensure_Card_Informations (This);
|
||||
|
||||
-- Flush the data cache
|
||||
Cortex_M.Cache.Clean_DCache
|
||||
|
@ -494,13 +498,12 @@ package body SDCard is
|
|||
Len => Data'Length);
|
||||
|
||||
DMA_Interrupt_Handler.Set_Transfer_State;
|
||||
SDMMC_Interrupt_Handler.Set_Transfer_State (Controller);
|
||||
SDMMC_Interrupt_Handler.Set_Transfer_State (This);
|
||||
|
||||
Clear_All_Status (SD_DMA, SD_DMA_Tx_Stream);
|
||||
Ret := Write_Blocks_DMA
|
||||
(Controller.Device.all,
|
||||
Unsigned_64 (Block_Number) *
|
||||
Unsigned_64 (Controller.Info.Card_Block_Size),
|
||||
(This.Device.all,
|
||||
Block_Number * UInt64 (This.Info.Card_Block_Size),
|
||||
SD_DMA,
|
||||
SD_DMA_Tx_Stream,
|
||||
SD_Data (Data));
|
||||
|
@ -522,7 +525,7 @@ package body SDCard is
|
|||
loop
|
||||
-- FIXME: some people claim, that this goes wrong with multiblock, see
|
||||
-- http://blog.frankvh.com/2011/09/04/stm32f2xx-sdio-sd-card-interface/
|
||||
exit when not Get_Flag (Controller.Device.all, TX_Active);
|
||||
exit when not Get_Flag (This.Device.all, TX_Active);
|
||||
end loop;
|
||||
|
||||
Clear_All_Status (SD_DMA, SD_DMA_Tx_Stream);
|
||||
|
@ -545,27 +548,26 @@ package body SDCard is
|
|||
----------
|
||||
|
||||
overriding function Read
|
||||
(Controller : in out SDCard_Controller;
|
||||
Block_Number : UInt32;
|
||||
(This : in out SDCard_Controller;
|
||||
Block_Number : UInt64;
|
||||
Data : out Block) return Boolean
|
||||
is
|
||||
Ret : Boolean;
|
||||
SD_Err : SD_Error;
|
||||
DMA_Err : DMA_Error_Code;
|
||||
begin
|
||||
Ensure_Card_Informations (Controller);
|
||||
Ensure_Card_Informations (This);
|
||||
|
||||
DMA_Interrupt_Handler.Set_Transfer_State;
|
||||
SDMMC_Interrupt_Handler.Set_Transfer_State (Controller);
|
||||
SDMMC_Interrupt_Handler.Set_Transfer_State (This);
|
||||
|
||||
Cortex_M.Cache.Clean_DCache
|
||||
(Start => Data'Address,
|
||||
(Start => Data (Data'First)'Address,
|
||||
Len => Data'Length);
|
||||
|
||||
SD_Err := Read_Blocks_DMA
|
||||
(Controller.Device.all,
|
||||
Unsigned_64 (Block_Number) *
|
||||
Unsigned_64 (Controller.Info.Card_Block_Size),
|
||||
(This.Device.all,
|
||||
Block_Number * UInt64 (This.Info.Card_Block_Size),
|
||||
SD_DMA,
|
||||
SD_DMA_Rx_Stream,
|
||||
SD_Data (Data));
|
||||
|
@ -579,25 +581,30 @@ package body SDCard is
|
|||
end if;
|
||||
|
||||
SDMMC_Interrupt_Handler.Wait_Transfer (SD_Err);
|
||||
DMA_Interrupt_Handler.Wait_Transfer (DMA_Err);
|
||||
if SD_Err = OK then
|
||||
DMA_Interrupt_Handler.Wait_Transfer (DMA_Err);
|
||||
else
|
||||
DMA_Interrupt_Handler.Clear_Transfer_State;
|
||||
Abort_Transfer (SD_DMA, SD_DMA_Rx_Stream, DMA_Err);
|
||||
end if;
|
||||
|
||||
loop
|
||||
exit when not Get_Flag (Controller.Device.all, RX_Active);
|
||||
exit when not Get_Flag (This.Device.all, RX_Active);
|
||||
end loop;
|
||||
|
||||
Ret := SD_Err = OK and then DMA_Err = DMA_No_Error;
|
||||
|
||||
if Last_Operation (Controller.Device.all) =
|
||||
if Last_Operation (This.Device.all) =
|
||||
Read_Multiple_Blocks_Operation
|
||||
then
|
||||
SD_Err := Stop_Transfer (Controller.Device.all);
|
||||
SD_Err := Stop_Transfer (This.Device.all);
|
||||
Ret := Ret and then SD_Err = OK;
|
||||
end if;
|
||||
|
||||
Clear_All_Status (SD_DMA, SD_DMA_Rx_Stream);
|
||||
Disable (SD_DMA, SD_DMA_Rx_Stream);
|
||||
Disable_Data (Controller.Device.all);
|
||||
Clear_Static_Flags (Controller.Device.all);
|
||||
Disable_Data (This.Device.all);
|
||||
Clear_Static_Flags (This.Device.all);
|
||||
|
||||
Cortex_M.Cache.Invalidate_DCache
|
||||
(Start => Data'Address,
|
||||
|
|
|
@ -32,9 +32,9 @@
|
|||
-- @author MCD Application Team --
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
with Interfaces; use Interfaces;
|
||||
with Ada.Interrupts.Names;
|
||||
|
||||
with HAL.SDMMC;
|
||||
with STM32.SDMMC;
|
||||
|
||||
with HAL; use HAL;
|
||||
|
@ -51,45 +51,43 @@ package SDCard is
|
|||
|
||||
type SDCard_Controller
|
||||
(Device : not null access STM32.SDMMC.SDMMC_Controller) is
|
||||
limited new HAL.Block_Drivers.Block_Driver with private;
|
||||
limited new Block_Driver with private;
|
||||
|
||||
Device_Error : exception;
|
||||
|
||||
procedure Initialize
|
||||
(Controller : in out SDCard_Controller);
|
||||
(This : in out SDCard_Controller);
|
||||
-- Initilizes the Controller's pins
|
||||
|
||||
function Card_Present
|
||||
(Controller : in out SDCard_Controller) return Boolean;
|
||||
(This : in out SDCard_Controller) return Boolean;
|
||||
-- Whether a SD-Card is present in the sdcard reader
|
||||
|
||||
function Get_Card_Information
|
||||
(Controller : in out SDCard_Controller)
|
||||
return STM32.SDMMC.Card_Information
|
||||
with Pre => Controller.Card_Present;
|
||||
(This : in out SDCard_Controller)
|
||||
return HAL.SDMMC.Card_Information
|
||||
with Pre => This.Card_Present;
|
||||
-- Retrieves the card informations
|
||||
|
||||
function Block_Size
|
||||
(Controller : in out SDCard_Controller)
|
||||
return Unsigned_32;
|
||||
(This : in out SDCard_Controller)
|
||||
return UInt32;
|
||||
-- The insterted card block size. 512 Bytes for sd-cards
|
||||
|
||||
overriding function Read
|
||||
(Controller : in out SDCard_Controller;
|
||||
Block_Number : UInt32;
|
||||
(This : in out SDCard_Controller;
|
||||
Block_Number : UInt64;
|
||||
Data : out Block) return Boolean
|
||||
with Pre => (Data'Size mod Controller.Block_Size) = 0
|
||||
and then Data'Size < 2 ** 16;
|
||||
with Pre => Data'Length <= 16#10000#;
|
||||
-- Reads Data.
|
||||
-- Data size needs to be a multiple of the card's block size and maximum
|
||||
-- length is 2**16
|
||||
|
||||
overriding function Write
|
||||
(Controller : in out SDCard_Controller;
|
||||
Block_Number : UInt32;
|
||||
(This : in out SDCard_Controller;
|
||||
Block_Number : UInt64;
|
||||
Data : Block) return Boolean
|
||||
with Pre => (Data'Size mod Controller.Block_Size) = 0
|
||||
and then Data'Size < 2 ** 16;
|
||||
with Pre => Data'Length <= 16#10000#;
|
||||
-- Writes Data.
|
||||
-- Data size needs to be a multiple of the card's block size and maximum
|
||||
-- length is 2**16
|
||||
|
@ -99,7 +97,7 @@ private
|
|||
type SDCard_Controller
|
||||
(Device : not null access STM32.SDMMC.SDMMC_Controller) is
|
||||
limited new HAL.Block_Drivers.Block_Driver with record
|
||||
Info : STM32.SDMMC.Card_Information;
|
||||
Info : HAL.SDMMC.Card_Information;
|
||||
Has_Info : Boolean := False;
|
||||
Card_Detected : Boolean := False;
|
||||
end record;
|
||||
|
|
|
@ -36,16 +36,21 @@ package HAL.Block_Drivers is
|
|||
|
||||
subtype Block is UInt8_Array;
|
||||
|
||||
Block_Size : constant := 512;
|
||||
-- Size of a block, for block number.
|
||||
|
||||
function Read
|
||||
(This : in out Block_Driver;
|
||||
Block_Number : UInt32;
|
||||
Block_Number : UInt64;
|
||||
Data : out Block)
|
||||
return Boolean is abstract;
|
||||
return Boolean is abstract
|
||||
with Pre'Class => Data'Length mod Block_Size = 0;
|
||||
|
||||
function Write
|
||||
(This : in out Block_Driver;
|
||||
Block_Number : UInt32;
|
||||
Block_Number : UInt64;
|
||||
Data : Block)
|
||||
return Boolean is abstract;
|
||||
return Boolean is abstract
|
||||
with Pre'Class => Data'Length mod Block_Size = 0;
|
||||
|
||||
end HAL.Block_Drivers;
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- --
|
||||
-- Copyright (C) 2016-2017, AdaCore --
|
||||
-- --
|
||||
-- Redistribution and use in source and binary forms, with or without --
|
||||
-- modification, are permitted provided that the following conditions are --
|
||||
-- met: --
|
||||
-- 1. Redistributions of source code must retain the above copyright --
|
||||
-- notice, this list of conditions and the following disclaimer. --
|
||||
-- 2. Redistributions in binary form must reproduce the above copyright --
|
||||
-- notice, this list of conditions and the following disclaimer in --
|
||||
-- the documentation and/or other materials provided with the --
|
||||
-- distribution. --
|
||||
-- 3. Neither the name of STMicroelectronics nor the names of its --
|
||||
-- contributors may be used to endorse or promote products derived --
|
||||
-- from this software without specific prior written permission. --
|
||||
-- --
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS --
|
||||
-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT --
|
||||
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR --
|
||||
-- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT --
|
||||
-- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, --
|
||||
-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT --
|
||||
-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, --
|
||||
-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY --
|
||||
-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT --
|
||||
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE --
|
||||
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --
|
||||
-- --
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
package body HAL.SDMMC is
|
||||
|
||||
--------------
|
||||
-- Send_Cmd --
|
||||
--------------
|
||||
|
||||
procedure Send_Cmd
|
||||
(This : in out SDMMC_Driver'Class;
|
||||
Cmd : SD_Command;
|
||||
Arg : UInt32;
|
||||
Status : out SD_Error) is
|
||||
begin
|
||||
Send_Cmd (This, Cmd_Desc (Cmd), Arg, Status);
|
||||
end Send_Cmd;
|
||||
|
||||
---------------
|
||||
-- Send_ACmd --
|
||||
---------------
|
||||
|
||||
procedure Send_ACmd
|
||||
(This : in out SDMMC_Driver'Class;
|
||||
Cmd : SD_Specific_Command;
|
||||
Rca : UInt16;
|
||||
Arg : UInt32;
|
||||
Status : out SD_Error)
|
||||
is
|
||||
S_Arg : constant UInt32 :=
|
||||
Shift_Left (UInt32 (Rca), 16);
|
||||
begin
|
||||
Send_Cmd (This, Cmd_Desc (App_Cmd), S_Arg, Status);
|
||||
|
||||
if Status /= OK then
|
||||
return;
|
||||
end if;
|
||||
|
||||
Send_Cmd (This, Acmd_Desc (Cmd), Arg, Status);
|
||||
end Send_ACmd;
|
||||
|
||||
end HAL.SDMMC;
|
|
@ -0,0 +1,441 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- --
|
||||
-- Copyright (C) 2016-2017, AdaCore --
|
||||
-- --
|
||||
-- Redistribution and use in source and binary forms, with or without --
|
||||
-- modification, are permitted provided that the following conditions are --
|
||||
-- met: --
|
||||
-- 1. Redistributions of source code must retain the above copyright --
|
||||
-- notice, this list of conditions and the following disclaimer. --
|
||||
-- 2. Redistributions in binary form must reproduce the above copyright --
|
||||
-- notice, this list of conditions and the following disclaimer in --
|
||||
-- the documentation and/or other materials provided with the --
|
||||
-- distribution. --
|
||||
-- 3. Neither the name of STMicroelectronics nor the names of its --
|
||||
-- contributors may be used to endorse or promote products derived --
|
||||
-- from this software without specific prior written permission. --
|
||||
-- --
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS --
|
||||
-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT --
|
||||
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR --
|
||||
-- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT --
|
||||
-- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, --
|
||||
-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT --
|
||||
-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, --
|
||||
-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY --
|
||||
-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT --
|
||||
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE --
|
||||
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --
|
||||
-- --
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
package HAL.SDMMC is
|
||||
|
||||
type SD_Error is
|
||||
(OK,
|
||||
Error,
|
||||
Timeout_Error,
|
||||
Command_Timeout_Error,
|
||||
Unsupported_Card,
|
||||
Rx_Overrun,
|
||||
Tx_Underrun,
|
||||
Request_Not_Applicable,
|
||||
CRC_Check_Fail,
|
||||
Illegal_Cmd,
|
||||
Address_Out_Of_Range,
|
||||
Address_Missaligned,
|
||||
Block_Length_Error,
|
||||
Erase_Seq_Error,
|
||||
Bad_Erase_Parameter,
|
||||
Write_Protection_Violation,
|
||||
Lock_Unlock_Failed,
|
||||
Card_ECC_Failed,
|
||||
Card_ECC_Disabled,
|
||||
CC_Error,
|
||||
General_Unknown_Error,
|
||||
Stream_Read_Underrun,
|
||||
Stream_Write_Underrun,
|
||||
CID_CSD_Overwrite,
|
||||
WP_Erase_Skip,
|
||||
Erase_Reset,
|
||||
AKE_SEQ_Error,
|
||||
Invalid_Voltage_Range,
|
||||
Startbit_Not_Detected,
|
||||
DMA_Alignment_Error);
|
||||
|
||||
-- Wide bus mode
|
||||
type Wide_Bus_Mode is
|
||||
(
|
||||
-- Default bus mode: SDMMC_D0 is used.
|
||||
Wide_Bus_1B,
|
||||
-- 4-wide bus mode: SDMMC_D[3:0] used.
|
||||
Wide_Bus_4B,
|
||||
-- 8-wide bus mode: SDMMC_D[7:0] used.
|
||||
Wide_Bus_8B)
|
||||
with Size => 2;
|
||||
for Wide_Bus_Mode use
|
||||
(Wide_Bus_1B => 0,
|
||||
Wide_Bus_4B => 1,
|
||||
Wide_Bus_8B => 2);
|
||||
|
||||
type Supported_SD_Memory_Cards is
|
||||
(STD_Capacity_SD_Card_V1_1,
|
||||
STD_Capacity_SD_Card_v2_0,
|
||||
High_Capacity_SD_Card,
|
||||
Multimedia_Card,
|
||||
Secure_Digital_IO_Card,
|
||||
High_Speed_Multimedia_Card,
|
||||
Secure_Digital_IO_Combo_Card,
|
||||
High_Capacity_MMC_Card);
|
||||
|
||||
type Card_Specific_Data_Register is record
|
||||
CSD_Structure : UInt8;
|
||||
System_Specification_Version : UInt8;
|
||||
Reserved : UInt8;
|
||||
Data_Read_Access_Time_1 : UInt8;
|
||||
Data_Read_Access_Time_2 : UInt8; -- In CLK Cycles
|
||||
Max_Data_Transfer_Rate : UInt8;
|
||||
Card_Command_Class : UInt16;
|
||||
Max_Read_Data_Block_Length : UInt8;
|
||||
Partial_Block_For_Read_Allowed : Boolean;
|
||||
Write_Block_Missalignment : Boolean;
|
||||
Read_Block_Missalignment : Boolean;
|
||||
DSR_Implemented : Boolean;
|
||||
Reserved_2 : UInt8;
|
||||
Device_Size : UInt32;
|
||||
Max_Read_Current_At_VDD_Min : UInt8;
|
||||
Max_Read_Current_At_VDD_Max : UInt8;
|
||||
Max_Write_Current_At_VDD_Min : UInt8;
|
||||
Max_Write_Current_At_VDD_Max : UInt8;
|
||||
Device_Size_Multiplier : UInt8;
|
||||
Erase_Group_Size : UInt8;
|
||||
Erase_Group_Size_Multiplier : UInt8;
|
||||
Write_Protect_Group_Size : UInt8;
|
||||
Write_Protect_Group_Enable : Boolean;
|
||||
Manufacturer_Default_ECC : UInt8;
|
||||
Write_Speed_Factor : UInt8;
|
||||
Max_Write_Data_Block_Length : UInt8;
|
||||
Partial_Blocks_For_Write_Allowed : Boolean;
|
||||
Reserved_3 : UInt8;
|
||||
Content_Protection_Application : Boolean;
|
||||
File_Format_Group : Boolean;
|
||||
Copy_Flag : Boolean;
|
||||
Permanent_Write_Protection : Boolean;
|
||||
Temporary_Write_Protection : Boolean;
|
||||
File_Format : UInt8;
|
||||
ECC_Code : UInt8;
|
||||
CSD_CRC : UInt8;
|
||||
Reserved_4 : UInt8; -- Always 1
|
||||
end record;
|
||||
|
||||
type Card_Revision is record
|
||||
Major : UInt4;
|
||||
Minor : UInt4;
|
||||
end record with Pack;
|
||||
|
||||
type Manufacturing_Year is range 2000 .. 2255;
|
||||
type Manufacturing_Month is
|
||||
(January,
|
||||
February,
|
||||
March,
|
||||
April,
|
||||
May,
|
||||
June,
|
||||
July,
|
||||
August,
|
||||
September,
|
||||
October,
|
||||
November,
|
||||
December) with Size => 4;
|
||||
|
||||
type Manufacturing_Date_Type is record
|
||||
Year : Manufacturing_Year;
|
||||
Month : Manufacturing_Month;
|
||||
end record;
|
||||
|
||||
type Card_Identification_Data_Register is record
|
||||
Manufacturer_ID : UInt8;
|
||||
OEM_Application_ID : String (1 .. 2);
|
||||
Product_Name : String (1 .. 5);
|
||||
Product_Revision : Card_Revision;
|
||||
Product_Serial_Number : UInt32;
|
||||
Reserved_1 : UInt8;
|
||||
Manufacturing_Date : Manufacturing_Date_Type;
|
||||
CID_CRC : UInt8;
|
||||
Reserved_2 : UInt8; -- Always 1
|
||||
end record;
|
||||
|
||||
type SDCard_Configuration_Register is record
|
||||
SCR_Structure : UInt8;
|
||||
SD_Spec : UInt8;
|
||||
Data_Stat_After_Erase : UInt8;
|
||||
SD_Security : UInt8;
|
||||
SD_Bus_Widths : UInt8;
|
||||
SD_Spec3 : Boolean;
|
||||
Ex_Security : UInt8;
|
||||
SD_Spec4 : Boolean;
|
||||
Reserved_1 : UInt8;
|
||||
CMD_Support : UInt8;
|
||||
Reserved_2 : UInt32;
|
||||
end record;
|
||||
|
||||
type Card_Information is record
|
||||
SD_CSD : Card_Specific_Data_Register;
|
||||
SD_CID : Card_Identification_Data_Register;
|
||||
Card_Capacity : UInt64;
|
||||
Card_Block_Size : UInt32;
|
||||
RCA : UInt16; -- SD relative card address
|
||||
Card_Type : Supported_SD_Memory_Cards :=
|
||||
STD_Capacity_SD_Card_V1_1;
|
||||
end record;
|
||||
|
||||
type SD_Command is new UInt6;
|
||||
|
||||
-- Resets the SD memory card
|
||||
Go_Idle_State : constant SD_Command := 0;
|
||||
|
||||
-- Sends host capacity support information and activates the card's
|
||||
-- initialization process
|
||||
Send_Op_Cond : constant SD_Command := 1; -- Only for MMC
|
||||
|
||||
-- Asks any card connected to the host to send the CID numbers on the
|
||||
-- CMD line.
|
||||
All_Send_CID : constant SD_Command := 2;
|
||||
|
||||
-- Asks the card to publish a new relative address (RCA).
|
||||
Send_Relative_Addr : constant SD_Command := 3;
|
||||
|
||||
-- Programs the DSR of all cards.
|
||||
Set_DSR : constant SD_Command := 4;
|
||||
|
||||
-- Sends host capacity support information (HCS) and asks the accessed
|
||||
-- card to send its operating condition register (OCR) content in the
|
||||
-- response on the CMD line.
|
||||
SDMMC_Send_Op_Cond : constant SD_Command := 5;
|
||||
|
||||
-- Checks switchable function (mode 0) and switch card function (mode 1).
|
||||
Switch_Func : constant SD_Command := 6;
|
||||
|
||||
-- Selects the card by its own relative address and gets deselected by
|
||||
-- any other address
|
||||
Select_Card : constant SD_Command := 7;
|
||||
Deselect_Card : constant SD_Command := 7;
|
||||
|
||||
-- Sends SD Memory Card interface condition
|
||||
Send_If_Cond : constant SD_Command := 8;
|
||||
|
||||
-- Addressed card sends its card specific data
|
||||
Send_CSD : constant SD_Command := 9;
|
||||
|
||||
-- Addressed card sends its card identification (CID) on the CMD line.
|
||||
Send_CID : constant SD_Command := 10;
|
||||
|
||||
Read_Dat_Until_Stop : constant SD_Command := 11;
|
||||
Stop_Transmission : constant SD_Command := 12;
|
||||
Send_Status : constant SD_Command := 13;
|
||||
HS_Bustest_Read : constant SD_Command := 14;
|
||||
Go_Inactive_State : constant SD_Command := 15;
|
||||
Set_Blocklen : constant SD_Command := 16;
|
||||
Read_Single_Block : constant SD_Command := 17;
|
||||
Read_Multi_Block : constant SD_Command := 18;
|
||||
HS_Bustest_Write : constant SD_Command := 19;
|
||||
Write_Dat_Until_Stop : constant SD_Command := 20;
|
||||
Set_Block_Count : constant SD_Command := 23; -- Only for MMC
|
||||
Write_Single_Block : constant SD_Command := 24;
|
||||
Write_Multi_Block : constant SD_Command := 25;
|
||||
Prog_CID : constant SD_Command := 26;
|
||||
Prog_CSD : constant SD_Command := 27;
|
||||
Set_Write_Prot : constant SD_Command := 28;
|
||||
Clr_Write_Prot : constant SD_Command := 29;
|
||||
Send_Write_Prot : constant SD_Command := 30;
|
||||
SD_Erase_Grp_Start : constant SD_Command := 32;
|
||||
SD_Erase_Grp_End : constant SD_Command := 33;
|
||||
Erase_Grp_Start : constant SD_Command := 35;
|
||||
Erase_Grp_End : constant SD_Command := 36;
|
||||
Erase : constant SD_Command := 38;
|
||||
Fast_IO : constant SD_Command := 39;
|
||||
Go_IRQ_State : constant SD_Command := 40;
|
||||
Lock_Unlock : constant SD_Command := 42;
|
||||
App_Cmd : constant SD_Command := 55;
|
||||
Gen_Cmd : constant SD_Command := 56;
|
||||
|
||||
-- SD-Card speciric commands
|
||||
-- App_Cmd should be sent before sending these commands
|
||||
subtype SD_Specific_Command is SD_Command;
|
||||
|
||||
SD_App_Set_Bus_Width : constant SD_Specific_Command := 6;
|
||||
SD_App_Status : constant SD_Specific_Command := 13;
|
||||
SD_App_Secure_Read_Multi_Block : constant SD_Specific_Command := 18;
|
||||
SD_App_Send_Num_Write_Blocks : constant SD_Specific_Command := 22;
|
||||
SD_App_Set_Write_Block_Erase_Count : constant SD_Specific_Command := 23;
|
||||
SD_App_Secure_Write_Multi_Block : constant SD_Specific_Command := 25;
|
||||
SD_App_Secure_Erase : constant SD_Specific_Command := 38;
|
||||
SD_App_Send_Op_Cond : constant SD_Specific_Command := 41;
|
||||
SD_App_Get_MKB : constant SD_Specific_Command := 43;
|
||||
SD_App_Get_MID : constant SD_Specific_Command := 44;
|
||||
SD_App_Set_CER_RN1 : constant SD_Specific_Command := 45;
|
||||
SD_App_Get_CER_RN2 : constant SD_Specific_Command := 46;
|
||||
SD_App_Set_CER_RES2 : constant SD_Specific_Command := 47;
|
||||
SD_App_Get_CER_RES1 : constant SD_Specific_Command := 48;
|
||||
SD_App_Change_Secure_Area : constant SD_Specific_Command := 49;
|
||||
SD_App_Send_SCR : constant SD_Specific_Command := 51;
|
||||
|
||||
type Rsp_Kind is
|
||||
(Rsp_Invalid,
|
||||
-- Unknown/invalid command
|
||||
|
||||
Rsp_No,
|
||||
-- No response.
|
||||
|
||||
Rsp_R1, Rsp_R1B, Rsp_R2, Rsp_R3, Rsp_R6, Rsp_R7
|
||||
-- Response with format
|
||||
);
|
||||
-- Response format
|
||||
|
||||
type Tfr_Kind is
|
||||
(Tfr_Invalid, Tfr_No,
|
||||
Tfr_Read, Tfr_Write,
|
||||
Tfr_Read_Multi, Tfr_Write_Multi);
|
||||
-- Transfer
|
||||
|
||||
type Cmd_Desc_Type is record
|
||||
Cmd : SD_Command;
|
||||
Rsp : Rsp_Kind;
|
||||
Tfr : Tfr_Kind;
|
||||
end record;
|
||||
|
||||
type Cmd_Desc_Array is array (SD_Command) of Cmd_Desc_Type;
|
||||
type ACmd_Desc_Array is array (SD_Specific_Command) of Cmd_Desc_Type;
|
||||
|
||||
Cmd_Desc : constant Cmd_Desc_Array :=
|
||||
(Go_Idle_State => (Cmd => Go_Idle_State,
|
||||
Rsp => Rsp_No,
|
||||
Tfr => Tfr_No),
|
||||
Send_Op_Cond => (Cmd => Send_Op_Cond,
|
||||
Rsp => Rsp_R3,
|
||||
Tfr => Tfr_No),
|
||||
All_Send_CID => (Cmd => All_Send_CID,
|
||||
Rsp => Rsp_R2,
|
||||
Tfr => Tfr_No),
|
||||
Send_Relative_Addr => (Cmd => Send_Relative_Addr,
|
||||
Rsp => Rsp_R3,
|
||||
Tfr => Tfr_No),
|
||||
Switch_Func => (Cmd => Switch_Func,
|
||||
Rsp => Rsp_R1,
|
||||
Tfr => Tfr_Read),
|
||||
Select_Card => (Cmd => Select_Card,
|
||||
Rsp => Rsp_R1B,
|
||||
Tfr => Tfr_No),
|
||||
Send_If_Cond => (Cmd => Send_If_Cond,
|
||||
Rsp => Rsp_R7,
|
||||
Tfr => Tfr_No),
|
||||
Send_CSD => (Cmd => Send_CSD,
|
||||
Rsp => Rsp_R2,
|
||||
Tfr => Tfr_No),
|
||||
Send_CID => (Cmd => Send_CID,
|
||||
Rsp => Rsp_R2,
|
||||
Tfr => Tfr_No),
|
||||
Stop_Transmission => (Cmd => Stop_Transmission,
|
||||
Rsp => Rsp_R1,
|
||||
Tfr => Tfr_No),
|
||||
Read_Single_Block => (Cmd => Read_Single_Block,
|
||||
Rsp => Rsp_R1,
|
||||
Tfr => Tfr_Read),
|
||||
Read_Multi_Block => (Cmd => Read_Multi_Block,
|
||||
Rsp => Rsp_R1,
|
||||
Tfr => Tfr_Read_Multi),
|
||||
Send_Status => (Cmd => Send_Status,
|
||||
Rsp => Rsp_R1,
|
||||
Tfr => Tfr_No),
|
||||
Set_Blocklen => (Cmd => Set_Blocklen,
|
||||
Rsp => Rsp_R1,
|
||||
Tfr => Tfr_No),
|
||||
App_Cmd => (Cmd => App_Cmd,
|
||||
Rsp => Rsp_R1,
|
||||
Tfr => Tfr_No),
|
||||
others => (Cmd => 0,
|
||||
Rsp => Rsp_Invalid,
|
||||
Tfr => Tfr_Invalid));
|
||||
|
||||
Acmd_Desc : constant ACmd_Desc_Array :=
|
||||
(SD_App_Set_Bus_Width => (Cmd => SD_App_Set_Bus_Width,
|
||||
Rsp => Rsp_R1,
|
||||
Tfr => Tfr_No),
|
||||
SD_App_Send_Op_Cond => (Cmd => SD_App_Send_Op_Cond,
|
||||
Rsp => Rsp_R3,
|
||||
Tfr => Tfr_No),
|
||||
SD_App_Send_SCR => (Cmd => SD_App_Send_SCR,
|
||||
Rsp => Rsp_R1,
|
||||
Tfr => Tfr_Read),
|
||||
others => (Cmd => 0,
|
||||
Rsp => Rsp_Invalid,
|
||||
Tfr => Tfr_Invalid));
|
||||
|
||||
type SDMMC_Driver is limited interface;
|
||||
|
||||
procedure Delay_Milliseconds
|
||||
(This : SDMMC_Driver;
|
||||
Amount : Natural) is abstract;
|
||||
-- Do not use directly 'delay until' so that this package can still be
|
||||
-- used with the zfp profile
|
||||
|
||||
procedure Reset
|
||||
(This : in out SDMMC_Driver;
|
||||
Status : out SD_Error) is abstract;
|
||||
-- Initialize the driver, enable clocking.
|
||||
|
||||
procedure Set_Clock
|
||||
(This : in out SDMMC_Driver;
|
||||
Freq : Natural) is abstract;
|
||||
-- Set clock frequency.
|
||||
|
||||
procedure Set_Bus_Size
|
||||
(This : in out SDMMC_Driver;
|
||||
Mode : Wide_Bus_Mode) is abstract;
|
||||
-- Set host bus size; the command must have been set to the card.
|
||||
|
||||
procedure Send_Cmd
|
||||
(This : in out SDMMC_Driver;
|
||||
Cmd : Cmd_Desc_Type;
|
||||
Arg : UInt32;
|
||||
Status : out SD_Error) is abstract;
|
||||
-- Send a command (without data transfer) and wait for result.
|
||||
|
||||
procedure Read_Cmd
|
||||
(This : in out SDMMC_Driver;
|
||||
Cmd : Cmd_Desc_Type;
|
||||
Arg : UInt32;
|
||||
Buf : out UInt32_Array;
|
||||
Status : out SD_Error) is abstract;
|
||||
-- Read data command
|
||||
|
||||
procedure Read_Rsp48
|
||||
(This : in out SDMMC_Driver;
|
||||
Rsp : out UInt32) is abstract;
|
||||
-- Read the 32 interesting bits of the last 48bits response (start bit,
|
||||
-- transmission bit, command index, crc and end bit are discarded).
|
||||
-- Cannot fail.
|
||||
|
||||
procedure Read_Rsp136
|
||||
(This : in out SDMMC_Driver;
|
||||
W0, W1, W2, W3 : out UInt32) is abstract;
|
||||
-- Read the 128 interesting bits of the last 136 bit response.
|
||||
-- W0 is the MSB, W3 the LSB
|
||||
-- Cannot fail.
|
||||
|
||||
procedure Send_Cmd
|
||||
(This : in out SDMMC_Driver'Class;
|
||||
Cmd : SD_Command;
|
||||
Arg : UInt32;
|
||||
Status : out SD_Error);
|
||||
-- Wrapper for Send_Cmd using a generic command.
|
||||
|
||||
procedure Send_ACmd
|
||||
(This : in out SDMMC_Driver'Class;
|
||||
Cmd : SD_Specific_Command;
|
||||
Rca : UInt16;
|
||||
Arg : UInt32;
|
||||
Status : out SD_Error);
|
||||
-- Send application specific command
|
||||
|
||||
end HAL.SDMMC;
|
|
@ -161,6 +161,6 @@ package HAL is
|
|||
|
||||
type UInt8_Array is array (Natural range <>) of UInt8;
|
||||
type UInt16_Array is array (Natural range <>) of UInt16;
|
||||
type Word_Array is array (Natural range <>) of UInt32;
|
||||
type UInt32_Array is array (Natural range <>) of UInt32;
|
||||
|
||||
end HAL;
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
with "config";
|
||||
with "../hal/HAL";
|
||||
|
||||
library project SDMMC is
|
||||
|
||||
for Library_Name use "sdmmc";
|
||||
for Library_Kind use "static";
|
||||
for Library_Dir use "lib/" & Config.Object_Subdir;
|
||||
for Object_Dir use "obj/" & Config.Object_Subdir;
|
||||
|
||||
for Source_Dirs use
|
||||
("sdmmc");
|
||||
|
||||
package Compiler renames Config.Compiler;
|
||||
package Builder renames Config.Builder;
|
||||
|
||||
end SDMMC;
|
|
@ -0,0 +1,664 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- --
|
||||
-- Copyright (C) 2015-2017, AdaCore --
|
||||
-- --
|
||||
-- Redistribution and use in source and binary forms, with or without --
|
||||
-- modification, are permitted provided that the following conditions are --
|
||||
-- met: --
|
||||
-- 1. Redistributions of source code must retain the above copyright --
|
||||
-- notice, this list of conditions and the following disclaimer. --
|
||||
-- 2. Redistributions in binary form must reproduce the above copyright --
|
||||
-- notice, this list of conditions and the following disclaimer in --
|
||||
-- the documentation and/or other materials provided with the --
|
||||
-- distribution. --
|
||||
-- 3. Neither the name of the copyright holder nor the names of its --
|
||||
-- contributors may be used to endorse or promote products derived --
|
||||
-- from this software without specific prior written permission. --
|
||||
-- --
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS --
|
||||
-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT --
|
||||
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR --
|
||||
-- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT --
|
||||
-- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, --
|
||||
-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT --
|
||||
-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, --
|
||||
-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY --
|
||||
-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT --
|
||||
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE --
|
||||
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --
|
||||
-- --
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
with System;
|
||||
|
||||
package body SDMMC_Init is
|
||||
|
||||
procedure Convert_Card_Identification_Data_Register
|
||||
(W0, W1, W2, W3 : UInt32;
|
||||
Res : out Card_Identification_Data_Register);
|
||||
-- Convert the R2 reply to CID
|
||||
|
||||
procedure Convert_Card_Specific_Data_Register
|
||||
(W0, W1, W2, W3 : UInt32;
|
||||
Card_Type : Supported_SD_Memory_Cards;
|
||||
CSD : out Card_Specific_Data_Register);
|
||||
-- Convert the R2 reply to CSD
|
||||
|
||||
procedure Convert_SDCard_Configuration_Register
|
||||
(W0, W1 : UInt32;
|
||||
SCR : out SDCard_Configuration_Register);
|
||||
-- Convert W0 (MSB) / W1 (LSB) to SCR.
|
||||
|
||||
function Compute_Card_Capacity
|
||||
(CSD : Card_Specific_Data_Register;
|
||||
Card_Type : Supported_SD_Memory_Cards) return UInt64;
|
||||
-- Compute the card capacity (in bytes) from the CSD
|
||||
|
||||
function Compute_Card_Block_Size
|
||||
(CSD : Card_Specific_Data_Register;
|
||||
Card_Type : Supported_SD_Memory_Cards) return UInt32;
|
||||
-- Compute the card block size (in bytes) from the CSD.
|
||||
|
||||
function Get_Transfer_Rate
|
||||
(CSD : Card_Specific_Data_Register) return Natural;
|
||||
-- Compute transfer rate from CSD
|
||||
|
||||
function Swap32 (Val : UInt32) return UInt32 with Inline_Always;
|
||||
|
||||
function BE32_To_Host (Val : UInt32) return UInt32 with Inline_Always;
|
||||
|
||||
-- Swap bytes in a word
|
||||
------------
|
||||
-- Swap32 --
|
||||
------------
|
||||
|
||||
function Swap32 (Val : UInt32) return UInt32 is
|
||||
begin
|
||||
return Shift_Left (Val and 16#00_00_00_ff#, 24)
|
||||
or Shift_Left (Val and 16#00_00_ff_00#, 8)
|
||||
or Shift_Right (Val and 16#00_ff_00_00#, 8)
|
||||
or Shift_Right (Val and 16#ff_00_00_00#, 24);
|
||||
end Swap32;
|
||||
|
||||
------------------
|
||||
-- BE32_To_Host --
|
||||
------------------
|
||||
|
||||
function BE32_To_Host (Val : UInt32) return UInt32 is
|
||||
use System;
|
||||
begin
|
||||
if Default_Bit_Order = Low_Order_First then
|
||||
return Swap32 (Val);
|
||||
else
|
||||
return Val;
|
||||
end if;
|
||||
end BE32_To_Host;
|
||||
|
||||
---------------------------------
|
||||
-- Card_Identification_Process --
|
||||
---------------------------------
|
||||
|
||||
procedure Card_Identification_Process
|
||||
(This : in out SDMMC_Driver'Class;
|
||||
Info : out Card_Information;
|
||||
Status : out SD_Error)
|
||||
is
|
||||
Rsp : UInt32;
|
||||
W0, W1, W2, W3 : UInt32;
|
||||
Rca : UInt32;
|
||||
|
||||
begin
|
||||
-- Reset controller
|
||||
This.Reset (Status);
|
||||
|
||||
if Status /= OK then
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- CMD0: Sets the SDCard state to Idle
|
||||
Send_Cmd (This, Go_Idle_State, 0, Status);
|
||||
|
||||
if Status /= OK then
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- CMD8: IF_Cond, voltage supplied: 0x1 (2.7V - 3.6V)
|
||||
-- It is mandatory for the host compliant to Physical Spec v2.00
|
||||
-- to send CMD8 before ACMD41
|
||||
Send_Cmd (This, Send_If_Cond, 16#1a5#, Status);
|
||||
|
||||
if Status = OK then
|
||||
-- at least SD Card 2.0
|
||||
Info.Card_Type := STD_Capacity_SD_Card_v2_0;
|
||||
|
||||
Read_Rsp48 (This, Rsp);
|
||||
|
||||
if (Rsp and 16#fff#) /= 16#1a5# then
|
||||
-- Bad voltage or bad pattern.
|
||||
Status := Error;
|
||||
return;
|
||||
end if;
|
||||
else
|
||||
-- If SD Card, then it's v1.1
|
||||
Info.Card_Type := STD_Capacity_SD_Card_V1_1;
|
||||
end if;
|
||||
|
||||
for I in 1 .. 5 loop
|
||||
This.Delay_Milliseconds (200);
|
||||
|
||||
-- CMD55: APP_CMD
|
||||
-- This is done manually to handle error (this command is not
|
||||
-- supported by mmc).
|
||||
Send_Cmd (This, Cmd_Desc (App_Cmd), 0, Status);
|
||||
|
||||
if Status /= OK then
|
||||
if Status = Command_Timeout_Error
|
||||
and then I = 1
|
||||
and then Info.Card_Type = STD_Capacity_SD_Card_V1_1
|
||||
then
|
||||
-- Not an SDCard. Suppose MMC.
|
||||
Info.Card_Type := Multimedia_Card;
|
||||
exit;
|
||||
end if;
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- ACMD41: SD_SEND_OP_COND (no crc check)
|
||||
-- Arg: HCS=1, XPC=0, S18R=0
|
||||
Send_Cmd
|
||||
(This, Acmd_Desc (SD_App_Send_Op_Cond), 16#40ff_0000#, Status);
|
||||
if Status /= OK then
|
||||
return;
|
||||
end if;
|
||||
|
||||
Read_Rsp48 (This, Rsp);
|
||||
|
||||
if (Rsp and SD_OCR_High_Capacity) = SD_OCR_High_Capacity then
|
||||
Info.Card_Type := High_Capacity_SD_Card;
|
||||
end if;
|
||||
|
||||
if (Rsp and SD_OCR_Power_Up) = 0 then
|
||||
Status := Error;
|
||||
|
||||
else
|
||||
Status := OK;
|
||||
exit;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
if Status = Command_Timeout_Error
|
||||
and then Info.Card_Type = Multimedia_Card
|
||||
then
|
||||
for I in 1 .. 5 loop
|
||||
This.Delay_Milliseconds (200);
|
||||
|
||||
-- CMD1: SEND_OP_COND query voltage
|
||||
Send_Cmd (This, Cmd_Desc (Send_Op_Cond), 16#00ff_8000#, Status);
|
||||
if Status /= OK then
|
||||
return;
|
||||
end if;
|
||||
|
||||
Read_Rsp48 (This, Rsp);
|
||||
|
||||
if (Rsp and SD_OCR_Power_Up) = 0 then
|
||||
Status := Error;
|
||||
else
|
||||
if (Rsp and 16#00ff_8000#) /= 16#00ff_8000# then
|
||||
Status := Error;
|
||||
return;
|
||||
end if;
|
||||
Status := OK;
|
||||
exit;
|
||||
end if;
|
||||
end loop;
|
||||
end if;
|
||||
|
||||
if Status /= OK then
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- TODO: Switch voltage
|
||||
|
||||
-- CMD2: ALL_SEND_CID (136 bits)
|
||||
Send_Cmd (This, All_Send_CID, 0, Status);
|
||||
if Status /= OK then
|
||||
return;
|
||||
end if;
|
||||
|
||||
Read_Rsp136 (This, W0, W1, W2, W3);
|
||||
Convert_Card_Identification_Data_Register (W0, W1, W2, W3, Info.SD_CID);
|
||||
|
||||
-- CMD3: SEND_RELATIVE_ADDR
|
||||
case Info.Card_Type is
|
||||
when Multimedia_Card =>
|
||||
Rca := 16#01_0000#;
|
||||
when others =>
|
||||
Rca := 0;
|
||||
end case;
|
||||
|
||||
Send_Cmd (This, Send_Relative_Addr, Rca, Status);
|
||||
if Status /= OK then
|
||||
return;
|
||||
end if;
|
||||
case Info.Card_Type is
|
||||
when Multimedia_Card =>
|
||||
null;
|
||||
when others =>
|
||||
Read_Rsp48 (This, Rsp);
|
||||
Rca := Rsp and 16#ffff_0000#;
|
||||
if (Rsp and 16#e100#) /= 16#0100# then
|
||||
return;
|
||||
end if;
|
||||
end case;
|
||||
Info.RCA := UInt16 (Shift_Right (Rca, 16));
|
||||
|
||||
-- Switch to 25Mhz
|
||||
case Info.Card_Type is
|
||||
when Multimedia_Card =>
|
||||
Set_Clock (This, Get_Transfer_Rate (Info.SD_CSD));
|
||||
when STD_Capacity_SD_Card_V1_1
|
||||
| STD_Capacity_SD_Card_v2_0
|
||||
| High_Capacity_SD_Card =>
|
||||
Set_Clock (This, 25_000_000);
|
||||
when others =>
|
||||
-- Not yet handled
|
||||
raise Program_Error;
|
||||
end case;
|
||||
|
||||
-- CMD10: SEND_CID (136 bits)
|
||||
Send_Cmd (This, Send_CID, Rca, Status);
|
||||
if Status /= OK then
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- CMD9: SEND_CSD
|
||||
Send_Cmd (This, Send_CSD, Rca, Status);
|
||||
if Status /= OK then
|
||||
return;
|
||||
end if;
|
||||
Read_Rsp136 (This, W0, W1, W2, W3);
|
||||
Convert_Card_Specific_Data_Register
|
||||
(W0, W1, W2, W3, Info.Card_Type, Info.SD_CSD);
|
||||
Info.Card_Capacity :=
|
||||
Compute_Card_Capacity (Info.SD_CSD, Info.Card_Type);
|
||||
Info.Card_Block_Size :=
|
||||
Compute_Card_Block_Size (Info.SD_CSD, Info.Card_Type);
|
||||
|
||||
-- CMD7: SELECT
|
||||
Send_Cmd (This, Select_Card, Rca, Status);
|
||||
if Status /= OK then
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- CMD13: STATUS
|
||||
Send_Cmd (This, Send_Status, Rca, Status);
|
||||
if Status /= OK then
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- Bus size
|
||||
case Info.Card_Type is
|
||||
when STD_Capacity_SD_Card_V1_1
|
||||
| STD_Capacity_SD_Card_v2_0
|
||||
| High_Capacity_SD_Card =>
|
||||
Send_ACmd (This, SD_App_Set_Bus_Width, Info.RCA, 2, Status);
|
||||
if Status /= OK then
|
||||
return;
|
||||
else
|
||||
Set_Bus_Size (This, Wide_Bus_4B);
|
||||
end if;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
|
||||
if (Info.SD_CSD.Card_Command_Class and 2**10) /= 0 then
|
||||
-- Class 10 supported.
|
||||
declare
|
||||
subtype Switch_Status_Type is UInt32_Array (1 .. 16);
|
||||
|
||||
Switch_Status : Switch_Status_Type;
|
||||
begin
|
||||
-- CMD6
|
||||
Read_Cmd (This, Cmd_Desc (Switch_Func), 16#00_fffff0#,
|
||||
Switch_Status, Status);
|
||||
if Status /= OK then
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- Handle endianness
|
||||
for I in Switch_Status'Range loop
|
||||
Switch_Status (I) := BE32_To_Host (Switch_Status (I));
|
||||
end loop;
|
||||
|
||||
-- Switch tp 50Mhz if possible.
|
||||
if (Switch_Status (4) and 2**(16 + 1)) /= 0 then
|
||||
Read_Cmd (This, Cmd_Desc (Switch_Func), 16#80_fffff1#,
|
||||
Switch_Status, Status);
|
||||
if Status /= OK then
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- Switch to 50Mhz
|
||||
Set_Clock (This, 50_000_000);
|
||||
end if;
|
||||
end;
|
||||
end if;
|
||||
end Card_Identification_Process;
|
||||
|
||||
--------------
|
||||
-- Read_SCR --
|
||||
--------------
|
||||
|
||||
procedure Read_SCR
|
||||
(This : in out SDMMC_Driver'Class;
|
||||
Info : Card_Information;
|
||||
SCR : out SDCard_Configuration_Register;
|
||||
Status : out SD_Error)
|
||||
is
|
||||
subtype SD_SCR is UInt32_Array (1 .. 2);
|
||||
Tmp : SD_SCR;
|
||||
Rca : UInt32;
|
||||
|
||||
begin
|
||||
Rca := Shift_Left (UInt32 (Info.RCA), 16);
|
||||
|
||||
Send_Cmd (This, App_Cmd, Rca, Status);
|
||||
if Status /= OK then
|
||||
return;
|
||||
end if;
|
||||
|
||||
Read_Cmd
|
||||
(This,
|
||||
Cmd => Acmd_Desc (SD_App_Send_SCR),
|
||||
Arg => 0,
|
||||
Buf => Tmp,
|
||||
Status => Status);
|
||||
|
||||
if Status /= OK then
|
||||
return;
|
||||
end if;
|
||||
|
||||
Convert_SDCard_Configuration_Register
|
||||
(BE32_To_Host (Tmp (1)), BE32_To_Host (Tmp (2)), SCR);
|
||||
end Read_SCR;
|
||||
|
||||
-----------------------------------------------
|
||||
-- Convert_Card_Identification_Data_Register --
|
||||
-----------------------------------------------
|
||||
|
||||
procedure Convert_Card_Identification_Data_Register
|
||||
(W0, W1, W2, W3 : UInt32;
|
||||
Res : out Card_Identification_Data_Register)
|
||||
is
|
||||
Tmp : UInt8;
|
||||
begin
|
||||
-- Byte 0
|
||||
Tmp := UInt8 (Shift_Right (W0 and 16#FF00_0000#, 24));
|
||||
Res.Manufacturer_ID := Tmp;
|
||||
|
||||
-- Byte 1 & 2
|
||||
Tmp := UInt8 (Shift_Right (W0 and 16#00FF_0000#, 16));
|
||||
Res.OEM_Application_ID (1) := Character'Val (Tmp);
|
||||
Tmp := UInt8 (Shift_Right (W0 and 16#0000_FF00#, 8));
|
||||
Res.OEM_Application_ID (2) := Character'Val (Tmp);
|
||||
|
||||
-- Byte 3-7
|
||||
Tmp := UInt8 (W0 and 16#0000_00FF#);
|
||||
Res.Product_Name (1) := Character'Val (Tmp);
|
||||
Tmp := UInt8 (Shift_Right (W1 and 16#FF00_0000#, 24));
|
||||
Res.Product_Name (2) := Character'Val (Tmp);
|
||||
Tmp := UInt8 (Shift_Right (W1 and 16#00FF_0000#, 16));
|
||||
Res.Product_Name (3) := Character'Val (Tmp);
|
||||
Tmp := UInt8 (Shift_Right (W1 and 16#0000_FF00#, 8));
|
||||
Res.Product_Name (4) := Character'Val (Tmp);
|
||||
Tmp := UInt8 (W1 and 16#0000_00FF#);
|
||||
Res.Product_Name (5) := Character'Val (Tmp);
|
||||
|
||||
-- Byte 8
|
||||
Tmp := UInt8 (Shift_Right (W2 and 16#FF00_0000#, 24));
|
||||
Res.Product_Revision.Major := UInt4 (Shift_Right (Tmp, 4));
|
||||
Res.Product_Revision.Minor := UInt4 (Tmp and 16#0F#);
|
||||
|
||||
-- Byte 9 - 12
|
||||
Res.Product_Serial_Number :=
|
||||
Shift_Left (W2 and 16#00FF_FFFF#, 8) or
|
||||
Shift_Right (W3 and 16#FF00_0000#, 24);
|
||||
|
||||
-- Byte 13 - 14
|
||||
Res.Manufacturing_Date.Month :=
|
||||
Manufacturing_Month'Val (Shift_Right (W3 and 16#0000_0F00#, 8) - 1);
|
||||
Res.Manufacturing_Date.Year :=
|
||||
Manufacturing_Year (2000 + Shift_Right (W3 and 16#000F_F000#, 12));
|
||||
|
||||
-- Byte 15
|
||||
Tmp := UInt8 (W3 and 16#0000_00FF#);
|
||||
Res.CID_CRC := Shift_Right (Tmp and 16#FE#, 1);
|
||||
end Convert_Card_Identification_Data_Register;
|
||||
|
||||
-----------------------------------------
|
||||
-- Convert_Card_Specific_Data_Register --
|
||||
-----------------------------------------
|
||||
|
||||
procedure Convert_Card_Specific_Data_Register
|
||||
(W0, W1, W2, W3 : UInt32;
|
||||
Card_Type : Supported_SD_Memory_Cards;
|
||||
CSD : out Card_Specific_Data_Register)
|
||||
is
|
||||
Tmp : UInt8;
|
||||
begin
|
||||
-- Analysis of CSD Byte 0
|
||||
Tmp := UInt8 (Shift_Right (W0 and 16#FF00_0000#, 24));
|
||||
CSD.CSD_Structure := Shift_Right (Tmp and 16#C0#, 6);
|
||||
CSD.System_Specification_Version := Shift_Right (Tmp and 16#3C#, 2);
|
||||
CSD.Reserved := Tmp and 16#03#;
|
||||
|
||||
-- Byte 1
|
||||
Tmp := UInt8 (Shift_Right (W0 and 16#00FF_0000#, 16));
|
||||
CSD.Data_Read_Access_Time_1 := Tmp;
|
||||
|
||||
-- Byte 2
|
||||
Tmp := UInt8 (Shift_Right (W0 and 16#0000_FF00#, 8));
|
||||
CSD.Data_Read_Access_Time_2 := Tmp;
|
||||
|
||||
-- Byte 3
|
||||
Tmp := UInt8 (W0 and 16#0000_00FF#);
|
||||
CSD.Max_Data_Transfer_Rate := Tmp;
|
||||
|
||||
-- Byte 4 & 5
|
||||
CSD.Card_Command_Class :=
|
||||
UInt16 (Shift_Right (W1 and 16#FFF0_0000#, 20));
|
||||
CSD.Max_Read_Data_Block_Length :=
|
||||
UInt8 (Shift_Right (W1 and 16#000F_0000#, 16));
|
||||
|
||||
-- Byte 6
|
||||
Tmp := UInt8 (Shift_Right (W1 and 16#0000_FF00#, 8));
|
||||
CSD.Partial_Block_For_Read_Allowed := (Tmp and 16#80#) /= 0;
|
||||
CSD.Write_Block_Missalignment := (Tmp and 16#40#) /= 0;
|
||||
CSD.Read_Block_Missalignment := (Tmp and 16#20#) /= 0;
|
||||
CSD.DSR_Implemented := (Tmp and 16#10#) /= 0;
|
||||
CSD.Reserved_2 := 0;
|
||||
|
||||
if Card_Type = Multimedia_Card
|
||||
or else CSD.CSD_Structure = 0
|
||||
then
|
||||
CSD.Device_Size := Shift_Left (UInt32 (Tmp) and 16#03#, 10);
|
||||
|
||||
-- Byte 7
|
||||
Tmp := UInt8 (W1 and 16#0000_00FF#);
|
||||
CSD.Device_Size := CSD.Device_Size or Shift_Left (UInt32 (Tmp), 2);
|
||||
|
||||
-- Byte 8
|
||||
Tmp := UInt8 (Shift_Right (W2 and 16#FF00_0000#, 24));
|
||||
CSD.Device_Size := CSD.Device_Size or
|
||||
Shift_Right (UInt32 (Tmp and 16#C0#), 6);
|
||||
CSD.Max_Read_Current_At_VDD_Min := Shift_Right (Tmp and 16#38#, 3);
|
||||
CSD.Max_Read_Current_At_VDD_Max := Tmp and 16#07#;
|
||||
|
||||
-- Byte 9
|
||||
Tmp := UInt8 (Shift_Right (W2 and 16#00FF_0000#, 16));
|
||||
CSD.Max_Write_Current_At_VDD_Min := Shift_Right (Tmp and 16#E0#, 5);
|
||||
CSD.Max_Write_Current_At_VDD_Max := Shift_Right (Tmp and 16#1C#, 2);
|
||||
CSD.Device_Size_Multiplier := Shift_Left (Tmp and 16#03#, 1);
|
||||
|
||||
-- Byte 10
|
||||
Tmp := UInt8 (Shift_Right (W2 and 16#0000_FF00#, 8));
|
||||
CSD.Device_Size_Multiplier :=
|
||||
CSD.Device_Size_Multiplier or Shift_Right (Tmp and 16#80#, 7);
|
||||
elsif CSD.CSD_Structure = 1 then
|
||||
-- Byte 7
|
||||
Tmp := UInt8 (W1 and 16#0000_00FF#);
|
||||
CSD.Device_Size := Shift_Left (UInt32 (Tmp), 16);
|
||||
|
||||
-- Byte 8 & 9
|
||||
CSD.Device_Size := CSD.Device_Size or
|
||||
(Shift_Right (W2 and 16#FFFF_0000#, 16));
|
||||
|
||||
-- Byte 10
|
||||
Tmp := UInt8 (Shift_Right (W2 and 16#0000_FF00#, 8));
|
||||
else
|
||||
-- Unsupported
|
||||
null;
|
||||
-- return Unsupported_Card;
|
||||
end if;
|
||||
|
||||
CSD.Erase_Group_Size := Shift_Right (Tmp and 16#40#, 6);
|
||||
CSD.Erase_Group_Size_Multiplier := Shift_Left (Tmp and 16#3F#, 1);
|
||||
|
||||
-- Byte 11
|
||||
Tmp := UInt8 (W2 and 16#0000_00FF#);
|
||||
CSD.Erase_Group_Size_Multiplier :=
|
||||
CSD.Erase_Group_Size_Multiplier or Shift_Right (Tmp and 16#80#, 7);
|
||||
CSD.Write_Protect_Group_Size := Tmp and 16#7F#;
|
||||
|
||||
-- Byte 12
|
||||
Tmp := UInt8 (Shift_Right (W3 and 16#FF00_0000#, 24));
|
||||
CSD.Write_Protect_Group_Enable := (Tmp and 16#80#) /= 0;
|
||||
CSD.Manufacturer_Default_ECC := Shift_Right (Tmp and 16#60#, 5);
|
||||
CSD.Write_Speed_Factor := Shift_Right (Tmp and 16#1C#, 2);
|
||||
CSD.Max_Write_Data_Block_Length := Shift_Left (Tmp and 16#03#, 2);
|
||||
|
||||
-- Byte 13
|
||||
Tmp := UInt8 (Shift_Right (W3 and 16#00FF_0000#, 16));
|
||||
CSD.Max_Write_Data_Block_Length :=
|
||||
CSD.Max_Read_Data_Block_Length or Shift_Right (Tmp and 16#C0#, 6);
|
||||
CSD.Partial_Blocks_For_Write_Allowed := (Tmp and 16#20#) /= 0;
|
||||
CSD.Reserved_3 := 0;
|
||||
CSD.Content_Protection_Application := (Tmp and 16#01#) /= 0;
|
||||
|
||||
-- Byte 14
|
||||
Tmp := UInt8 (Shift_Right (W3 and 16#0000_FF00#, 8));
|
||||
CSD.File_Format_Group := (Tmp and 16#80#) /= 0;
|
||||
CSD.Copy_Flag := (Tmp and 16#40#) /= 0;
|
||||
CSD.Permanent_Write_Protection := (Tmp and 16#20#) /= 0;
|
||||
CSD.Temporary_Write_Protection := (Tmp and 16#10#) /= 0;
|
||||
CSD.File_Format := Shift_Right (Tmp and 16#0C#, 2);
|
||||
CSD.ECC_Code := Tmp and 16#03#;
|
||||
|
||||
-- Byte 15
|
||||
Tmp := UInt8 (W3 and 16#0000_00FF#);
|
||||
CSD.CSD_CRC := Shift_Right (Tmp and 16#FE#, 1);
|
||||
CSD.Reserved_4 := 0;
|
||||
end Convert_Card_Specific_Data_Register;
|
||||
|
||||
---------------------------
|
||||
-- Compute_Card_Capacity --
|
||||
---------------------------
|
||||
|
||||
function Compute_Card_Capacity
|
||||
(CSD : Card_Specific_Data_Register;
|
||||
Card_Type : Supported_SD_Memory_Cards) return UInt64
|
||||
is
|
||||
begin
|
||||
if Card_Type = Multimedia_Card
|
||||
or else CSD.CSD_Structure = 0
|
||||
then
|
||||
return UInt64 (CSD.Device_Size + 1) *
|
||||
2 ** Natural (CSD.Device_Size_Multiplier + 2) *
|
||||
2 ** Natural (CSD.Max_Read_Data_Block_Length);
|
||||
elsif CSD.CSD_Structure = 1 then
|
||||
return UInt64 (CSD.Device_Size + 1) * 512 * 1024;
|
||||
else
|
||||
return 0;
|
||||
end if;
|
||||
end Compute_Card_Capacity;
|
||||
|
||||
-----------------------------
|
||||
-- Compute_Card_Block_Size --
|
||||
-----------------------------
|
||||
|
||||
function Compute_Card_Block_Size
|
||||
(CSD : Card_Specific_Data_Register;
|
||||
Card_Type : Supported_SD_Memory_Cards) return UInt32
|
||||
is
|
||||
begin
|
||||
if Card_Type = Multimedia_Card
|
||||
or else CSD.CSD_Structure = 0
|
||||
then
|
||||
return 2 ** Natural (CSD.Max_Read_Data_Block_Length);
|
||||
elsif CSD.CSD_Structure = 1 then
|
||||
return 512;
|
||||
else
|
||||
return 0;
|
||||
end if;
|
||||
end Compute_Card_Block_Size;
|
||||
|
||||
-------------------------------------------
|
||||
-- Convert_SDCard_Configuration_Register --
|
||||
-------------------------------------------
|
||||
|
||||
procedure Convert_SDCard_Configuration_Register
|
||||
(W0, W1 : UInt32;
|
||||
SCR : out SDCard_Configuration_Register)
|
||||
is
|
||||
begin
|
||||
SCR := (SCR_Structure => UInt8 (Shift_Right (W0, 28) and 16#f#),
|
||||
SD_Spec => UInt8 (Shift_Right (W0, 24) and 16#f#),
|
||||
Data_Stat_After_Erase => UInt8 (Shift_Right (W0, 23) and 1),
|
||||
SD_Security => UInt8 (Shift_Right (W0, 20) and 7),
|
||||
SD_Bus_Widths => UInt8 (Shift_Right (W0, 16) and 16#f#),
|
||||
SD_Spec3 => (Shift_Right (W0, 15) and 1) /= 0,
|
||||
Ex_Security => UInt8 (Shift_Right (W0, 11) and 16#f#),
|
||||
SD_Spec4 => (Shift_Right (W0, 10) and 1) /= 0,
|
||||
Reserved_1 => UInt8 (Shift_Right (W0, 4) and 16#3f#),
|
||||
CMD_Support => UInt8 (Shift_Right (W0, 0) and 16#f#),
|
||||
Reserved_2 => W1);
|
||||
end Convert_SDCard_Configuration_Register;
|
||||
|
||||
-----------------------
|
||||
-- Get_Transfer_Rate --
|
||||
-----------------------
|
||||
|
||||
function Get_Transfer_Rate
|
||||
(CSD : Card_Specific_Data_Register) return Natural
|
||||
is
|
||||
Res : Natural;
|
||||
begin
|
||||
case Shift_Right (CSD.Max_Data_Transfer_Rate, 3) and 15 is
|
||||
when 16#1# => Res := 10;
|
||||
when 16#2# => Res := 12;
|
||||
when 16#3# => Res := 13;
|
||||
when 16#4# => Res := 15;
|
||||
when 16#5# => Res := 20;
|
||||
when 16#6# => Res := 25;
|
||||
when 16#7# => Res := 30;
|
||||
when 16#8# => Res := 35;
|
||||
when 16#9# => Res := 40;
|
||||
when 16#a# => Res := 45;
|
||||
when 16#b# => Res := 50;
|
||||
when 16#c# => Res := 55;
|
||||
when 16#d# => Res := 60;
|
||||
when 16#e# => Res := 70;
|
||||
when 16#f# => Res := 80;
|
||||
when others => return 400_000;
|
||||
end case;
|
||||
|
||||
case CSD.Max_Data_Transfer_Rate and 7 is
|
||||
when 0 => return Res * 100_000 / 10;
|
||||
when 1 => return Res * 1_000_000 / 10;
|
||||
when 2 => return Res * 10_000_000 / 10;
|
||||
when 3 => return Res * 100_000_000 / 10;
|
||||
when others => return 400_000;
|
||||
end case;
|
||||
end Get_Transfer_Rate;
|
||||
|
||||
end SDMMC_Init;
|
|
@ -0,0 +1,55 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- --
|
||||
-- Copyright (C) 2015-2017, AdaCore --
|
||||
-- --
|
||||
-- Redistribution and use in source and binary forms, with or without --
|
||||
-- modification, are permitted provided that the following conditions are --
|
||||
-- met: --
|
||||
-- 1. Redistributions of source code must retain the above copyright --
|
||||
-- notice, this list of conditions and the following disclaimer. --
|
||||
-- 2. Redistributions in binary form must reproduce the above copyright --
|
||||
-- notice, this list of conditions and the following disclaimer in --
|
||||
-- the documentation and/or other materials provided with the --
|
||||
-- distribution. --
|
||||
-- 3. Neither the name of the copyright holder nor the names of its --
|
||||
-- contributors may be used to endorse or promote products derived --
|
||||
-- from this software without specific prior written permission. --
|
||||
-- --
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS --
|
||||
-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT --
|
||||
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR --
|
||||
-- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT --
|
||||
-- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, --
|
||||
-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT --
|
||||
-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, --
|
||||
-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY --
|
||||
-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT --
|
||||
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE --
|
||||
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --
|
||||
-- --
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
with HAL.SDMMC; use HAL, HAL.SDMMC;
|
||||
|
||||
-- This package implements the SD and MMC card identification protocol.
|
||||
package SDMMC_Init is
|
||||
|
||||
procedure Card_Identification_Process (This : in out SDMMC_Driver'Class;
|
||||
Info : out Card_Information;
|
||||
Status : out SD_Error);
|
||||
-- Generic card identification process procedure.
|
||||
|
||||
procedure Read_SCR (This : in out SDMMC_Driver'Class;
|
||||
Info : Card_Information;
|
||||
SCR : out SDCard_Configuration_Register;
|
||||
Status : out SD_Error);
|
||||
-- Retrieve the current SDCard configuration
|
||||
|
||||
-- OCR bits
|
||||
SD_OCR_Power_Up : constant := 16#8000_0000#;
|
||||
SD_OCR_High_Capacity : constant := 16#4000_0000#;
|
||||
SD_OCR_Std_Capacity : constant := 16#0000_0000#;
|
||||
|
||||
SD_MAX_VOLT_TRIAL : constant := 16#0000_FFFF#;
|
||||
|
||||
end SDMMC_Init;
|
|
@ -88,7 +88,7 @@ package body Partitions is
|
|||
P_Entry : Partition_Entry;
|
||||
begin
|
||||
loop
|
||||
if not Disk.Read (Address, EBR) or else EBR (510 .. 511) /= (16#55#, 16#AA#) then
|
||||
if not Disk.Read (UInt64 (Address), EBR) or else EBR (510 .. 511) /= (16#55#, 16#AA#) then
|
||||
return Entry_Cnt;
|
||||
end if;
|
||||
|
||||
|
@ -122,7 +122,7 @@ package body Partitions is
|
|||
Address : Logical_Block_Address := EBR_Address;
|
||||
begin
|
||||
loop
|
||||
if not Disk.Read (Address, EBR) or else EBR (510 .. 511) /= (16#55#, 16#AA#) then
|
||||
if not Disk.Read (UInt64 (Address), EBR) or else EBR (510 .. 511) /= (16#55#, 16#AA#) then
|
||||
return Invalid_Parition;
|
||||
end if;
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ package body File_Block_Drivers is
|
|||
overriding
|
||||
function Read
|
||||
(This : in out File_Block_Driver;
|
||||
Block_Number : UInt32;
|
||||
Block_Number : UInt64;
|
||||
Data : out Block)
|
||||
return Boolean
|
||||
is
|
||||
|
@ -58,7 +58,7 @@ package body File_Block_Drivers is
|
|||
overriding
|
||||
function Write
|
||||
(This : in out File_Block_Driver;
|
||||
Block_Number : UInt32;
|
||||
Block_Number : UInt64;
|
||||
Data : Block)
|
||||
return Boolean
|
||||
is
|
||||
|
|
|
@ -42,14 +42,14 @@ package File_Block_Drivers is
|
|||
overriding
|
||||
function Read
|
||||
(This : in out File_Block_Driver;
|
||||
Block_Number : UInt32;
|
||||
Block_Number : UInt64;
|
||||
Data : out Block)
|
||||
return Boolean;
|
||||
|
||||
overriding
|
||||
function Write
|
||||
(This : in out File_Block_Driver;
|
||||
Block_Number : UInt32;
|
||||
Block_Number : UInt64;
|
||||
Data : Block)
|
||||
return Boolean;
|
||||
|
||||
|
|
Loading…
Reference in New Issue