URL
https://opencores.org/ocsvn/sdhc-sc-core/sdhc-sc-core/trunk
Subversion Repositories sdhc-sc-core
[/] [sdhc-sc-core/] [trunk/] [grpSd/] [pkgSd/] [src/] [Sd-p.vhdl] - Rev 185
Compare with Previous | Blame | View Log
-- SDHC-SC-Core -- Secure Digital High Capacity Self Configuring Core -- -- (C) Copyright 2010, Rainer Kastl -- All rights reserved. -- -- Redistribution and use in source and binary forms, with or without -- modification, are permitted provided that the following conditions are met: -- * Redistributions of source code must retain the above copyright -- notice, this list of conditions and the following disclaimer. -- * 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. -- * Neither the name of the <organization> 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 <COPYRIGHT HOLDER> 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. -- -- File : Sd-p.vhdl -- Owner : Rainer Kastl -- Description : Definitions for SD cards and controllers (Spec 2.0) -- Links : -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.Global.all; package Sd is -- CMD transfer: constants constant cSdStartBit : std_ulogic := '0'; constant cSdEndBit : std_ulogic := '1'; constant cSdTransBitHost : std_ulogic := '1'; constant cSdTransBitSlave : std_ulogic := '0'; -- CMD transfer: types constant cSdCmdIdHigh : natural := 6; subtype aSdCmdId is std_ulogic_vector(cSdCmdIdHigh-1 downto 0); subtype aSdCmdArg is std_ulogic_vector(31 downto 0); type aSdCmdContent is record id : aSdCmdId; arg : aSdCmdArg; end record aSdCmdContent; constant cDefaultSdCmdContent : aSdCmdContent := ( id => (others => '0'), arg => (others => '0')); type aSdCmdToken is record startbit : std_ulogic; -- cSdStartBit transbit : std_ulogic; content : aSdCmdContent; crc7 : std_ulogic_vector(6 downto 0); -- CRC of content endbit : std_ulogic; --cSdEndBit end record aSdCmdToken; constant cDefaultSdCmdToken : aSdCmdToken := ( startbit => cActivated, transbit => cActivated, content => cDefaultSdCmdContent, crc7 => (others => '0'), endbit => cInactivated); -- SD Card Regs subtype aVoltageWindow is std_ulogic_vector(23 downto 15); constant cVoltageWindow : aVoltageWindow := (others => '1'); constant cSdR3Id : aSdCmdId := (others => '1'); constant cSdR2Id : aSdCmdId := (others => '1'); type aSdRegOCR is record voltagewindow : aVoltageWindow; ccs : std_ulogic; nBusy : std_ulogic; end record aSdRegOCR; subtype aSdCardStatus is std_ulogic_vector(31 downto 0); constant cSdStatusReadyForDataBit : natural := 8; constant cDefaultSdCardStatus : aSdCardStatus := (others => '0'); constant cSdOCRQuery : aSdRegOCR := ( voltagewindow => (others => '0'), ccs => '0', nBusy => '0'); function OCRToArg (ocr : in aSdRegOCR) return aSdCmdArg; function ArgToOcr (arg : in aSdCmdArg) return aSdRegOCR; subtype aSdCIDMID is std_ulogic_vector(7 downto 0); subtype aSdCIDOID is std_ulogic_vector(15 downto 0); subtype aSdCIDPNM is std_ulogic_vector(39 downto 0); subtype aSdCIDPRV is std_ulogic_vector(7 downto 0); subtype aSdCIDPSN is std_ulogic_vector(31 downto 0); subtype aSdCIDMDT is std_ulogic_vector(11 downto 0); type aSdRegCID is record mid : aSdCIDMID; oid : aSdCIDOID; name : aSdCIDPNM; revision : aSdCIDPRV; serialnumber : aSdCIDPSN; date : aSdCIDMDT; end record; constant cCIDLength : natural := 127; constant cDefaultSdRegCID : aSdRegCID := ( mid => (others => '0'), oid => (others => '0'), name => (others => '0'), revision => (others => '0'), serialnumber => (others => '0'), date => (others => '0')); function UpdateCID(icid : in aSdRegCID; data : in std_ulogic; pos : in natural) return aSdRegCID; subtype aSdRCA is std_ulogic_vector(15 downto 0); constant cDefaultRCA : aSdRCA := (others => '0'); constant cSdWideModeBit : natural := 31-(63-50); -- first word -- Data types subtype aSdData is std_ulogic_vector(3 downto 0); constant cSdStartBits : aSdData := (others => cSdStartBit); constant cSdEndBits : aSdData := (others => cSdEndBit); constant cBlocklen : natural := 512 * 8; -- 512 bytes subtype aSdDataBlock is std_ulogic_vector(cBlocklen - 1 downto 0); type aSdDataBusMode is (standard, wide); type aSdDataMode is (usual, widewidth); type aSdDataBits is (ScrBits, SwitchFunctionBits); constant cScrBitsCount : natural := 4096 - 64 + 7; -- expressed in bits constant cSwitchFunctionBitsCount : natural := 4096 - 512 + 7; -- expressed in bits constant cWideModeBitAddr : natural := 50; constant cHighSpeedBitAddr : natural := 401; constant cSwitchFunctionBitLowAddr : natural := 376; -- Types for entities -- between SdController and SdCmd type aSdCmdFromController is record Content : aSdCmdContent; -- id and arg to sent to card Valid : std_ulogic; -- gets asserted when Content is valid and can be sent to card ExpectCID : std_ulogic; -- gets asserted when next response is R2 CheckCrc : std_ulogic; -- gets asserted when CRC has to be checked (exceptions is R3) end record aSdCmdFromController; type aSdCmdToController is record Ack : std_ulogic; -- Gets asserted when crc was sent, but endbit was not. This way we can minimize the wait time between sending 2 cmds. Receiving : std_ulogic; -- gets asserted when a response is received currently Content : aSdCmdContent; -- received id and arg, see valid Valid : std_ulogic; -- gets asserted when CmdContent is valid (therefore a cmd was received and can be saved) Err : std_ulogic; -- gets asserted when an error occurred during receiving a cmd, for example the crc check does not hold Cid : aSdRegCID; -- received CID register of the card, see valid end record aSdCmdToController; constant cDefaultSdCmdToController : aSdCmdToController := ( Ack => cInactivated, Receiving => cInactivated, Valid => cInactivated, Content => cDefaultSdCmdContent, Err => cInactivated, Cid => cDefaultSdRegCID); constant cDataRamAddrWidth : natural := 7; constant cDataRamDataWidth : natural := 32; subtype aWord is std_ulogic_vector(cDataRamDataWidth - 1 downto 0); subtype aAddr is natural range 0 to 2**cDataRamAddrWidth - 1; type aSdControllerToRam is record Addr : aAddr; end record aSdControllerToRam; constant cDefaultSdControllerToRam : aSdControllerToRam := (Addr => 0); type aSdControllerFromRam is record Data : aWord; end record aSdControllerFromRam; -- between SdController and SdData type aSdDataFromController is record Mode : aSdDataBusMode; -- select 1 bit or 4 bit mode DataMode : aSdDataMode; -- select usual or wide width data ExpectBits : aSdDataBits; -- how many bits are expected in wide with data mode Valid : std_ulogic; -- valid, when the datablock is valid and has to be sent CheckBusy : std_ulogic; -- check for busy signaling DisableRb : std_ulogic; -- disable read back: do not save read data to fifo end record aSdDataFromController; constant cDefaultSdDataFromController : aSdDataFromController := ( Mode => standard, DataMode => usual, ExpectBits => ScrBits, Valid => cInactivated, CheckBusy => cInactivated, DisableRb => cActivated); type aSpeedBits is record HighSpeedSupported : std_ulogic; SwitchFunctionOK : std_ulogic_vector(3 downto 0); -- 0x01 when ok end record aSpeedBits; constant cDefaultSpeedBits : aSpeedBits := ( HighSpeedSupported => '0', SwitchFunctionOK => (others => '0')); type aSdDataToController is record Ack : std_ulogic; -- gets asserted when a datablock was sent to the card Receiving : std_ulogic; -- gets asserted when a datablock is currently received Valid : std_ulogic; -- gets asserted when DataBlock is valid and therefore it was received correctly Busy : std_ulogic; -- gets asserted when the card returns busy Err : std_ulogic; -- gets asserted when an error occurred during receiving a data block (CRC) SpeedBits : aSpeedBits; -- gets set, when data for check or switch function cmd is received (DataMode = widewidth and ExpectBits = SwitchFunctionBits WideMode : std_ulogic; -- gets set, when scr is read (datamode = widewidth and ExpectBits = ScrBits) end record aSdDataToController; constant cDefaultSdDataToController : aSdDataToController := ( Ack => cInactivated, Receiving => cInactivated, Valid => cInactivated, Busy => cInactivated, Err => cInactivated, SpeedBits => cDefaultSpeedBits, WideMode => cInactivated); -- SdData to Ram type aSdDataToRam is record En : std_ulogic; Addr : aAddr; Data : aWord; We : std_ulogic; end record aSdDataToRam; constant cDefaultSdDataToRam : aSdDataToRam := ( En => cInactivated, Addr => 0, Data => (others => '0'), We => cInactivated); type aSdDataFromRam is record Data : aWord; end record aSdDataFromRam; -- between SdController and wishbone interface type aSdRegisters is record CardStatus : aSdCardStatus; end record aSdRegisters; -- constants for SdController subtype aRCA is std_ulogic_vector(15 downto 0); constant cSdDefaultRCA : aRCA := (others => '0'); -- command ids -- abbreviations: -- RCA: relative card address constant cSdCmdGoIdleState : aSdCmdId := std_ulogic_vector(to_unsigned(0, cSdCmdIdHigh)); -- no args constant cSdCmdAllSendCID : aSdCmdId := std_ulogic_vector(to_unsigned(2, cSdCmdIdHigh)); -- no args constant cSdCmdSendRelAdr : aSdCmdId := std_ulogic_vector(to_unsigned(3, cSdCmdIdHigh)); -- no args constant cSdCmdSetDSR : aSdCmdId := std_ulogic_vector(to_unsigned(4, cSdCmdIdHigh)); -- [31:16] DSR constant cSdCmdSelCard : aSdCmdId := std_ulogic_vector(to_unsigned(7, cSdCmdIdHigh)); -- [31:16] RCA constant cSdCmdDeselCard : aSdCmdId := cSdCmdSelCard; -- [31:16] RCA constant cSdCmdSendIfCond : aSdCmdId := std_ulogic_vector(to_unsigned(8, cSdCmdIdHigh)); constant cSdDefaultVoltage : std_ulogic_vector(3 downto 0) := "0001"; -- 2.7 -- - 3.6 V constant cCheckpattern : std_ulogic_vector(7 downto 0) := "10101010"; -- recommended constant cSdArgVoltage : aSdCmdArg := "00000000000000000000" & -- reserved cSdDefaultVoltage & -- supply voltage cCheckPattern; constant cSdCmdSendCSD : aSdCmdId := std_ulogic_vector(to_unsigned(9, cSdCmdIdHigh)); -- [31:16] RCA constant cSdCmdSendCID : aSdCmdId := std_ulogic_vector(to_unsigned(10, cSdCmdIdHigh)); -- [31:16] RCA constant cSdCmdStopTrans : aSdCmdId := std_ulogic_vector(to_unsigned(12, cSdCmdIdHigh)); -- no args constant cSdCmdSendStatus : aSdCmdId := std_ulogic_vector(to_unsigned(13, cSdCmdIdHigh)); -- [31:16] RCA constant cSdNextIsACMD : aSdCmdId := std_ulogic_vector(to_unsigned(55, cSdCmdIdHigh)); constant cSdACMDArg : aSdCmdArg := cSdDefaultRCA & X"0000"; -- [31:16] RCA constant cSdArgAppCmdPos : natural := 5; constant cSdCmdReadSingleBlock : aSdCmdId := std_ulogic_vector(to_unsigned(17, cSdCmdIdHigh)); constant cSdCmdWriteSingleBlock : aSdCmdId := std_ulogic_vector(to_unsigned(24, cSdCmdIdHigh)); constant cSdCmdACMD41 : aSdCmdId := std_ulogic_vector(to_unsigned(41, cSdCmdIdHigh)); constant cSdCmdSendSCR : aSdCmdId := std_ulogic_vector(to_unsigned(51, cSdCmdIdHigh)); constant cSdCmdSetBusWidth : aSdCmdId := std_ulogic_vector(to_unsigned(6, cSdCmdIdHigh)); -- [31:2] stuff, [1:0] bus width constant cSdWideBusWidth : std_ulogic_vector(1 downto 0) := "10"; constant cSdStandardBusWidth : std_ulogic_vector(1 downto 0) := "00"; constant cSdCmdSwitchFunction : aSdCmdId := std_ulogic_vector(to_unsigned(6, cSdCmdIdHigh)); -- 31: mode constant cSdCmdCheckMode : std_ulogic := '0'; constant cSdCmdSwitchMode : std_ulogic := '1'; -- 30:24 reserved -- 23:8 function group 6 - 3 -- 7:4 group 2 for command system -- 3:0 group 1 for access mode constant cSdCmdCheckSpeedSupport : aSdCmdArg := X"00FFFFF1"; constant cSdCmdSwitchSpeed : aSdCmdArg := X"80FFFFF1"; constant cSdHighSpeedFunctionSupportBit : natural := 401; constant cSdHighSpeedFunctionGroupLow : natural := 376; type aiSdCmd is record Cmd : std_ulogic; end record aiSdCmd; type aoSdCmd is record Cmd : std_ulogic; En : std_ulogic; end record aoSdCmd; type aiSdData is record Data : aSdData; end record aiSdData; type aoSdData is record Data : aSdData; En : aSdData; end record aoSdData; constant cDefaultSdData : aoSdData := ( Data => (others => '0'), En => (others => '0')); end package Sd; package body Sd is function OCRToArg (ocr : in aSdRegOCR) return aSdCmdArg is variable temp : aSdCmdArg; begin temp := ocr.nBusy & ocr.ccs & "000000" & ocr.voltagewindow & "000000000000000"; return temp; end function OCRtoArg; function ArgToOcr (arg : in aSdCmdArg) return aSdRegOCR is variable ocr : aSdRegOCR; begin ocr.nBusy := arg(31); ocr.ccs := arg(30); ocr.voltagewindow := arg(23 downto 15); return ocr; end function ArgToOcr; function UpdateCID(icid : in aSdRegCID; data : in std_ulogic; pos : in natural) return aSdRegCID is variable cid : aSdRegCID; begin cid := icid; if (pos <= 127 and pos >= 120) then cid.mid(pos-120) := data; elsif (pos <= 119 and pos >= 104) then cid.oid(pos-104) := data; elsif (pos <= 103 and pos >= 64) then cid.name(pos-64) := data; elsif (pos <= 63 and pos >= 56) then cid.revision(pos-56) := data; elsif (pos <= 55 and pos >= 24) then cid.serialnumber(pos-24) := data; elsif (pos <= 19 and pos >= 8) then cid.date(pos-8) := data; end if; return cid; end function UpdateCID; end package body Sd;