RT-Thread/AT91SAM7X256的一些资源

发布于 2009-03-23 13:40:39
RT-Thread 0.2.4版本中包括AT91SAM7X256的realview mdk移植,gcc的移植还没来得及试,争取0.3.0的时候把它也加进去。

以下是用来跑RT-Thread/AT91SAM7X256 0.2.4开发板相关的一些资源:
下载附件[AT91SAM7X256部分.pdf]
下载附件[.pdf]
下载附件[MII接口部分.pdf]

查看更多

关注者
0
被浏览
3.4k
2 个回答
bernard
bernard 2009-03-23
MMC卡相关的代码,还没来得及试,这部分代码似乎和这块板子比较类似:

/*-----------------------------------------------------------------------*/
/* MMC/SDC (in SPI mode) control module */
/*-----------------------------------------------------------------------*/

#include

#include "diskio.h"
#include "Board.h"

extern void AT91F_DBGU_Printk( char *buffer);

#define CARD_WP_PIN AT91C_PIO_PA16
#define CARD_INS_PIN AT91C_PIO_PA15
#define CARD_PWR_PIN AT91C_PIO_PA12
static AT91PS_PIO pPIOA = AT91C_BASE_PIOA;
static AT91PS_SPI pSPI = AT91C_BASE_SPI0;

#define CARD_SELECT_PIN AT91C_PA13_SPI0_NPCS1
#define SPI_CSR_NUM 0

#define SPI_SCBR_MIN 2


/* MMC/SD command (in SPI) */
#define CMD0 (0x40+0) /* GO_IDLE_STATE */
#define CMD1 (0x40+1) /* SEND_OP_COND */
#define CMD9 (0x40+9) /* SEND_CSD */
#define CMD10 (0x40+10) /* SEND_CID */
#define CMD12 (0x40+12) /* STOP_TRANSMISSION */
#define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */
#define CMD18 (0x40+18) /* READ_MULTIPLE_BLOCK */
#define CMD24 (0x40+24) /* WRITE_BLOCK */
#define CMD25 (0x40+25) /* WRITE_MULTIPLE_BLOCK */
#define CMD58 (0x40+58) /* READ_OCR */


/* Control signals (Platform dependent) */
#define SELECT() (pPIOA->PIO_CODR = CARD_SELECT_PIN) /* MMC CS = L */
#define DESELECT() (pPIOA->PIO_SODR = CARD_SELECT_PIN) /* MMC CS = H */

#define SOCKWP CARD_WP_PIN /* Write protect switch (PB5) */
#define SOCKINS CARD_INS_PIN /* Card detect switch (PB4) */

// #define POWER_ON() PORTE &= ~0x80 /* Socke power (PE7) */
// #define POWER_OFF() PORTE |= 0x80

//给MMC上下电
#define POWER_ON() (pPIOA->PIO_CODR = CARD_PWR_PIN)
#define POWER_OFF() (pPIOA->PIO_SODR = CARD_PWR_PIN)

static volatile
DSTATUS Stat = STA_NOINIT; /* Disk status */

// AT91: thru systime
static volatile
BYTE Timer; /* 100Hz decrement timer */



/*-----------------------------------------------------------------------*/
/* Module Private Functions */


#if 0
/*--------------------------------*/
/* Transmit a byte to MMC via SPI */
/* (Platform dependent) */

#define xmit_spi(dat) SPDR=(dat); loop_until_bit_is_set(SPSR,SPIF)

/*---------------------------------*/
/* Receive a byte from MMC via SPI */
/* (Platform dependent) */

static
BYTE rcvr_spi()
{
SPDR = 0xFF;
loop_until_bit_is_set(SPSR, SPIF);
return SPDR;
}

/* Alternative macro to receive data fast */
#define rcvr_spi_m(dst) SPDR=0xFF; loop_until_bit_is_set(SPSR,SPIF); *(dst)=SPDR

#endif


//*****************************************************
//设置SPI速度 ,串口波特率 SPCK BAUD=MCK/SCBR
static
void AT91_spiSetSpeed(BYTE speed)
{
DWORD reg;

if ( speed < SPI_SCBR_MIN ) speed = SPI_SCBR_MIN;
if ( speed > 1 ) speed &= 0xFE;

reg = pSPI->SPI_CSR[SPI_CSR_NUM];
reg = ( reg & ~(AT91C_SPI_SCBR) ) | ( (DWORD)speed << 8 );
pSPI->SPI_CSR[SPI_CSR_NUM] = reg;
}

