собственно вот.
имеется несколько регистров в ПЛИС, запись в которые производится по 16-битному SPI по конкретному ЧипСелекту, тобишь NPCS.
вот функция настройки самого SPI'я:
CODE
void ConfigureSPI(unsigned int Frequency, unsigned short DelayBefore, unsigned short DelayBetwen)//, void (*handler)(void))
{
// static const Pin SPIpins[] = {PIN_SPI_MISO, PIN_SPI_MOSI, PIN_SPI_SPCK, PIN_SPI_NPCS0, PIN_SPI_NPCS1, PIN_SPI_NPCS2, PIN_SPI_NPCS3};
PIO_Configure(SPIpins, PIO_LISTSIZE(SPIpins));
if(!PMC_IsPeriphEnabled(AT91C_ID_SPI)) PMC_EnablePeripheral(AT91C_ID_SPI); // Enable CLK for SPI
AT91C_BASE_SPI->SPI_IDR = 0xFFFFFFFF; // Disable Interrupts
AT91C_BASE_PIOA->PIO_PDR |= PIN_SPCK|PIN_MISO|PIN_MOSI|PINS_NPCSX;
AT91C_BASE_PIOA->PIO_ASR |= PIN_NPCS0|PIN_NPCS1;
AT91C_BASE_PIOA->PIO_BSR |= PIN_NPCS2|PIN_NPCS3;
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS; // Disable SPI interface
// Execute a software reset of the SPI twice
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
// Configure ISR for SPI
AT91C_BASE_SPI->SPI_IDR = 0xFFFFFFFF; // Disable Interrupts (second)
AIC_DisableIT(AT91C_ID_SPI); // Disable configured Interrupts
// Cоnfigure SPI port
AT91C_BASE_SPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_PCSDEC | AT91C_SPI_PS_VARIABLE;
AT91C_BASE_SPI->SPI_CSR[0] = SPI_SCBR(Frequency,BOARD_MCK)
// | SPI_DLYBS(Frequency,BOARD_MCK,DelayBefore)
// | SPI_DLYBCT(Frequency,BOARD_MCK,DelayBetwen)
| AT91C_SPI_BITS_16
| AT91C_SPI_CPOL;// | AT91C_SPI_CSAAT;// | AT91C_SPI_NCPHA; // ;
AT91C_BASE_SPI->SPI_CSR[1] = SPI_SCBR(Frequency,BOARD_MCK)
// | SPI_DLYBS(Frequency,BOARD_MCK,DelayBefore)
// | SPI_DLYBCT(Frequency,BOARD_MCK,DelayBetwen)
| AT91C_SPI_BITS_16
| AT91C_SPI_CPOL;// | AT91C_SPI_CSAAT;// | AT91C_SPI_NCPHA; // ;
AT91C_BASE_SPI->SPI_CSR[2] = SPI_SCBR(Frequency,BOARD_MCK)
// | SPI_DLYBS(Frequency,BOARD_MCK,DelayBefore)
// | SPI_DLYBCT(Frequency,BOARD_MCK,DelayBetwen)
| AT91C_SPI_BITS_16
| AT91C_SPI_CPOL;// | AT91C_SPI_CSAAT;// | AT91C_SPI_NCPHA; // ;
AT91C_BASE_SPI->SPI_CSR[3] = SPI_SCBR(Frequency,BOARD_MCK)
// | SPI_DLYBS(Frequency,BOARD_MCK,DelayBefore)
// | SPI_DLYBCT(Frequency,BOARD_MCK,DelayBetwen)
| AT91C_SPI_BITS_16
| AT91C_SPI_CPOL;// | AT91C_SPI_CSAAT;// | AT91C_SPI_NCPHA; // ;
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN; // Enable SPI Interface
}
собственно данные в порт пишу так:
CODE
void func_SendGet_mode0(char CheckID)
{
unsigned int tmp;
volatile unsigned int bufft[8];
volatile unsigned int buffr[8];
// жду окончания передидущей трансляции данных
while ((*AT91C_SPI_SR & (AT91C_SPI_ENDRX|AT91C_SPI_ENDTX)) != (AT91C_SPI_ENDRX|AT91C_SPI_ENDTX));
for (tmp = Data.Start; tmp < Data.Stop; tmp++)
{
//забиваю данные в буфер передачи
bufft[0] = (((tmp << 3) | (tmp << 11)) & 0xFFFF)|SPI10; //SPI10 = (10 << 16)
bufft[1] = (Data.DataIn[0][tmp] & 0xFFFF)|SPI8; //SPI8 = (8 << 16)
bufft[2] = (Data.DataIn[1][tmp] & 0xFFFF)|SPI9; //SPI9 = (9 << 16)
// формирую указатели на буфера и их длинны
*AT91C_SPI_RPR = ((unsigned int) bufft);
*AT91C_SPI_TPR = ((unsigned int) buffr);
*AT91C_SPI_RCR = 3;
*AT91C_SPI_TCR = 3;
*AT91C_SPI_PTCR = AT91C_PDC_RXTEN|AT91C_PDC_TXTEN; //старт посылки
while(*AT91C_SPI_RCR != 0); //ожидание конца передачи/приема
Data.DataIn[1][Data.Prew] = buffr[1]; // перенос 2 принятого слова в нужное место
Data.DataIn[0][Data.Prew] = buffr[2]; // перенос 3 принятого слова в нужное место
}
}
на ногах NPCS вот что:
CS 1 посылка 2 посылка 3 посылка
0 0 0 0
1 0 0 0
2 0 0 0
3 0 1 0
подскажите что не так? куда глядеть? вроде-бы все правильно. или я упускаю из виду манипулирование полем PCS в регистре AT91C_SPI_MR ???
заранее спасибо.
собственно в догонку:
фактически, выбором NPCS управляю через регистр *AT91C_SPI_TDR полем PCS...