Line 8... |
Line 8... |
|
|
architecture Rtl of SdController is
|
architecture Rtl of SdController is
|
|
|
type aSdControllerState is (startup, init, config, idle, invalidCard);
|
type aSdControllerState is (startup, init, config, idle, invalidCard);
|
type aCmdRegion is (CMD0, CMD8, CMD55, ACMD41, CMD2, CMD3, SelectCard);
|
type aCmdRegion is (CMD0, CMD8, CMD55, ACMD41, CMD2, CMD3, SelectCard);
|
type aRegion is (send, receive, waitstate);
|
type aRegion is (idle, send, receive, waitstate);
|
|
|
constant cDefaultToSdCmd : aSdCmdFromController := (
|
constant cDefaultToSdCmd : aSdCmdFromController := (
|
(id => (others => '0'),
|
(id => (others => '0'),
|
arg => (others => '0')),
|
arg => (others => '0')),
|
Valid => cInactivated,
|
Valid => cInactivated,
|
Line 32... |
Line 32... |
end record aSdControllerReg;
|
end record aSdControllerReg;
|
|
|
constant cDefaultSdControllerReg : aSdControllerReg := (
|
constant cDefaultSdControllerReg : aSdControllerReg := (
|
State => startup,
|
State => startup,
|
CmdRegion => CMD0,
|
CmdRegion => CMD0,
|
Region => send,
|
Region => idle,
|
HCS => cActivated,
|
HCS => cActivated,
|
CCS => cInactivated,
|
CCS => cInactivated,
|
RCA => cDefaultRCA,
|
RCA => cDefaultRCA,
|
CardStatus => cDefaultSdCardStatus,
|
CardStatus => cDefaultSdCardStatus,
|
ToSdCmd => cDefaultToSdCmd,
|
ToSdCmd => cDefaultToSdCmd,
|
Line 65... |
Line 65... |
end process Regs;
|
end process Regs;
|
|
|
Comb : process (iSdCmd, Timeout, NextCmdTimeout, R)
|
Comb : process (iSdCmd, Timeout, NextCmdTimeout, R)
|
variable ocr : aSdRegOCR;
|
variable ocr : aSdRegOCR;
|
variable arg : aSdCmdArg;
|
variable arg : aSdCmdArg;
|
|
variable NextRegion : aRegion;
|
|
variable NextCmdRegion : aCmdRegion;
|
|
variable NextState : aSdControllerState;
|
begin
|
begin
|
-- default assignments
|
-- default assignments
|
NextR <= R;
|
NextR <= R;
|
NextR.ToSdCmd <= cDefaultToSdCmd;
|
NextR.ToSdCmd <= cDefaultToSdCmd;
|
TimeoutEnable <= cInactivated;
|
TimeoutEnable <= cInactivated;
|
NextCmdTimeoutEnable <= cInactivated;
|
NextCmdTimeoutEnable <= cInactivated;
|
|
|
|
-- variables
|
|
NextRegion := R.Region;
|
|
NextCmdRegion := R.CmdRegion;
|
|
NextState := R.State;
|
|
|
-- Status
|
-- Status
|
oLedBank <= (others => cInactivated);
|
oLedBank <= (others => cInactivated);
|
|
|
case R.State is
|
case R.State is
|
when startup =>
|
when startup =>
|
TimeoutEnable <= cActivated;
|
TimeoutEnable <= cActivated;
|
|
|
if (Timeout = cActivated) then
|
if (Timeout = cActivated) then
|
TimeoutEnable <= cInactivated;
|
TimeoutEnable <= cInactivated;
|
NextR.State <= init;
|
NextR.State <= init;
|
|
NextR.Region <= send;
|
end if;
|
end if;
|
|
|
when init =>
|
when init =>
|
case R.CmdRegion is
|
case R.CmdRegion is
|
when CMD0 =>
|
when CMD0 =>
|
case R.Region is
|
case R.Region is
|
when send =>
|
when send =>
|
NextR.ToSdCmd.Content.id <= cSdCmdGoIdleState;
|
NextR.ToSdCmd.Content.id <= cSdCmdGoIdleState;
|
NextR.ToSdCmd.Valid <= cActivated;
|
|
|
|
if (iSdCmd.Ack = cActivated) then
|
|
NextR.ToSdCmd.Valid <= cInactivated;
|
|
NextR.Region <= waitstate;
|
|
NextR.CardStatus <= cDefaultSdCardStatus;
|
NextR.CardStatus <= cDefaultSdCardStatus;
|
end if;
|
NextRegion := waitstate;
|
|
|
when waitstate =>
|
when waitstate =>
|
NextCmdTimeoutEnable <= cActivated;
|
NextRegion := send;
|
|
NextCmdRegion := CMD8;
|
if (NextCmdTimeout = cActivated) then
|
|
NextCmdTimeoutEnable <= cInactivated;
|
|
NextR.Region <= send;
|
|
NextR.CmdRegion <= CMD8;
|
|
end if;
|
|
|
|
when others =>
|
when others =>
|
report "SdController: Unhandled state" severity error;
|
report "SdController: Unhandled state" severity error;
|
end case;
|
end case;
|
|
|
when CMD8 =>
|
when CMD8 =>
|
case R.Region is
|
case R.Region is
|
when send =>
|
when send =>
|
NextR.ToSdCmd.Content.id <= cSdCmdSendIfCond;
|
NextR.ToSdCmd.Content.id <= cSdCmdSendIfCond;
|
NextR.ToSdCmd.Content.arg <= cSdArgVoltage;
|
NextR.ToSdCmd.Content.arg <= cSdArgVoltage;
|
NextR.ToSdCmd.Valid <= cActivated;
|
NextRegion := receive;
|
|
|
if (iSdCmd.Ack = cActivated) then
|
|
NextR.ToSdCmd.Valid <= cInactivated;
|
|
NextR.Region <= receive;
|
|
end if;
|
|
|
|
when receive =>
|
when receive =>
|
oLedBank(0) <= cActivated;
|
|
TimeoutEnable <= cActivated;
|
|
|
|
if (iSdCmd.Valid = cActivated) then
|
if (iSdCmd.Valid = cActivated) then
|
if (iSdCmd.Content.id = cSdCmdSendIfCond and iSdCmd.Content.arg = cSdArgVoltage) then
|
if (iSdCmd.Content.id = cSdCmdSendIfCond and iSdCmd.Content.arg = cSdArgVoltage) then
|
NextR.Region <= waitstate;
|
NextR.Region <= waitstate;
|
NextR.HCS <= cActivated;
|
NextR.HCS <= cActivated;
|
|
|
Line 142... |
Line 133... |
NextR.CmdRegion <= CMD55;
|
NextR.CmdRegion <= CMD55;
|
NextR.Region <= send;
|
NextR.Region <= send;
|
end if;
|
end if;
|
|
|
when waitstate =>
|
when waitstate =>
|
NextCmdTimeoutEnable <= cActivated;
|
NextCmdRegion := CMD55;
|
|
NextRegion := send;
|
if (NextCmdTimeout = cActivated) then
|
|
NextCmdTimeoutEnable <= cInactivated;
|
|
NextR.CmdRegion <= CMD55;
|
|
NextR.Region <= send;
|
|
end if;
|
|
|
|
when others =>
|
when others =>
|
report "SdController: Unhandled state" severity error;
|
report "SdController: Unhandled state" severity error;
|
end case;
|
end case;
|
|
|
Line 161... |
Line 147... |
|
|
case R.Region is
|
case R.Region is
|
when send =>
|
when send =>
|
NextR.ToSdCmd.Content.id <= cSdNextIsACMD;
|
NextR.ToSdCmd.Content.id <= cSdNextIsACMD;
|
NextR.ToSdCmd.Content.arg <= cSdACMDArg;
|
NextR.ToSdCmd.Content.arg <= cSdACMDArg;
|
NextR.ToSdCmd.Valid <= cActivated;
|
NextRegion := receive;
|
|
|
if (iSdCmd.Ack = cActivated) then
|
|
NextR.ToSdCmd.Valid <= cInactivated;
|
|
NextR.Region <= receive;
|
|
end if;
|
|
|
|
when receive =>
|
when receive =>
|
oLedBank(0) <= cActivated;
|
|
TimeoutEnable <= cActivated;
|
|
|
|
if (iSdCmd.Valid = cActivated) then
|
if (iSdCmd.Valid = cActivated) then
|
if (iSdCmd.Content.id = cSdNextIsACMD) then
|
if (iSdCmd.Content.id = cSdNextIsACMD) then
|
NextR.CardStatus <= iSdCmd.Content.arg;
|
NextR.CardStatus <= iSdCmd.Content.arg;
|
NextR.CmdRegion <= CMD55;
|
NextR.CmdRegion <= CMD55;
|
|
|
Line 190... |
Line 168... |
elsif (Timeout = cActivated) then
|
elsif (Timeout = cActivated) then
|
NextR.State <= invalidCard;
|
NextR.State <= invalidCard;
|
end if;
|
end if;
|
|
|
when waitstate =>
|
when waitstate =>
|
NextCmdTimeoutEnable <= cActivated;
|
NextCmdRegion := ACMD41;
|
|
NextRegion := send;
|
if (NextCmdTimeout = cActivated) then
|
|
NextR.CmdRegion <= ACMD41;
|
|
NextR.Region <= send;
|
|
end if;
|
|
|
|
when others =>
|
when others =>
|
report "SdController: Unhandled state" severity error;
|
report "SdController: Unhandled state" severity error;
|
end case;
|
end case;
|
|
|
Line 212... |
Line 186... |
ocr.ccs := R.HCS;
|
ocr.ccs := R.HCS;
|
ocr.voltagewindow := cVoltageWindow;
|
ocr.voltagewindow := cVoltageWindow;
|
|
|
NextR.ToSdCmd.Content.id <= cSdCmdACMD41;
|
NextR.ToSdCmd.Content.id <= cSdCmdACMD41;
|
NextR.ToSdCmd.Content.arg <= OCRToArg(ocr);
|
NextR.ToSdCmd.Content.arg <= OCRToArg(ocr);
|
NextR.ToSdCmd.Valid <= cActivated;
|
NextRegion := receive;
|
if (iSdCmd.Ack = cActivated) then
|
|
NextR.ToSdCmd.Valid <= cInactivated;
|
|
NextR.Region <= receive;
|
|
end if;
|
|
|
|
when receive =>
|
when receive =>
|
oLedBank(0) <= cActivated;
|
|
TimeoutEnable <= cActivated;
|
|
NextR.ToSdCmd.CheckCrc <= cInactivated;
|
NextR.ToSdCmd.CheckCrc <= cInactivated;
|
|
|
if (iSdCmd.Valid = cActivated) then
|
if (iSdCmd.Valid = cActivated) then
|
NextR.CmdRegion <= CMD8;
|
NextR.CmdRegion <= CMD8;
|
NextR.Region <= waitstate;
|
NextR.Region <= waitstate;
|
Line 245... |
Line 213... |
elsif (Timeout = cActivated) then
|
elsif (Timeout = cActivated) then
|
NextR.State <= invalidCard;
|
NextR.State <= invalidCard;
|
end if;
|
end if;
|
|
|
when waitstate =>
|
when waitstate =>
|
NextCmdTimeoutEnable <= cActivated;
|
NextCmdRegion := CMD2;
|
|
NextRegion := send;
|
if (NextCmdTimeout = cActivated) then
|
|
NextR.CmdRegion <= CMD2;
|
|
NextR.Region <= send;
|
|
end if;
|
|
|
|
|
|
when others =>
|
when others =>
|
report "SdController: Unhandled state" severity error;
|
report "SdController: Unhandled state" severity error;
|
end case;
|
end case;
|
Line 265... |
Line 229... |
case R.Region is
|
case R.Region is
|
when send =>
|
when send =>
|
NextR.ToSdCmd.Content.id <= cSdCmdAllSendCID;
|
NextR.ToSdCmd.Content.id <= cSdCmdAllSendCID;
|
NextR.ToSdCmd.Valid <= cActivated;
|
NextR.ToSdCmd.Valid <= cActivated;
|
|
|
if (iSdCmd.Ack = cActivated) then
|
NextRegion := receive;
|
NextR.ToSdCmd.Valid <= cInactivated;
|
|
NextR.Region <= receive;
|
|
end if;
|
|
|
|
when receive =>
|
when receive =>
|
oLedBank(0) <= cActivated;
|
|
NextR.ToSdCmd.ExpectCID <= cActivated;
|
NextR.ToSdCmd.ExpectCID <= cActivated;
|
TimeoutEnable <= cActivated;
|
|
|
|
if (iSdCmd.Valid = cActivated) then
|
if (iSdCmd.Valid = cActivated) then
|
NextR.State <= invalidCard;
|
NextR.State <= invalidCard;
|
|
|
if (iSdCmd.Content.id = cSdR2Id) then
|
if (iSdCmd.Content.id = cSdR2Id) then
|
Line 287... |
Line 246... |
elsif (Timeout = cActivated) then
|
elsif (Timeout = cActivated) then
|
NextR.State <= invalidCard;
|
NextR.State <= invalidCard;
|
end if;
|
end if;
|
|
|
when waitstate =>
|
when waitstate =>
|
NextCmdTimeoutEnable <= cActivated;
|
NextCmdRegion := CMD3;
|
|
NextRegion := send;
|
|
|
if (NextCmdTimeout = cActivated) then
|
|
NextR.CmdRegion <= CMD3;
|
|
NextR.Region <= send;
|
|
end if;
|
|
when others =>
|
when others =>
|
report "SdController: Unhandled state" severity error;
|
report "SdController: Unhandled state" severity error;
|
end case;
|
end case;
|
|
|
when CMD3 =>
|
when CMD3 =>
|
Line 305... |
Line 261... |
case R.Region is
|
case R.Region is
|
when send =>
|
when send =>
|
NextR.ToSdCmd.Content.id <= cSdCmdSendRelAdr;
|
NextR.ToSdCmd.Content.id <= cSdCmdSendRelAdr;
|
NextR.ToSdCmd.Valid <= cActivated;
|
NextR.ToSdCmd.Valid <= cActivated;
|
|
|
if (iSdCmd.Ack = cActivated) then
|
NextRegion := receive;
|
NextR.ToSdCmd.Valid <= cInactivated;
|
|
NextR.Region <= receive;
|
|
end if;
|
|
|
|
when receive =>
|
when receive =>
|
oLedBank(0) <= cActivated;
|
|
TimeoutEnable <= cActivated;
|
|
|
|
if (iSdCmd.Valid = cActivated) then
|
if (iSdCmd.Valid = cActivated) then
|
if (iSdCmd.Content.id = cSdCmdSendRelAdr) then
|
if (iSdCmd.Content.id = cSdCmdSendRelAdr) then
|
NextR.RCA <= iSdCmd.Content.arg(31 downto 16);
|
NextR.RCA <= iSdCmd.Content.arg(31 downto 16);
|
NextR.State <= idle; -- config;
|
NextR.Region <= waitstate;
|
NextR.CmdRegion <= SelectCard;
|
|
end if;
|
end if;
|
elsif (Timeout = cActivated) then
|
elsif (Timeout = cActivated) then
|
NextR.State <= invalidCard;
|
NextR.State <= invalidCard;
|
end if;
|
end if;
|
|
|
|
when waitstate =>
|
|
NextState := config;
|
|
NextCmdRegion := SelectCard;
|
|
NextRegion := send;
|
|
|
when others =>
|
when others =>
|
report "SdController: Unhandled state" severity error;
|
report "SdController: Unhandled state" severity error;
|
end case;
|
end case;
|
|
|
when others =>
|
when others =>
|
Line 340... |
Line 294... |
case R.CmdRegion is
|
case R.CmdRegion is
|
when SelectCard =>
|
when SelectCard =>
|
case R.Region is
|
case R.Region is
|
when send =>
|
when send =>
|
NextR.ToSdCmd.Content.id <= cSdCmdSelCard;
|
NextR.ToSdCmd.Content.id <= cSdCmdSelCard;
|
NextR.ToSdCmd.Valid <= cActivated;
|
NextR.ToSdCmd.Content.arg <= R.RCA & X"0000";
|
|
|
if (iSdCmd.Ack = cActivated) then
|
NextRegion := receive;
|
NextR.ToSdCmd.Valid <= cInactivated;
|
|
NextR.Region <= receive;
|
|
end if;
|
|
|
|
when receive => -- Response R1b: with busy!
|
when receive => -- Response R1b: with busy!
|
|
if (iSdCmd.Valid = cActivated) then
|
|
if (iSdCmd.Content.id = cSdCmdSelCard) then
|
|
NextR.CardStatus <= iSdCmd.Content.arg;
|
|
NextR.State <= idle;
|
|
end if;
|
|
elsif (Timeout = cActivated) then
|
|
NextR.State <= invalidCard;
|
|
end if;
|
|
|
when waitstate =>
|
when waitstate =>
|
|
|
when others =>
|
when others =>
|
report "Unhandled Region" severity error;
|
report "Unhandled Region" severity error;
|
Line 368... |
Line 327... |
oLedBank(7) <= cActivated;
|
oLedBank(7) <= cActivated;
|
|
|
when others =>
|
when others =>
|
report "SdController: Unhandled state" severity error;
|
report "SdController: Unhandled state" severity error;
|
end case;
|
end case;
|
|
|
|
case R.Region is
|
|
when idle => -- do nothing
|
|
null;
|
|
|
|
when send =>
|
|
NextR.ToSdCmd.Valid <= cActivated;
|
|
|
|
if (iSdCmd.Ack = cActivated) then
|
|
NextR.ToSdCmd.Valid <= cInactivated;
|
|
NextR.Region <= NextRegion;
|
|
end if;
|
|
|
|
when receive =>
|
|
oLedBank(0) <= cActivated;
|
|
TimeoutEnable <= cActivated;
|
|
|
|
when waitstate =>
|
|
NextCmdTimeoutEnable <= cActivated;
|
|
|
|
if (NextCmdTimeout = cActivated) then
|
|
NextCmdTimeoutEnable <= cInactivated;
|
|
NextR.Region <= NextRegion;
|
|
NextR.CmdRegion <= NextCmdRegion;
|
|
NextR.State <= NextState;
|
|
end if;
|
|
|
|
when others =>
|
|
report "Unhandled region" severity error;
|
|
end case;
|
end process Comb;
|
end process Comb;
|
|
|
TimeoutGenerator_inst: entity work.TimeoutGenerator
|
TimeoutGenerator_inst: entity work.TimeoutGenerator
|
generic map (
|
generic map (
|
gClkFrequency => 25E6,
|
gClkFrequency => 25E6,
|
Line 384... |
Line 373... |
oTimeout => Timeout);
|
oTimeout => Timeout);
|
|
|
NextCmdTimeoutGenerator_inst: entity work.TimeoutGenerator
|
NextCmdTimeoutGenerator_inst: entity work.TimeoutGenerator
|
generic map (
|
generic map (
|
gClkFrequency => 25E6,
|
gClkFrequency => 25E6,
|
gTimeoutTime => 1 sec / 25E6 * (8)
|
gTimeoutTime => 600 us--1 sec / 25E6 * (8)
|
)
|
)
|
port map (
|
port map (
|
iClk => iClk,
|
iClk => iClk,
|
inResetAsync => inResetAsync,
|
inResetAsync => inResetAsync,
|
iEnable => NextCmdTimeoutEnable,
|
iEnable => NextCmdTimeoutEnable,
|