static
BYTE AT91_spi(BYTE outgoing)
{
BYTE incoming;

while( !( pSPI->SPI_SR & AT91C_SPI_TDRE ) ); // transfer compl. wait
pSPI->SPI_TDR = (WORD)( outgoing );
while( !( pSPI->SPI_SR & AT91C_SPI_RDRF ) ); // wait for char
incoming = (BYTE)( pSPI->SPI_RDR );

return incoming;
}

/*--------------------------------*/
/* Transmit a byte to MMC via SPI */
/* (Platform dependent) */

static
void xmit_spi(BYTE dat)
{
AT91_spi(dat);
}

/*---------------------------------*/
/* Receive a byte from MMC via SPI */
/* (Platform dependent) */

static
BYTE rcvr_spi(void)
{
return AT91_spi(0xff);
}

/* Alternative "macro" (not at AT91 so far) to receive data fast */
static
void rcvr_spi_m(BYTE *dst)
{
*dst = rcvr_spi();
}


/*---------------------*/
/* Wait for card ready */

static
BYTE wait_ready ()
{
BYTE res;

Timer = 50; /* Wait for ready in timeout of 500ms */
rcvr_spi();
do
res = rcvr_spi();
while ((res != 0xFF) && Timer);
return res;
}

/*--------------------------------*/
/* Receive a data packet from MMC */

extern
BOOL rcvr_datablock (
BYTE *buff, /* Data buffer to store received data */
BYTE wc /* Word count (0 means 256 words) */
)
{
BYTE token;

Timer = 10;
do { /* Wait for data packet in timeout of 100ms */
token = rcvr_spi();
} while ((token == 0xFF) && Timer );
if(token != 0xFE) return FALSE; /* If not valid data token, retutn with error */

do { /* Receive the data block into buffer */
rcvr_spi_m(buff++);
rcvr_spi_m(buff++);
} while (--wc);
rcvr_spi(); /* Discard CRC */
rcvr_spi();

return TRUE; /* Return with success */
}



/*---------------------------*/
/* Send a data packet to MMC */

#ifndef _READONLY
static
BOOL xmit_datablock (
const BYTE *buff, /* 512 byte data block to be transmitted */
BYTE token /* Data/Stop token */
)
{
BYTE resp, wc = 0;


if (wait_ready() != 0xFF) return FALSE;

xmit_spi(token); /* Xmit data token */
if (token != 0xFD) { /* Is data token */
do { /* Xmit the 512 byte data block to MMC */
xmit_spi(*buff++);
xmit_spi(*buff++);
} while (--wc);
xmit_spi(0xFF); /* CRC (Dummy) */
xmit_spi(0xFF);
resp = rcvr_spi(); /* Reveive data response */
if ((resp & 0x1F) != 0x05) /* If not accepted, return with error */
return FALSE;
}

return TRUE;
}
#endif


/*------------------------------*/
/* Send a command packet to MMC */

extern
BYTE send_cmd (
BYTE cmd, /* Command byte */
DWORD arg /* Argument */
)
{
BYTE n, res;


if (wait_ready() != 0xFF) return 0xFF;

/* Send command packet */
xmit_spi(cmd); /* Command */
xmit_spi((BYTE)(arg >> 24)); /* Argument[31..24] */
xmit_spi((BYTE)(arg >> 16)); /* Argument[23..16] */
xmit_spi((BYTE)(arg >> 8)); /* Argument[15..8] */
xmit_spi((BYTE)arg); /* Argument[7..0] */
xmit_spi(0x95); /* CRC (valid for only CMD0) */

/* Receive command response */
if (cmd == CMD12) rcvr_spi(); /* Skip a stuff byte when stop reading */
n = 10; /* Wait for a valid response in timeout of 10 attempts */
do
res = rcvr_spi();
while ((res & 0x80) && --n);

return res; /* Return with the response value */
}




/*-----------------------------------------------------------------------*/
/* Public Functions */


/*-----------------------*/
/* Initialize Disk Drive */
/* (Platform dependent) */

