Added SD Card support. The SD card VHDL code comes from MultiComp.
Memory Map
-- 0x010050-0x010058F - SD Card -- 0x010051 - SDDATA read/write data -- 0x010053 - SDSTATUS read -- 0x010053 - SDCONTROL write -- 0x010055 - SDLBA0 write-only -- 0x010057 - SDLBA1 write-only -- 0x010059 - SDLBA2 write-only (only bits 6:0 are valid)
C Code to Read First SD Card Block to SRAM
// SDCard.c
#define ACIASTAT (volatile unsigned char *) 0x010041
#define ACIADATA (volatile unsigned char *) 0x010043
#define VDUSTAT (volatile unsigned char *) 0x010040
#define VDUDATA (volatile unsigned char *) 0x010042
#define ACIA_TXRDYBIT 0x2
// SD Card
#define SD_SDDATA_REG (volatile unsigned char *) 0x010051
#define SD_STATUS_REG (volatile unsigned char *) 0x010053
#define SD_CMD_REG (volatile unsigned char *) 0x010053
#define SD_LBA0_REG (volatile unsigned char *) 0x010055
#define SD_LBA1_REG (volatile unsigned char *) 0x010057
#define SD_LBA2_REG (volatile unsigned char *) 0x010059
// SD Card Status Reg
#define SD_WR_RDY 0X80
#define SD_RD_RDY 0X40
#define SD_BLK_BUSY 0X20
#define SD_INIT_BUSY 0X10
// SD Card Control values
#define SD_RD_BLK 0x00
#define SD_WR_BLK 0x01
#define BUFFER_START 0XE000
/*
-- To read a 512-byte block from the SDCARD:
-- Wait until SDSTATUS=0x80 (ensures previous cmd has completed)
-- Write SDLBA0, SDLBA1 SDLBA2 to select block index to read from
-- Write 0 to SDCONTROL to issue read command
-- Loop 512 times:
-- Wait until SDSTATUS=0xE0 (read byte ready, block busy)
-- Read byte from SDDATA
--
-- To write a 512-byte block to the SDCARD:
-- Wait until SDSTATUS=0x80 (ensures previous cmd has completed)
-- Write SDLBA0, SDLBA1 SDLBA2 to select block index to write to
-- Write 1 to SDCONTROL to issue write command
-- Loop 512 times:
-- Wait until SDSTATUS=0xA0 (block busy)
-- Write byte to SDDATA
*/
// Prototypes
void printCharToACIA(unsigned char);
void printStringToACIA(const char *);
void printCharToVDU(unsigned char);
void printStringToVDU(const char *);
void waitUART(unsigned int waitTime);
void wait_Until_SD_CMD_Done(void);
void write_SD_LBA(unsigned long);
void readSDBlockToBuffer(void);
void wait_Until_SD_Char_RD_Rdy(void);
int main(void)
{
asm("move.l #0x1000,%sp"); // Set up initial stack pointer
printStringToVDU("Waiting on SD Card ready\n\r");
wait_Until_SD_CMD_Done();
printStringToVDU("SD Card is ready\n\r");
printStringToVDU("Writing LBA = 0\n\r");
write_SD_LBA(0);
printStringToVDU("Reading block\n\r");
readSDBlockToBuffer();
printStringToVDU("Block was read to 0xE000\n\r");
asm("move.b #228,%d7\n\t"
"trap #14");
return(0);
}
void readSDBlockToBuffer(void)
{
unsigned short loopCount = 512;
unsigned char readSDChar;
unsigned char * destAddr;
destAddr = (unsigned long) BUFFER_START;
* SD_CMD_REG = SD_RD_BLK;
while (loopCount > 0)
{
wait_Until_SD_Char_RD_Rdy();
readSDChar = *SD_SDDATA_REG;
*destAddr++ = readSDChar;
loopCount--;
}
}
void write_SD_LBA(unsigned long lba)
{
unsigned char lba0, lba1, lba2;
lba0 = lba & 0xff;
lba1 = (lba >> 8) & 0xff;
lba2 = (lba >> 16) & 0xff;
* SD_LBA0_REG = lba0;
* SD_LBA1_REG = lba1;
* SD_LBA2_REG = lba2;
}
void wait_Until_SD_Char_RD_Rdy(void)
{
unsigned char charStat;
charStat = * SD_STATUS_REG;
while (charStat != 0xE0)
{
charStat = *SD_STATUS_REG;
}
}
void wait_Until_SD_CMD_Done(void)
{
unsigned char charStat;
charStat = * SD_STATUS_REG;
while (charStat != 0x80)
{
charStat = *SD_STATUS_REG;
}
}
void waitUART(unsigned int waitTime)
{
volatile unsigned int timeCount = 0;
for (timeCount = 0; timeCount < waitTime; timeCount++);
}
void printCharToACIA(unsigned char charToPrint)
{
while ((*ACIASTAT & ACIA_TXRDYBIT) != ACIA_TXRDYBIT);
* ACIADATA = charToPrint;
}
void printStringToACIA(const char * strToPrint)
{
int strOff = 0;
while(strToPrint[strOff] != 0)
printCharToACIA(strToPrint[strOff++]);
}
void printCharToVDU(unsigned char charToPrint)
{
while ((*VDUSTAT & ACIA_TXRDYBIT) != ACIA_TXRDYBIT);
* VDUDATA = charToPrint;
}
void printStringToVDU(const char * strToPrint)
{
int strOff = 0;
while(strToPrint[strOff] != 0)
printCharToVDU(strToPrint[strOff++]);
}
Results
Reading 6809 FLEX SD Card.
TUTOR 1.3 > GO 2000 PHYSICAL ADDRESS=00002000 Waiting on SD Card ready SD Card is ready Writing LBA = 0 Reading block Block was read to 0xE000 TUTOR 1.3 > WHAT TUTOR 1.3 > MD E000 00E000 00 41 49 4E 00 00 00 00 42 4F 4F 54 47 45 4E 00 .AIN....BOOTGEN. TUTOR 1.3 > 00E010 45 58 45 00 24 00 00 F0 00 00 00 00 00 00 00 00 EXE.$..p........ 00E020 53 59 53 54 45 4D 00 00 48 45 4C 50 00 00 00 00 SYSTEM..HELP.... 00E030 45 58 45 00 25 B7 00 F0 00 00 00 00 00 00 00 00 EXE.%7.p........ 00E040 48 45 4C 50 00 00 00 00 53 59 53 54 45 4D 00 00 HELP....SYSTEM.. 00E050 48 4C 50 00 27 20 00 F0 00 00 00 00 00 00 00 00 HLP.' .p........ 00E060 53 59 53 54 45 4D 00 00 43 4F 50 59 00 00 00 00 SYSTEM..COPY.... 00E070 45 58 45 00 29 00 00 F0 00 00 00 00 00 00 00 00 EXE.)..p........ 00E080 53 59 53 54 45 4D 00 00 44 49 52 00 00 00 00 00 SYSTEM..DIR..... 00E090 45 58 45 00 2B 00 00 F0 00 00 00 00 00 00 00 00 EXE.+..p........ 00E0A0 53 59 53 54 45 4D 00 00 43 48 4B 44 49 53 4B 00 SYSTEM..CHKDISK. 00E0B0 45 58 45 00 2D 00 00 F0 00 00 00 00 00 00 00 00 EXE.-..p........ 00E0C0 53 59 53 54 45 4D 00 00 41 53 4D 00 00 00 00 00 SYSTEM..ASM..... 00E0D0 45 58 45 00 65 00 00 F0 00 00 00 00 00 00 00 00 EXE.e..p........ 00E0E0 53 59 53 54 45 4D 00 00 41 53 50 00 00 00 00 00 SYSTEM..ASP..... 00E0F0 45 58 45 00 6E 00 00 F0 00 00 00 00 00 00 00 00 EXE.n..p........ 00E100 53 59 53 54 45 4D 00 00 42 41 53 49 43 00 00 00 SYSTEM..BASIC... TUTOR 1.3 >
Works well!
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.