OpenCores
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] - Diff between revs 170 and 185

Show entire file | Details | Blame | View Log

Rev 170 Rev 185
Line 1... Line 1...
 
-- 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;
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.