extern DSTATUS disk_initialize ()
{
BYTE n;


AT91PS_PMC pPMC = AT91C_BASE_PMC;

//mmc 上电
// set chip-select as output high (unselect card)

pPIOA->PIO_PER = CARD_PWR_PIN; // enable GPIO of CS-pin
pPIOA->PIO_CODR = CARD_PWR_PIN; // set high
pPIOA->PIO_OER = CARD_PWR_PIN; // output enable

OSTimeDly(1000); //延时30ms
//for (Timer = 3; Timer; ); /* Wait for 30ms */
// for ( l = 3000; l;l-- );
/* MMC socket-switch init */
// disable internal Pull-Ups if needed
//pPIOA->PIO_PPUDR = CARD_INS_PIN | CARD_WP_PIN;
// configure as inputs
//pPIOA->PIO_ODR = CARD_INS_PIN | CARD_WP_PIN;
// enable control of pins by PIO
//pPIOA->PIO_PER = CARD_INS_PIN | CARD_WP_PIN;

// disable PIO from controlling MOSI, MISO, SCK (=hand over to SPI)
// keep CS untouched - used as GPIO pin during init
pPIOA->PIO_PDR = AT91C_PA16_SPI0_MISO | AT91C_PA17_SPI0_MOSI | AT91C_PA18_SPI0_SPCK; // | NCPS_PDR_BIT;
// set pin-functions in PIO Controller
pPIOA->PIO_ASR = AT91C_PA16_SPI0_MISO | AT91C_PA17_SPI0_MOSI | AT91C_PA18_SPI0_SPCK; /// not here: | NCPS_ASR_BIT;

// set chip-select as output high (unselect card)
pPIOA->PIO_PER = CARD_SELECT_PIN; // enable GPIO of CS-pin
pPIOA->PIO_SODR = CARD_SELECT_PIN; // set high
pPIOA->PIO_OER = CARD_SELECT_PIN; // output enable

// enable peripheral clock for SPI ( PID Bit 5 )
pPMC->PMC_PCER = ( (DWORD) 1 << AT91C_ID_SPI0 ); // n.b. IDs are just bit-numbers

// SPI enable and reset
pSPI->SPI_CR = AT91C_SPI_SPIEN | AT91C_SPI_SWRST;

// SPI mode: master, FDIV=0, fault detection disabled
pSPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS;

// set chip-select-register
// 8 bits per transfer, CPOL=1, ClockPhase=0, DLYBCT = 0
pSPI->SPI_CSR[SPI_CSR_NUM] = AT91C_SPI_CPOL | AT91C_SPI_BITS_8;

// slow during init
AT91_spiSetSpeed(0xFE);

// enable
pSPI->SPI_CR = AT91C_SPI_SPIEN;

Stat |= STA_NOINIT;
if (!(Stat & STA_NODISK)) {
n = 10; /* Dummy clock */
do
rcvr_spi();
while (--n);

AT91F_DBGU_Printk("SPI prepare done
"); /////////////////////////////////////////

SELECT(); /* CS = L */
if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
Timer = 100; /* Wait for card ready in timeout of 1 sec */
while (Timer && send_cmd(CMD1, 0));
if (Timer) Stat &= ~STA_NOINIT; /* When device goes ready, clear STA_NOINIT */
}

//AT91F_DBGU_Printk("CMD0 done timer = %i
", Timer);

DESELECT(); /* CS = H */
rcvr_spi(); /* Idle (Release DO) */

AT91_spiSetSpeed(SPI_SCBR_MIN);
}

if (Stat & STA_NOINIT)
disk_shutdown();
return Stat;
}

/*-----------------------*/
/* Shutdown */
/* (Platform dependent) */

#if 0
DSTATUS disk_shutdown ()
{
SPCR = 0; /* Disable SPI function */
DDRB = 0b11000000; /* Disable drivers */
PORTB = 0b10110000;
POWER_OFF(); /* Socket power OFF */

Stat |= STA_NOINIT;

return Stat;
}
#endif

/*
断电拔卡
*/

DSTATUS disk_shutdown ()
{
POWER_OFF(); /* Socket power OFF */
Stat |= STA_NOINIT;
return 0;
}


/*--------------------*/
/* Return Disk Status */

DSTATUS disk_status ()
{
return Stat;
}



/*----------------*/
/* Read Sector(s) */

