Created
January 14, 2016 21:39
-
-
Save packysauce/9fcc9a2699d6c0c201fa to your computer and use it in GitHub Desktop.
omap3 sdcard driver written in D using mkregisters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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