version 1.4, 2007/12/21 17:40:29 |
version 1.5, 2007/12/24 15:46:40 |
|
|
#include <libkern/printf.h> |
#include <libkern/printf.h> |
#include <arch/sam7s64/dev/at91sam7.h> |
#include <arch/sam7s64/dev/at91sam7.h> |
|
|
|
/* #define SASPI_DEBUG */ |
|
|
|
#ifdef SASPI_DEBUG |
|
#define DPRINTF(x...) do { printf(x); } while (0) |
|
#else |
|
#define DPRINTF(x...) { } |
|
#endif |
|
|
/* |
/* |
* SPI driver. |
* SPI driver. |
*/ |
*/ |
|
|
*/ |
*/ |
|
|
/* |
/* |
* Disassociate SPI chip select, clock and data lines from PIO. |
* Disassociate SPI clock and data lines from PIO. |
* |
* |
* PA11 - NPCS0 |
* PA11 - NPCS0 (we will drive this as gpio pin) |
* PA12 - MISO |
* PA12 - MISO |
* PA13 - MOSI |
* PA13 - MOSI |
* PA14 - SPCK |
* PA14 - SPCK |
*/ |
*/ |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PDR, 1 << 11 | 1 << 12 | 1 << 13 | 1 << 14); |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PDR, 1 << 12 | 1 << 13 | 1 << 14); |
|
|
/* assign pins to Peripheral A */ |
/* assign pins to Peripheral A */ |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_ASR, 1 << 11 | 1 << 12 | 1 << 13 | 1 << 14); |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_ASR, 1 << 12 | 1 << 13 | 1 << 14); |
|
|
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_BSR, 0); |
/* |
|
* Configure NCPS0 (CS): |
|
* Enable PIO; Set high; Enable output. |
|
*/ |
|
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PER, 1 << 11); |
|
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_SODR, 1 << 11); |
|
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_OER, 1 << 11); |
|
|
|
|
/* reset and enable SPI */ |
/* reset and enable SPI */ |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CR, AT91C_SPI_SPIEN | AT91C_SPI_SWRST); |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CR, AT91C_SPI_SPIEN | AT91C_SPI_SWRST); |
/* XXX just to be sure */ |
/* XXX just to be sure */ |
|
|
|
|
/* set SPI mode to master; disable decoding of Chip Select; PCS 1110 (using fixed CS line) */ |
/* set SPI mode to master; disable decoding of Chip Select; PCS 1110 (using fixed CS line) */ |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_MR, AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | 0x0e << 16); /* XXX 15|16 */ |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_MR, AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | 0x0e << 16); /* XXX 15|16 */ |
// bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_MR, 0xe0011); /* XXX 15|16 */ |
|
|
|
/* |
/* |
* Configure Chip Select Register no. 0 (so no offset from SPI_CSR). |
* Configure Chip Select Register no. 0 (so no offset from SPI_CSR). |
|
|
* 8 bits per transfer; |
* 8 bits per transfer; |
* XXX SCBR=4a; |
* XXX SCBR=4a; |
*/ |
*/ |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CSR, AT91C_SPI_NCPHA | 0x4a00); |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CSR, AT91C_SPI_NCPHA | 0x4a00 ); |
|
|
/* enable PDC transfers to/from SPI */ |
/* enable PDC transfers to/from SPI */ |
// bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PDC_PTCR, AT91C_PDC_TXTEN | AT91C_PDC_RXTEN); |
|
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_PTCR, AT91C_PDC_TXTEN | AT91C_PDC_RXTEN); |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_PTCR, AT91C_PDC_TXTEN | AT91C_PDC_RXTEN); |
|
|
} |
} |
|
|
; |
; |
|
|
/* okay, send our byte */ |
/* okay, send our byte */ |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_TDR, 0x0000ffff & data); |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_TDR, 0x000000ff & data); |
|
DPRINTF("saspi_transmit: tx byte 0x%x\n", 0x000000ff & data); |
|
|
/* wait while Receive Register is full and read it */ |
/* wait while Receive Register is full and read it */ |
while(((bus_read_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_SR)) & AT91C_SPI_RDRF) == 0) |
while(((bus_read_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_SR)) & AT91C_SPI_RDRF) == 0) |
; |
; |
return( bus_read_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_RDR) & 0x0000ffff ); |
data = bus_read_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_RDR) & 0x000000ff; |
|
DPRINTF("saspi_transmit: rx byte 0x%x\n", data); |
|
|
|
return( data ); |
} |
} |
|
|
|
|
void |
void |
saspi_cs_low(void *selfdd) |
saspi_cs_high(void *selfdd) |
{ |
{ |
struct saspi_dd *ddp = selfdd; |
struct saspi_dd *ddp = selfdd; |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_CODR, 1 << 11); |
|
|
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_SODR, 1 << 11); |
} |
} |
|
|
|
|
void |
void |
saspi_cs_high(void *selfdd) |
saspi_cs_low(void *selfdd) |
{ |
{ |
struct saspi_dd *ddp = selfdd; |
struct saspi_dd *ddp = selfdd; |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_SODR, 1 << 11); |
|
|
|
|
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_CODR, 1 << 11); |
} |
} |
|
|