extern DRESULT disk_read (
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector number (LBA) */
BYTE count /* Sector count (1..255) */
)
{
if (Stat & STA_NOINIT) return RES_NOTRDY;
if (!count) return RES_PARERR;

sector *= 512; /* LBA --> byte address */

SELECT(); /* CS = L */

if (count == 1) { /* Single block read */
if ((send_cmd(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */
&& rcvr_datablock(buff, (BYTE)(512/2)))
count = 0;
}
else { /* Multiple block read */
if (send_cmd(CMD18, sector) == 0) { /* READ_MULTIPLE_BLOCK */
do {
if (!rcvr_datablock(buff, (BYTE)(512/2))) break;
buff += 512;
} while (--count);
send_cmd(CMD12, 0); /* STOP_TRANSMISSION */
}
}

DESELECT(); /* CS = H */
rcvr_spi(); /* Idle (Release DO) */

return count ? RES_ERROR : RES_OK;
}



/*-----------------*/
/* Write Sector(s) */

#ifndef _READONLY
extern DRESULT disk_write (
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector number (LBA) */
BYTE count /* Sector count (1..255) */
)
{
if (Stat & STA_NOINIT) return RES_NOTRDY;
if (Stat & STA_PROTECT) return RES_WRPRT;
if (!count) return RES_PARERR;
sector *= 512; /* LBA --> byte address */

SELECT(); /* CS = L */

if (count == 1) { /* Single block write */
if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */
&& xmit_datablock(buff, 0xFE))
count = 0;
}
else { /* Multiple block write */
if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */
do {
if (!xmit_datablock(buff, 0xFC)) break;
buff += 512;
} while (--count);
if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */
count = 1;
}
}

DESELECT(); /* CS = H */
rcvr_spi(); /* Idle (Release DO) */

return count ? RES_ERROR : RES_OK;
}
#endif



/*--------------------------*/
/* Miscellaneous Functions */

DRESULT disk_ioctl (
BYTE ctrl, /* Control code */
void *buff /* Buffer to send/receive data block */
)
{
DRESULT res;
BYTE n, csd[16], *ptr = buff;
WORD csm, csize;


if (Stat & STA_NOINIT) return RES_NOTRDY;

SELECT(); /* CS = L */

res = RES_ERROR;
switch (ctrl) {
case GET_SECTORS : /* Get number of sectors on the disk (unsigned long) */
if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16/2)) {
/* Calculate disk size */
csm = 1 << (((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2);
csize = ((WORD)(csd[8] & 3) >> 6) + (WORD)(csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
#ifdef _BYTE_ACC
ST_DWORD(ptr, (DWORD)csize * csm);
#else
*(DWORD*)ptr = (DWORD)csize * csm;
#endif
res = RES_OK;
}
break;

case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */
if ((send_cmd(CMD9, 0) == 0) /* READ_CSD */
&& rcvr_datablock(ptr, 16/2))
res = RES_OK;
break;

case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */
if ((send_cmd(CMD10, 0) == 0) /* READ_CID */
&& rcvr_datablock(ptr, 16/2))
res = RES_OK;
break;

case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */
if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */
for (n = 0; n < 4; n++)
*ptr++ = rcvr_spi();
res = RES_OK;
}
break;

default:
res = RES_PARERR;
}

DESELECT(); /* CS = H */
rcvr_spi(); /* Idle (Release DO) */

return res;
}



/*---------------------------------------*/
/* Device timer interrupt procedure */
/* This must be called in period of 10ms */
/* (Platform dependent) */


void disk_timerproc ()
{
static BYTE pv;
BYTE n, s;
n = Timer; /* 100Hz decrement timer */
if (n) Timer = --n;

// n = pv;
// pv = SOCKPORT & (SOCKWP | SOCKINS); /* Sapmle socket switch */

pv = pPIOA->PIO_PDSR;

if (n == pv) { /* Have contacts stabled? */
s = Stat;

if (pv & SOCKWP) /* WP is H (write protected) */
s |= STA_PROTECT;
else /* WP is L (write enabled) */
s &= ~STA_PROTECT;

if (pv & SOCKINS) /* INS = H (Socket empty) */
s |= (STA_NODISK | STA_NOINIT);
else /* INS = L (Card inserted) */
s &= ~STA_NODISK;

Stat = s;
}
}


/*---------------------------------------------------------*/
/* User Provided Timer Function for FatFs module */
/*---------------------------------------------------------*/
/* This is a real time clock service to be called from */
/* FatFs module. Any valid time must be returned even if */
/* the system does not support a real time clock. */


DWORD get_fattime ()
{

return ((2008UL-1980) << 25) // Year = 2006
| (7UL << 21) // Month = Feb
| (8UL << 16) // Day = 9
| (22U << 11) // Hour = 22
| (30U << 5) // Min = 30
| (0U >> 1) // Sec = 0
;

}

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览