SD card module works. Disk and FATFS read work.
TODO: adapt SPI clock to SD card type for faster transfer
This commit is contained in:
@@ -60,7 +60,6 @@ CSRCS= \
|
||||
$(SRCDIR)/bas_printf.c \
|
||||
$(SRCDIR)/BaS.c \
|
||||
$(SRCDIR)/cache.c \
|
||||
$(SRCDIR)/sd_card.c \
|
||||
$(SRCDIR)/mmcbb.c \
|
||||
$(SRCDIR)/ff.c \
|
||||
$(SRCDIR)/wait.c
|
||||
|
||||
@@ -12,7 +12,6 @@ SECTIONS
|
||||
objs/startcf.o(.text) /* this one is the entry point so it must be the first */
|
||||
objs/sysinit.o(.text)
|
||||
objs/init_fpga.o(.text)
|
||||
objs/sd_card.o(.text)
|
||||
objs/ff.o(.text)
|
||||
objs/wait.o(.text)
|
||||
objs/mmcbb.o(.text)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include <MCF5475.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern int spi_init(void);
|
||||
extern void spi_init(void);
|
||||
extern uint32_t sd_com(uint32_t data);
|
||||
extern void sd_card_idle(void);
|
||||
extern uint8_t sd_card_get_status(void);
|
||||
|
||||
@@ -192,7 +192,18 @@ void BaS(void)
|
||||
xprintf("mount status of SD card fs is %d\r\n", fres);
|
||||
if (fres == FR_OK)
|
||||
{
|
||||
;
|
||||
DIR directory;
|
||||
|
||||
fres = f_opendir(&directory, "\\");
|
||||
if (fres == FR_OK)
|
||||
{
|
||||
FILINFO fi;
|
||||
|
||||
while (((fres = f_readdir(&directory, &fi)) == FR_OK) && fi.fname[0])
|
||||
{
|
||||
xprintf("%13.13s %d\r\n", fi.fname, fi.fsize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
xprintf("copy EmuTOS: ");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <stdint.h>
|
||||
#include <bas_types.h>
|
||||
#include <sd_card.h>
|
||||
#include <bas_printf.h>
|
||||
#include "sysinit.h"
|
||||
|
||||
/*
|
||||
@@ -44,8 +45,8 @@
|
||||
#define SSPxCR0 SSP1CR0
|
||||
#define SSPxCR1 SSP1CR1
|
||||
#define SSPxCPSR SSP1CPSR
|
||||
#define CS_LOW() {FIO0CLR0 = _BV(6);} /* Set P0.6 low */
|
||||
#define CS_HIGH() {FIO0SET0 = _BV(6);} /* Set P0.6 high */
|
||||
#define CS_HIGH() { dspi_fifo_val &= ~MCF_DSPI_DTFR_CS5; }
|
||||
#define CS_LOW() { dspi_fifo_val |= MCF_DSPI_DTFR_CS5; }
|
||||
#define PCSSPx PCSSP1
|
||||
#define PCLKSSPx PCLK_SSP1
|
||||
#endif
|
||||
@@ -110,15 +111,25 @@ static uint8_t CardType; /* Card type flags */
|
||||
/* Send/Receive data to the MMC (Platform dependent) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static uint32_t dspi_fifo_val = /* CONT disable continous chip select */
|
||||
/* CTAS use DCTAR0 for clock and attributes */
|
||||
MCF_DSPI_DTFR_EOQ; /* current transfer is last in queue */
|
||||
|
||||
|
||||
/* Exchange a byte */
|
||||
static uint8_t xchg_spi(uint8_t byte)
|
||||
{
|
||||
* (volatile uint8_t *) (&MCF_DSPI_DTFR + 3) = byte;
|
||||
uint32_t fifo = dspi_fifo_val | byte;
|
||||
uint8_t res;
|
||||
|
||||
//while (! (MCF_DSPI_DSR & MCF_DSPI_DSR_TCF)); /* wait until DSPI transfer complete */
|
||||
MCF_DSPI_DTFR = fifo;
|
||||
while (! (MCF_DSPI_DSR & MCF_DSPI_DSR_TCF)); /* wait until DSPI transfer complete */
|
||||
MCF_DSPI_DSR = 0xffffffff; /* clear DSPI status register */
|
||||
|
||||
return * (volatile uint8_t *) (&MCF_DSPI_DRFR + 3);
|
||||
fifo = MCF_DSPI_DRFR;
|
||||
res = fifo & 0xff;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -154,10 +165,11 @@ static void xmit_spi_multi(const uint8_t *buff, uint32_t btx)
|
||||
|
||||
static uint32_t card_ready(void)
|
||||
{
|
||||
static uint32_t counter = 0;
|
||||
uint8_t d;
|
||||
|
||||
d = xchg_spi(0xff);
|
||||
return (d != 0xff);
|
||||
return (d == 0xff);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -166,7 +178,7 @@ static uint32_t card_ready(void)
|
||||
* wt: timeout in ms
|
||||
* returns 1: ready, 0: timeout
|
||||
*/
|
||||
static int wait_ready (uint32_t wt)
|
||||
static int wait_ready(uint32_t wt)
|
||||
{
|
||||
return waitfor(wt, card_ready);
|
||||
}
|
||||
@@ -178,7 +190,7 @@ static int wait_ready (uint32_t wt)
|
||||
*/
|
||||
static void deselect(void)
|
||||
{
|
||||
MCF_DSPI_DTFR = MCF_DSPI_DTFR_EOQ | ~MCF_DSPI_DTFR_CS5;
|
||||
CS_HIGH();
|
||||
xchg_spi(0xFF); /* Dummy clock (force DO hi-z for multiple slave SPI) */
|
||||
MCF_DSPI_DSR = 0xffffffff; /* clear status register */
|
||||
}
|
||||
@@ -191,10 +203,12 @@ static void deselect(void)
|
||||
|
||||
static int select(void) /* 1:OK, 0:Timeout */
|
||||
{
|
||||
MCF_DSPI_DTFR = MCF_DSPI_DTFR_EOQ | MCF_DSPI_DTFR_CS5;
|
||||
CS_LOW();
|
||||
|
||||
xchg_spi(0xFF); /* Dummy clock (force DO enabled) */
|
||||
|
||||
if (wait_ready(500)) return 1; /* OK */
|
||||
if (wait_ready(5000000))
|
||||
return 1; /* OK */
|
||||
deselect();
|
||||
return 0; /* Timeout */
|
||||
}
|
||||
@@ -204,28 +218,42 @@ static int select(void) /* 1:OK, 0:Timeout */
|
||||
/*
|
||||
* Control SPI module (Platform dependent)
|
||||
*/
|
||||
|
||||
static void power_on (void) /* Enable SSP module and attach it to I/O pads */
|
||||
{
|
||||
spi_init();
|
||||
#ifdef _NOT_USED_
|
||||
__set_PCONP(PCSSPx, 1); /* Enable SSP module */
|
||||
__set_PCLKSEL(PCLKSSPx, PCLKDIV_SSP); /* Select PCLK frequency for SSP */
|
||||
SSPxCR0 = 0x0007; /* Set mode: SPI mode 0, 8-bit */
|
||||
SSPxCR1 = 0x2; /* Enable SSP with Master */
|
||||
#if SSP_CH == 0
|
||||
__set_PINSEL(0, 15, 2); /* Attach SCK0 to I/O pad */
|
||||
__set_PINSEL(0, 16, 2); /* Attach MISO0 to I/O pad */
|
||||
__set_PINSEL(0, 17, 2); /* Attach MOSI0 to I/O pad */
|
||||
FIO0DIR |= _BV(18)|_BV(17)|_BV(15); /* Set SCK0, MOSI0 and CS# as output */
|
||||
#elif SSP_CH == 1
|
||||
__set_PINSEL(0, 7, 2); /* Attach SCK1 to I/O pad */
|
||||
__set_PINSEL(0, 8, 2); /* Attach MISO1 to I/O pad */
|
||||
__set_PINSEL(0, 9, 2); /* Attach MOSI1 to I/O pad */
|
||||
FIO0DIR |= _BV(9)|_BV(7)|_BV(6); /* Set SCK1, MOSI1 and CS# as output */
|
||||
#endif
|
||||
MCF_PAD_PAR_DSPI = 0x1fff; /* configure all DSPI GPIO pins for DSPI usage */
|
||||
|
||||
/*
|
||||
* FIXME: really necessary or just an oversight
|
||||
* that PAD_PAR_DSPI is only 16 bit?
|
||||
*/
|
||||
// MCF_PAD_PAR_TIMER = 0xff; leave off for now
|
||||
|
||||
/*
|
||||
* initialize DSPI module configuration register
|
||||
*/
|
||||
MCF_DSPI_DMCR = MCF_DSPI_DMCR_MSTR | /* FireBee is DSPI master*/
|
||||
MCF_DSPI_DMCR_CSIS5 | /* CS5 inactive state high */
|
||||
MCF_DSPI_DMCR_CSIS3 | /* CS3 inactive state high */
|
||||
MCF_DSPI_DMCR_CSIS2 | /* CS2 inactive state high */
|
||||
MCF_DSPI_DMCR_DTXF | /* disable transmit FIFO */
|
||||
MCF_DSPI_DMCR_DRXF | /* disable receive FIFO */
|
||||
MCF_DSPI_DMCR_CTXF | /* clear transmit FIFO */
|
||||
MCF_DSPI_DMCR_CRXF; /* clear receive FIFO */
|
||||
|
||||
/* initialize DSPI clock and transfer attributes register 0 */
|
||||
MCF_DSPI_DCTAR0 = MCF_DSPI_DCTAR_TRSZ(0b111) | /* transfer size = 8 bit */
|
||||
MCF_DSPI_DCTAR_PCSSCK(0b01) | /* 3 clock DSPICS to DSPISCK delay prescaler */
|
||||
MCF_DSPI_DCTAR_PASC_3CLK | /* 3 clock DSPISCK to DSPICS negation prescaler */
|
||||
MCF_DSPI_DCTAR_PDT_3CLK | /* 3 clock delay between DSPICS assertions prescaler */
|
||||
MCF_DSPI_DCTAR_PBR_3CLK | /* 3 clock prescaler */
|
||||
MCF_DSPI_DCTAR_ASC(0b1001) | /* 1024 */
|
||||
MCF_DSPI_DCTAR_DT(0b1001) | /* 1024 */
|
||||
MCF_DSPI_DCTAR_BR(0b0111);
|
||||
|
||||
CS_HIGH(); /* Set CS# high */
|
||||
#endif /* _NOT_USED_ */
|
||||
|
||||
/* card should now be initialized as MMC */
|
||||
|
||||
wait(10 * 1000); /* 10ms */
|
||||
}
|
||||
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* sd_card.c
|
||||
*
|
||||
* This file is part of BaS_gcc.
|
||||
*
|
||||
* BaS_gcc is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BaS_gcc is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BaS_gcc. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Copyright 2010 - 2012 F. Aschwanden
|
||||
* Copyright 2011 - 2012 V. Riviere
|
||||
* Copyright 2012 M. Froeschle
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <MCF5475.h>
|
||||
#include <bas_printf.h>
|
||||
#include <sd_card.h>
|
||||
#include <wait.h>
|
||||
#include "diskio.h"
|
||||
|
||||
/*
|
||||
* "standard value" for DSPI module configuration register MCF_DSPC_DMCR
|
||||
*/
|
||||
const uint32_t DSPI_DMCR_CONF = MCF_DSPI_DMCR_MSTR | /* FireBee is DSPI master*/ /* 8 bit CS5 on */
|
||||
MCF_DSPI_DMCR_CSIS3 | /* CS3 inactive */
|
||||
MCF_DSPI_DMCR_CSIS2 | /* CS2 inactive */
|
||||
MCF_DSPI_DMCR_DTXF | /* disable transmit FIFO */
|
||||
MCF_DSPI_DMCR_DRXF | /* disable receive FIFO */
|
||||
MCF_DSPI_DMCR_CTXF | /* clear transmit FIFO */
|
||||
MCF_DSPI_DMCR_CRXF; /* clear receive FIFO */
|
||||
/* 0x800d3c00 */
|
||||
|
||||
|
||||
/*
|
||||
* Write data to the DSPI TX FIFO register
|
||||
* First 16 bits are the SPI command field (basically say only HOW to transfer the second
|
||||
* half), second are the data to transfer
|
||||
*/
|
||||
uint32_t spi_command(uint32_t data)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
MCF_DSPI_DTFR = data; /* write value to TX FIFO */
|
||||
|
||||
while (! (MCF_DSPI_DSR & MCF_DSPI_DSR_TCF)); /* wait until DSPI transfer complete */
|
||||
ret = MCF_DSPI_DRFR; /* read DSPI Rx FIFO register */
|
||||
MCF_DSPI_DSR = 0xffffffff; /* clear DSPI status register */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* transfer a byte to SPI. This only works if the rest of the DSPI TX FIFO has been
|
||||
* initialized previously (either by spi_com or a direct register write).
|
||||
* Returns a byte received from SPI (contents of the RX FIFO).
|
||||
*/
|
||||
|
||||
#define MCF_DSPI_DTFR_BYTE _MBAR[0x8a37]
|
||||
inline uint8_t spi_send_byte(uint8_t byte)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
MCF_DSPI_DTFR_BYTE = byte;
|
||||
|
||||
while (! (MCF_DSPI_DSR & MCF_DSPI_DSR_TCF)); /* wait until DSPI transfer complete */
|
||||
ret = MCF_DSPI_DTFR_BYTE;
|
||||
MCF_DSPI_DSR = 0xffffffff;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* as above, but word sized
|
||||
*/
|
||||
#define MCF_DSPI_DTFR_WORD * (uint16_t *) &_MBAR[0x8ad6]
|
||||
inline uint16_t spi_send_word(uint16_t word)
|
||||
{
|
||||
uint16_t ret;
|
||||
|
||||
MCF_DSPI_DTFR_WORD = word;
|
||||
|
||||
ret = MCF_DSPI_DTFR_WORD;
|
||||
MCF_DSPI_DSR = 0xffffffff;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int spi_init(void)
|
||||
{
|
||||
uint32_t ret;
|
||||
uint8_t rb;
|
||||
int i;
|
||||
|
||||
xprintf("SD-Card initialization: ");
|
||||
|
||||
MCF_PAD_PAR_DSPI = 0x1fff; /* configure all DSPI GPIO pins for DSPI usage */
|
||||
MCF_PAD_PAR_TIMER = 0xff; /*
|
||||
* FIXME: really necessary or just an oversight
|
||||
* that PAD_PAR_DSPI is only 16 bit?
|
||||
*/
|
||||
|
||||
MCF_DSPI_DMCR = DSPI_DMCR_CONF;
|
||||
|
||||
MCF_DSPI_DCTAR0 = MCF_DSPI_DCTAR_TRSZ(0b111) | /* transfer size = 8 bit */
|
||||
MCF_DSPI_DCTAR_PCSSCK(0b01) | /* 3 clock DSPICS to DSPISCK delay prescaler */
|
||||
MCF_DSPI_DCTAR_PASC_3CLK | /* 3 clock DSPISCK to DSPICS negation prescaler */
|
||||
MCF_DSPI_DCTAR_PDT_3CLK | /* 3 clock delay between DSPICS assertions prescaler */
|
||||
MCF_DSPI_DCTAR_PBR_3CLK | /* 3 clock prescaler */
|
||||
MCF_DSPI_DCTAR_ASC(0b1001) | /* 1024 */
|
||||
MCF_DSPI_DCTAR_DT(0b1001) | /* 1024 */
|
||||
MCF_DSPI_DCTAR_BR(0b0111);
|
||||
/* 0x38558897 */
|
||||
|
||||
MCF_DSPI_DSR = 0xffffffff; /* clear DSPI status register */
|
||||
wait(1000); /* wait 1ms */
|
||||
|
||||
MCF_DSPI_DMCR = DSPI_DMCR_CONF | MCF_DSPI_DMCR_CSCK; /* enable continuous serial comms clock */
|
||||
/* 0xc00d3c00 */
|
||||
|
||||
wait(10000);
|
||||
|
||||
MCF_DSPI_DMCR = DSPI_DMCR_CONF;
|
||||
|
||||
ret = spi_command(MCF_DSPI_DTFR_EOQ | MCF_DSPI_DTFR_CS5 | 0x00FF);
|
||||
for (i = 1; i < 10; i++)
|
||||
{
|
||||
rb = spi_send_byte(0xff);
|
||||
}
|
||||
|
||||
MCF_DSPI_DMCR = DSPI_DMCR_CONF | MCF_DSPI_DMCR_CSIS5; /* CS5 inactive */
|
||||
/* 0x802d3c00; */
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
ret = spi_command(MCF_DSPI_DTFR_EOQ | MCF_DSPI_DTFR_CS5);
|
||||
}
|
||||
|
||||
MCF_DSPI_DMCR = DSPI_DMCR_CONF;
|
||||
ret = spi_command(MCF_DSPI_DTFR_EOQ | MCF_DSPI_DTFR_CS5 | 0x00FF);
|
||||
rb = spi_send_byte(0xff);
|
||||
|
||||
MCF_DSPI_DMCR = DSPI_DMCR_CONF;
|
||||
|
||||
wait(10000);
|
||||
|
||||
xprintf("finished\r\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user