Код
static BYTE rcvr_spi()//Чтение
{
BYTE dat;
AT91PS_SPI pSPI = AT91C_BASE_SPI0;
while( !( pSPI->SPI_SR & AT91C_SPI_TDRE ) ); // transfer compl. wait
pSPI->SPI_TDR = 0xFF;
while( !( pSPI->SPI_SR & AT91C_SPI_RDRF ) ); // wait for char
dat = (BYTE)( pSPI->SPI_RDR );
return dat;
}
static BYTE xmit_spi(BYTE dat)//Запись
{
AT91PS_SPI pSPI = AT91C_BASE_SPI0;
while( !( pSPI->SPI_SR & AT91C_SPI_TDRE ) ); // transfer compl. wait
pSPI->SPI_TDR = dat;
while( !( pSPI->SPI_SR & AT91C_SPI_RDRF ) ); // wait for char
return (BYTE)( pSPI->SPI_RDR ); // it's important to read RDR here!
}
static void if_spiSetSpeed(unsigned char speed)
{
unsigned long reg;
AT91PS_SPI pSPI = AT91C_BASE_SPI0;
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) ) | ( (unsigned long)speed << 8 );
pSPI->SPI_CSR[SPI_CSR_NUM] = reg;
}
void pause(void)
{
int i;
for(i=1; i<1000; i++);
}
static void init_spi()
{
BYTE i;
AT91PS_SPI pSPI = AT91C_BASE_SPI0;
AT91PS_PIO pPIOA = AT91C_BASE_PIOA;
AT91PS_PMC pPMC = AT91C_BASE_PMC;
// 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;
pPIOA->PIO_BSR = NPCS_BSR_BIT;
// set chip-select as output high (unselect card)
pPIOA->PIO_PER = NPCS_BSR_BIT; // enable PIO of CS-pin
pPIOA->PIO_SODR = NPCS_BSR_BIT; // set
pPIOA->PIO_OER = NPCS_BSR_BIT; // output
// enable peripheral clock for SPI ( PID Bit 5 )
pPMC->PMC_PCER = ( (unsigned long) 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, fixed periph. sel., FDIV=0, fault detection disabled
pSPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_PS_FIXED | AT91C_SPI_MODFDIS;
// set PCS for fixed select
pSPI->SPI_MR &= 0xFFF0FFFF; // clear old PCS - redundant (AT91lib)
pSPI->SPI_MR |= ( (SPI_MR_PCS<<8) & AT91C_SPI_PCS ); // set PCS
// set chip-select-register
// 8 bits per transfer, CPOL=0, ClockPhase=0, DLYBCT = 0
//pSPI->SPI_CSR[SPI_CSR_NUM] = AT91C_SPI_CPOL | AT91C_SPI_BITS_8;
pSPI->SPI_CSR[SPI_CSR_NUM] = AT91C_SPI_NCPHA | AT91C_SPI_BITS_16; // ok
// slow during init
if_spiSetSpeed(0xFE);
// enable
pSPI->SPI_CR = AT91C_SPI_SPIEN;
/* Send 20 spi commands with card not selected */
//for(i=0;i<21;i++)
//xmit_spi(0xA);
/* enable automatic chip-select */
pPIOA->PIO_ODR = NPCS_BSR_BIT; // input
pPIOA->PIO_CODR = NPCS_BSR_BIT; // clear
// disable PIO from controlling the CS pin (=hand over to SPI)
pPIOA->PIO_PDR = NCPS_PDR_BIT;
// set pin-functions in PIO Controller
pPIOA->PIO_ASR = NCPS_ASR_BIT;
pPIOA->PIO_BSR = NPCS_BSR_BIT;
}
init_spi();
while (1)
{
xmit_spi(0xAAAA);//Запись SPI посылаем 2 байта
}
{
BYTE dat;
AT91PS_SPI pSPI = AT91C_BASE_SPI0;
while( !( pSPI->SPI_SR & AT91C_SPI_TDRE ) ); // transfer compl. wait
pSPI->SPI_TDR = 0xFF;
while( !( pSPI->SPI_SR & AT91C_SPI_RDRF ) ); // wait for char
dat = (BYTE)( pSPI->SPI_RDR );
return dat;
}
static BYTE xmit_spi(BYTE dat)//Запись
{
AT91PS_SPI pSPI = AT91C_BASE_SPI0;
while( !( pSPI->SPI_SR & AT91C_SPI_TDRE ) ); // transfer compl. wait
pSPI->SPI_TDR = dat;
while( !( pSPI->SPI_SR & AT91C_SPI_RDRF ) ); // wait for char
return (BYTE)( pSPI->SPI_RDR ); // it's important to read RDR here!
}
static void if_spiSetSpeed(unsigned char speed)
{
unsigned long reg;
AT91PS_SPI pSPI = AT91C_BASE_SPI0;
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) ) | ( (unsigned long)speed << 8 );
pSPI->SPI_CSR[SPI_CSR_NUM] = reg;
}
void pause(void)
{
int i;
for(i=1; i<1000; i++);
}
static void init_spi()
{
BYTE i;
AT91PS_SPI pSPI = AT91C_BASE_SPI0;
AT91PS_PIO pPIOA = AT91C_BASE_PIOA;
AT91PS_PMC pPMC = AT91C_BASE_PMC;
// 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;
pPIOA->PIO_BSR = NPCS_BSR_BIT;
// set chip-select as output high (unselect card)
pPIOA->PIO_PER = NPCS_BSR_BIT; // enable PIO of CS-pin
pPIOA->PIO_SODR = NPCS_BSR_BIT; // set
pPIOA->PIO_OER = NPCS_BSR_BIT; // output
// enable peripheral clock for SPI ( PID Bit 5 )
pPMC->PMC_PCER = ( (unsigned long) 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, fixed periph. sel., FDIV=0, fault detection disabled
pSPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_PS_FIXED | AT91C_SPI_MODFDIS;
// set PCS for fixed select
pSPI->SPI_MR &= 0xFFF0FFFF; // clear old PCS - redundant (AT91lib)
pSPI->SPI_MR |= ( (SPI_MR_PCS<<8) & AT91C_SPI_PCS ); // set PCS
// set chip-select-register
// 8 bits per transfer, CPOL=0, ClockPhase=0, DLYBCT = 0
//pSPI->SPI_CSR[SPI_CSR_NUM] = AT91C_SPI_CPOL | AT91C_SPI_BITS_8;
pSPI->SPI_CSR[SPI_CSR_NUM] = AT91C_SPI_NCPHA | AT91C_SPI_BITS_16; // ok
// slow during init
if_spiSetSpeed(0xFE);
// enable
pSPI->SPI_CR = AT91C_SPI_SPIEN;
/* Send 20 spi commands with card not selected */
//for(i=0;i<21;i++)
//xmit_spi(0xA);
/* enable automatic chip-select */
pPIOA->PIO_ODR = NPCS_BSR_BIT; // input
pPIOA->PIO_CODR = NPCS_BSR_BIT; // clear
// disable PIO from controlling the CS pin (=hand over to SPI)
pPIOA->PIO_PDR = NCPS_PDR_BIT;
// set pin-functions in PIO Controller
pPIOA->PIO_ASR = NCPS_ASR_BIT;
pPIOA->PIO_BSR = NPCS_BSR_BIT;
}
init_spi();
while (1)
{
xmit_spi(0xAAAA);//Запись SPI посылаем 2 байта
}
Не могу выставить в SPI 16 битовый режим...
В такой конф у меня клок 16 бит - а данных всё равно посылает только 8 бит...! Народ подскажите - как устагновить 16 битный режим ?