У Atmel контроллер SPI везде одинаковый да? (это для 9200),
CODE
static int at45_cs;
static void
at45_transfer( void *cmd_ptr,
int cmd_len,
void *dat_ptr,
int dat_len)
{
struct spi_tblk blks[2];
int blk_n = 1;
blks[0].rx = cmd_ptr;
blks[0].tx = cmd_ptr;
blks[0].len = cmd_len;
if (dat_len != 0) {
blks[1].rx = dat_ptr;
blks[1].tx = dat_ptr;
blks[1].len = dat_len;
++blk_n;
}
spi_select(at45_cs);
spi_transfer(blks, blk_n);
}
static int
at45_status()
{
uint8_t req[2];
req[0] = 0xd7;
at45_transfer(req, 2, 0, 0);
return req[1];
}
static void
at45_wait_rdy()
{
while (!(at45_status() & 0x80)) ;
}
int at45_init(int cs)
{
uint8_t req[4];
at45_cs = cs;
spi_mode(at45_cs, SPI_MODE_0, 8, 5, NULL);
req[0] = 0x9f;
at45_transfer(req, 4, 0, 0);
serial_printk(AT45 "Manufacturer ID: %b\n", req[1]);
serial_printk(AT45 "Density Code: %b\n", req[2]);
serial_printk(AT45 "Product Version: %b\n", req[3]);
if (req[1] != 0x1f || req[2] != 0x25) {
serial_printk(AT45 "Unknown Device\n");
return -1;
}
serial_printk(AT45 "Status Register: %b\n", at45_status());
return 0;
}
#define SPI_CPOL_0 (1 << 0)
#define SPI_CPOL_1 0
#define SPI_NCPHA_0 (1 << 1)
#define SPI_NCPHA_1 0
#define SPI_MODE_0 (SPI_CPOL_0 | SPI_NCPHA_1)
#define SPI_MODE_1 (SPI_CPOL_0 | SPI_NCPHA_0)
#define SPI_MODE_2 (SPI_CPOL_1 | SPI_NCPHA_1)
#define SPI_MODE_3 (SPI_CPOL_1 | SPI_NCPHA_0)
struct spi_tblk {
void *rx;
const void *tx;
int len;
};
static int csdec[] = {
0x000e0000,
0x000d0000,
0x000b0000,
0x00070000,
};
void spi_init()
{
uint32_t tmp32;
tmp32 = ( AT91C_PA0_MISO |
AT91C_PA1_MOSI |
AT91C_PA2_SPCK |
AT91C_PA3_NPCS0 |
AT91C_PA4_NPCS1 |
AT91C_PA5_NPCS2 |
AT91C_PA6_NPCS3 );
AT91C_BASE_PIOA->PIO_ASR = tmp32;
AT91C_BASE_PIOA->PIO_PDR = tmp32;
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI);
AT91C_BASE_SPI->SPI_IDR = 0xffffffff;
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
AT91C_BASE_SPI->SPI_MR = (AT91C_SPI_MSTR |
AT91C_SPI_MODFDIS | AT91C_SPI_PCS | (0x1f << 24));
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
}
void spi_mode(int cs, int pol, int bits, int baud, int dely)
{
AT91C_BASE_SPI->SPI_CSR[cs] = (pol | ((bits - 8) << 4) | (baud << 8) |
((dely) << 24) | ((dely >> 1) << 16));
}
void spi_select(int cs)
{
uint32_t tmp32 = AT91C_BASE_SPI->SPI_MR;
AT91C_BASE_SPI->SPI_MR = (tmp32 & ~(0x000f0000)) | csdec[cs];
}
void spi_transfer(struct spi_tblk *blk, int n)
{
AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS;
AT91C_BASE_SPI->SPI_TPR = (uint32_t) blk[0].tx;
AT91C_BASE_SPI->SPI_TCR = blk[0].len;
AT91C_BASE_SPI->SPI_RPR = (uint32_t) blk[0].rx;
AT91C_BASE_SPI->SPI_RCR = blk[0].len;
if (n > 1) {
AT91C_BASE_SPI->SPI_TNPR = (uint32_t) blk[1].tx;
AT91C_BASE_SPI->SPI_TNCR = blk[1].len;
AT91C_BASE_SPI->SPI_RNPR = (uint32_t) blk[1].rx;
AT91C_BASE_SPI->SPI_RNCR = blk[1].len;
}
AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTEN;
while (!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RXBUFF)) ;
AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS;
}