Skip to content

Instantly share code, notes, and snippets.

@packysauce
Created January 14, 2016 21:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save packysauce/9fcc9a2699d6c0c201fa to your computer and use it in GitHub Desktop.
Save packysauce/9fcc9a2699d6c0c201fa to your computer and use it in GitHub Desktop.
omap3 sdcard driver written in D using mkregisters
module devices.omap3.mmc;
import core.buffer, core.pack, core.mkregisters;
import devices.blockdevice;
import kernel;
const SDBP = 8;
const PSTATE_BRE = 1 << 11;
const HCTL_CR = 1 << 17;
const C_SIZE = [62, 73];
const C_SIZE_MULT = [47, 49];
const READ_BL_LEN = [80, 83];
enum ResponseType : uint
{
NONE = 0,
RESP_136,
RESP_48,
RESP_48_BUSY,
}
enum StatFields : size_t
{
TC = 0x1,
BGE = 0x2,
BRR = 0x20,
}
struct MMCRegisters
{
mixin(mkregisters!(
uint, "sysconfig", 0x10,
uint, "sysstatus", 0x14,
uint, "csre", 0x24,
uint, "systest", 0x28,
uint, "con", 0x2c,
uint, "pwcnt", 0x30,
uint, "blk", 0x104,
uint, "arg", 0x108,
uint, "cmd", 0x10c,
uint, "rsp10", 0x110,
uint, "rsp32", 0x114,
uint, "rsp54", 0x118,
uint, "rsp76", 0x11c,
uint, "data", 0x120,
uint, "pstate", 0x124,
uint, "hctl", 0x128,
uint, "sysctl", 0x12c,
uint, "stat", 0x130,
uint, "ie", 0x134,
uint, "ise", 0x138,
uint, "ac12", 0x13c,
uint, "capa", 0x140,
uint, "cur_capa", 0x148,
uint, "rev", 0x1fc
));
}
class SDCard : BlockDevice
{
public MMCRegisters *mmc;
private uint rca;
private uint[4] csd;
this(immutable size_t address)
{
mmc = cast(MMCRegisters*) address;
mmcInit();
}
void mmcInit()
{
mmc.sysconfig |= 2;
mmc.con |= 2; // set init
sendCommand(0);
while ((mmc.sysstatus & 1) != 1)
{
// Wait for reset.
}
mmc.sysctl |= 5;
mmc.hctl |= 0x5 << 9 | 0x2 | 1 << SDBP;
mmc.hctl &= ~(1 << 16);
mmc.con |= 1;
sendCommand(55);
sendCommand(41, 1); // set card voltage.
sendCommand(2);
sendCommand(3);
rca = mmc.rsp10;
sendCommand(9, rca, ResponseType.RESP_136);
csd = [mmc.rsp10, mmc.rsp32, mmc.rsp54, mmc.rsp76];
sendCommand(7, rca);
mmc.ie |= 3;
}
/* not done
uint decodeCSDField(uint start, uint end) {
uint sidx = start / 32;
uint eidx = end / 32;
uint start_bits = 2;
csd[sidx] >> ((sidx*uint.sizeof) - start );
}
size_t deviceSize() {
}
*/
void sendCommand(immutable uint cmd, immutable uint arg = 0,
immutable ResponseType type = ResponseType.RESP_48)
{
mmc.arg = arg;
mmc.cmd = cmd << 24 | type << 16;
}
void read(Buffer b, immutable size_t address, immutable size_t offset = 0)
in
{
assert(b.length >= BLOCK, "buffer length can not be less than a block");
}
body
{
// Read a single block.
mmc.blk = 1 << 16 | BLOCK;
mmc.arg = address * BLOCK;
mmc.cmd = 17 << 24 | ResponseType.RESP_48 << 16 | 1 << 21 | 1 << 4;
while ((mmc.stat & StatFields.BRR) != StatFields.BRR)
{
// Wait for request to complete.
}
for(size_t i = 0; i < BLOCK; i += uint.sizeof)
{
mmc.data.pack!(uint)(b, offset + i);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment