SD Card (non-SPI mode) init for CoreABC

51 views
Skip to first unread message

Antti....@googlemail.com

unread,
Mar 14, 2009, 3:06:51 AM3/14/09
to Antti-Brain
Hi

this nice example how the Actel CoreABC is optimized to have only
features required to yield in a very low resource specialised system
that only does SD card init and nothing more, complete source code is
attached:

CoreABC settings:

APB - no devices
Z register - 4 bit wide
Stack size - 4 levels
output port - 4 bits
input port - 2 bits
max instructions - 128 (7 bit PC)

optional instructions: AND, ADD, XOR, SHL/ROL, CALL/RET, IOWRT

instructions not used (disabled, optimized away): OR, IOREAD,INC,SHR,
PUSH/POP


the code below does initialize SD or SDHC cards
verified in real hardware both with SD and SDHC cards


//
//===========================
// Copyright 2009 Antti Lukats
//===========================
DEF OUT_C0_D0 0x00
DEF OUT_C1_D0 0x01
DEF OUT_C0_D1 0x02
DEF OUT_C1_D1 0x03
DEF OUT_C0_DH 0x06
DEF OUT_C1_DH 0x07

DEF CRC7 0x04
DEF TMP 0x06
DEF ARG0 0x01
DEF ARG1 0x03
DEF ARG2 0x02
DEF ARG3 0x05

$start
// START
// send dummy CLKs
CALL $sd_tx_clks

// 0 INIT
// ARG = STUFF
LOAD 0
CALL $sd_tx_command_0_0_01_22

// 8, HC, ARG = 00000122
LOAD 8
CALL $sd_tx_command_0_0_01_22


RAMWRT ARG2 0x00
RAMWRT ARG3 0x00
$RdyLoop
// ACMD41
// wait ready!
// APPCMD RCA=00 ARG = 0000 STUFF
LOAD 55
CALL $sd_tx_command_0_0_x_x

JUMP IFZERO $Error

// 41, set HC enable
LOAD 41
RAMWRT ARG0 0xC0
RAMWRT ARG1 0xFF
CALL $sd_tx_command

// need loop til Ready!
RAMREAD ARG0
JUMP IFPOSITIVE $RdyLoop

// CMD 2 ARG = STUFF
LOAD 2
CALL $sd_tx_command_0_0_x_x
// skip long response
CALL $sd_tx_clks


// CMD3 get RCA, ARG = STUFF
LOAD 3
CALL $sd_tx_command_0_0_x_x

// CMD7 go Transfer, ARG = RCA + STUFF
LOAD 7
CALL $sd_tx_command

// ACMD6 - set 4-bit mode
// CMD55 ARG = RCA + STUFF
LOAD 55
CALL $sd_tx_command
// STUFF + bin(10)
LOAD 6
CALL $sd_tx_command_0_0_01_22
// ready we are done!

// Set init DONE output flag
IOWRT 0x0F
HALT
//
// transmit SD Command
//
$sd_tx_CMD_byte
// Load LOOP counter
LOADZ 8
// Save transmit byte
RAMWRT TMP
$MyLoop
// ROL TMP
RAMREAD TMP
ROL
RAMWRT TMP
// check D7
AND 0x01
// Test D7
JUMP IFNOTZERO $MyTx1

// CLK OUT 0
IOWRT OUT_C0_D0
IOWRT OUT_C1_D0
//----
RAMREAD CRC7
SHL0
JUMP IFNEGATIVE $MyTx01XOR
JUMP $MyTx01


$MyTx1
// CLK OUT 1
IOWRT OUT_C0_D1
IOWRT OUT_C1_D1
//----
RAMREAD CRC7
$MyXOR
SHL0
JUMP IFNEGATIVE $MyTx01

$MyTx01XOR
// XOR CRC
XOR 0x09
// Bit done, CRC no XOR
$MyTx01
// update CRC
RAMWRT CRC7
// decrement loop counter

//
DECZ
JUMP IFNOT ZZERO $MyLoop
RETURN

//$sd_tx_command_0_0_0_x
// RAMWRT ARG2 0x00
$sd_tx_command_0_0_01_22
RAMWRT ARG2 0x01
RAMWRT ARG3 0x22
$sd_tx_command_0_0_x_x
RAMWRT ARG0 0x00
RAMWRT ARG1 0x00

$sd_tx_command
RAMWRT CRC7 0x00
//RAMREAD CMD
// Set HOST Bit
XOR 0x40
CALL $sd_tx_CMD_byte
RAMREAD ARG0
CALL $sd_tx_CMD_byte
RAMREAD ARG1
CALL $sd_tx_CMD_byte
RAMREAD ARG2
CALL $sd_tx_CMD_byte
RAMREAD ARG3
CALL $sd_tx_CMD_byte
// CRC7
RAMREAD CRC7
// shift and add STOP
SHL1
CALL $sd_tx_CMD_byte

//
// skip the RX response
//
LOAD 0x00
$wait_start
ADD 1
JUMP IFZERO $MyReturn
//RETURN IFZERO
//
IOWRT OUT_C0_DH
IOWRT OUT_C1_DH
JUMP IF INPUT0 $wait_start
// we have start bit!
// skip cmd byte
LOADZ 7
CALL $RxLoop
// Receive ARG0
CALL $Rx8Bit
RAMWRT ARG0
// Receive ARG1
CALL $Rx8Bit
RAMWRT ARG1
// we dont care receiving lower result
// just skip.
//JUMP $sd_tx_clks

// send some CLK's
$sd_tx_clks
LOAD 0
$initclks
IOWRT OUT_C0_DH
IOWRT OUT_C1_DH
ADD 1
JUMP IFNOTZERO $initclks
// FLAG OK
LOAD 0xFF
$MyReturn
RETURN

//
// Receive CMD/Response
//
$Rx8Bit
LOADZ 8
$RxLoop
IOWRT OUT_C0_DH
// acc <<= 1;
SHL0
// acc = acc | CMD bit;
JUMP IFNOT INPUT0 $Rx0
ADD 1
$Rx0
// CLK pulse
IOWRT OUT_C1_DH
// dec loop counter
DECZ
JUMP IFNOT ZZERO $RxLoop
// 8 bits are done
RETURN

//
$Error
IOWRT 0x06
HALT

//==========================

description of this system was first publische in Antti-Brain


Reply all
Reply to author
Forward
0 new messages