Поковырялся, изменил прогу на 100% (по моему мнению)-работающий вариант, чипсилекты перестали сниматься вообще

Что самое странное- если перед приемом или передачей поставить бряку, то чипселект выпрыгивает в High, и обмен происходит. Такое ощущение что он срабатывает по эстонски.
прога ниже:
Код
#define SPIFRAME (256)
void cfg_spi(void)
{ AT91PS_SPI pSPI=AT91C_BASE_SPI;
AT91F_PIO_CfgPeriph(
AT91C_BASE_PIOA, // PIO controller base address
AT91C_PA13_MOSI | AT91C_PA14_SPCK | AT91C_PA11_NPCS0 |AT91C_PA12_MISO, // Peripheral A
0); // Peripheral B
// spi init
AT91F_PMC_EnablePeriphClock( AT91C_BASE_PMC, ((unsigned int) 1 << AT91C_ID_SPI));
AT91F_SPI_Reset (AT91C_BASE_SPI);
AT91F_SPI_CfgMode( AT91C_BASE_SPI,
AT91C_SPI_MSTR | AT91C_SPI_PS_FIXED | AT91C_SPI_FDIV |
AT91C_SPI_MODFDIS | ((unsigned int)(0x00<<16) & AT91C_SPI_PCS));
pSPI->SPI_CSR[0]= AT91C_SPI_BITS_16|
((unsigned int) 0x03 << 8)| // (SPI) Serial Clock Baud Rate
((unsigned int) 0x05 << 16)| // (SPI) Delay Before SPCK
((unsigned int) 0x00 << 24); // (SPI) Delay Between Consecutive Transfers
AT91F_PDC_Open (AT91C_BASE_PDC_SPI);
pSPI->SPI_CR = AT91C_SPI_SPIEN;
}
/* протокол обмена cpu <=> fpga
формат обмена : 16-битные слова
1 слово передача/ прием (пусто)
15 14 13 12
| 1 R | 1 W | Count ena up/down | 12 adr |
2 слово - запись по адресу adr / синхро
3 слово запись по адресу adr+1 / чтение с адреса adr
*/
void txframe( unsigned short address, char uinc, unsigned int count, unsigned short *data)
{ // заголовок
static volatile unsigned int header;
unsigned int i;
// регистр spi
AT91PS_SPI pSPI=AT91C_BASE_SPI; AT91PS_PIO pPIO=AT91C_BASE_PIOA;
AT91PS_PDC pPDC=AT91C_BASE_PDC_SPI;
// ждем пока успокоится PDC
while( pPDC->PDC_TCR );
// (на всякий случай) ждем пока пин чипселекта не станет 1
while( pSPI->SPI_SR & AT91C_SPI_NSSR==0 );
// и до тех пор пока не будет окончена пересылка (что 100% дает снятие cs)
while( pSPI->SPI_SR & AT91C_SPI_TXEMPTY==0 );
// формирование заголовка
header=address | (unsigned short)(1<<14) | (unsigned short)(uinc<<13) | (unsigned short)(1<<12);
AT91F_PDC_DisableTx(pPDC);
AT91F_PDC_SendFrame( AT91C_BASE_PDC_SPI, (char *) &header, 1, (char *) data, count);
AT91F_PDC_EnableTx(pPDC);
}
void rxframe( unsigned short address, char uinc, unsigned int count, unsigned short *data)
{ // заголовок
static volatile unsigned int header;
static volatile unsigned int trash[20];
unsigned int i;
// регистр spi
AT91PS_SPI pSPI=AT91C_BASE_SPI;
AT91PS_PIO pPIO=AT91C_BASE_PIOA;
AT91PS_PDC pPDC=AT91C_BASE_PDC_SPI;
// дождаться окончания передачи
while( pPDC->PDC_TCR );
while( pSPI->SPI_SR & AT91C_SPI_NSSR==0 );
while( pSPI->SPI_SR & AT91C_SPI_TXEMPTY==0 );
// чистим на всякий случай регистр приема
header=pSPI->SPI_RDR;
// формирование заголовка
header=address | (unsigned short)(1<<15) | (unsigned short)(uinc<<13) | (unsigned short)(1<<12);
// добавлено в невменяемом состояни после 4-х часовой отладки
AT91F_PDC_DisableRx(pPDC); AT91F_PDC_DisableTx(pPDC);
// установить указатели на прием
AT91F_PDC_ReceiveFrame( AT91C_BASE_PDC_SPI, (char *) &trash, 2, (char *) data, count);
// отправка кадра
AT91F_PDC_SendFrame(AT91C_BASE_PDC_SPI,(char *) &header, 2, (char *) data, count);
// вот тут тоже
AT91F_PDC_EnableRx(pPDC); AT91F_PDC_EnableTx(pPDC);
// ожидание конца передачи
while( !AT91F_PDC_IsRxEmpty(AT91C_BASE_PDC_SPI) );
}
static volatile unsigned short trash[SPIFRAME],cash[SPIFRAME];
int main()
{
//* Begin
int i,j,k=0;
float y=0.314f; //здец
AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA );
// это для отладочного дрыгания ножкой
AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, AT91C_PIO_PA20);
AT91F_PIO_SetOutput( AT91C_BASE_PIOA, AT91C_PIO_PA20 );
cfg_spi();
// тут происходят совершенно непонятные вещи
while(1)
{
for(i=0;i<256;i++,k++)
{ trash[i]=(unsigned short)k; }
txframe(0x100,1,SPIFRAME,(unsigned short *)trash);
/*
... тут происхотят всякие полезные вычисления числа пи...
*/
rxframe(0x100,1,SPIFRAME,(unsigned short *)cash);
j=1;
for(i=0;i<256;i++)
{ if (trash[i]!=cash[i]) j=0; }
if (j!=0)
{ if (AT91F_PIO_IsSet(AT91C_BASE_PIOA,AT91C_PIO_PA20))
AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, AT91C_PIO_PA20 );
else
AT91F_PIO_SetOutput( AT91C_BASE_PIOA, AT91C_PIO_PA20 );
}
}
}//* End
void cfg_spi(void)
{ AT91PS_SPI pSPI=AT91C_BASE_SPI;
AT91F_PIO_CfgPeriph(
AT91C_BASE_PIOA, // PIO controller base address
AT91C_PA13_MOSI | AT91C_PA14_SPCK | AT91C_PA11_NPCS0 |AT91C_PA12_MISO, // Peripheral A
0); // Peripheral B
// spi init
AT91F_PMC_EnablePeriphClock( AT91C_BASE_PMC, ((unsigned int) 1 << AT91C_ID_SPI));
AT91F_SPI_Reset (AT91C_BASE_SPI);
AT91F_SPI_CfgMode( AT91C_BASE_SPI,
AT91C_SPI_MSTR | AT91C_SPI_PS_FIXED | AT91C_SPI_FDIV |
AT91C_SPI_MODFDIS | ((unsigned int)(0x00<<16) & AT91C_SPI_PCS));
pSPI->SPI_CSR[0]= AT91C_SPI_BITS_16|
((unsigned int) 0x03 << 8)| // (SPI) Serial Clock Baud Rate
((unsigned int) 0x05 << 16)| // (SPI) Delay Before SPCK
((unsigned int) 0x00 << 24); // (SPI) Delay Between Consecutive Transfers
AT91F_PDC_Open (AT91C_BASE_PDC_SPI);
pSPI->SPI_CR = AT91C_SPI_SPIEN;
}
/* протокол обмена cpu <=> fpga
формат обмена : 16-битные слова
1 слово передача/ прием (пусто)
15 14 13 12
| 1 R | 1 W | Count ena up/down | 12 adr |
2 слово - запись по адресу adr / синхро
3 слово запись по адресу adr+1 / чтение с адреса adr
*/
void txframe( unsigned short address, char uinc, unsigned int count, unsigned short *data)
{ // заголовок
static volatile unsigned int header;
unsigned int i;
// регистр spi
AT91PS_SPI pSPI=AT91C_BASE_SPI; AT91PS_PIO pPIO=AT91C_BASE_PIOA;
AT91PS_PDC pPDC=AT91C_BASE_PDC_SPI;
// ждем пока успокоится PDC
while( pPDC->PDC_TCR );
// (на всякий случай) ждем пока пин чипселекта не станет 1
while( pSPI->SPI_SR & AT91C_SPI_NSSR==0 );
// и до тех пор пока не будет окончена пересылка (что 100% дает снятие cs)
while( pSPI->SPI_SR & AT91C_SPI_TXEMPTY==0 );
// формирование заголовка
header=address | (unsigned short)(1<<14) | (unsigned short)(uinc<<13) | (unsigned short)(1<<12);
AT91F_PDC_DisableTx(pPDC);
AT91F_PDC_SendFrame( AT91C_BASE_PDC_SPI, (char *) &header, 1, (char *) data, count);
AT91F_PDC_EnableTx(pPDC);
}
void rxframe( unsigned short address, char uinc, unsigned int count, unsigned short *data)
{ // заголовок
static volatile unsigned int header;
static volatile unsigned int trash[20];
unsigned int i;
// регистр spi
AT91PS_SPI pSPI=AT91C_BASE_SPI;
AT91PS_PIO pPIO=AT91C_BASE_PIOA;
AT91PS_PDC pPDC=AT91C_BASE_PDC_SPI;
// дождаться окончания передачи
while( pPDC->PDC_TCR );
while( pSPI->SPI_SR & AT91C_SPI_NSSR==0 );
while( pSPI->SPI_SR & AT91C_SPI_TXEMPTY==0 );
// чистим на всякий случай регистр приема
header=pSPI->SPI_RDR;
// формирование заголовка
header=address | (unsigned short)(1<<15) | (unsigned short)(uinc<<13) | (unsigned short)(1<<12);
// добавлено в невменяемом состояни после 4-х часовой отладки
AT91F_PDC_DisableRx(pPDC); AT91F_PDC_DisableTx(pPDC);
// установить указатели на прием
AT91F_PDC_ReceiveFrame( AT91C_BASE_PDC_SPI, (char *) &trash, 2, (char *) data, count);
// отправка кадра
AT91F_PDC_SendFrame(AT91C_BASE_PDC_SPI,(char *) &header, 2, (char *) data, count);
// вот тут тоже
AT91F_PDC_EnableRx(pPDC); AT91F_PDC_EnableTx(pPDC);
// ожидание конца передачи
while( !AT91F_PDC_IsRxEmpty(AT91C_BASE_PDC_SPI) );
}
static volatile unsigned short trash[SPIFRAME],cash[SPIFRAME];
int main()
{
//* Begin
int i,j,k=0;
float y=0.314f; //здец
AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA );
// это для отладочного дрыгания ножкой
AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, AT91C_PIO_PA20);
AT91F_PIO_SetOutput( AT91C_BASE_PIOA, AT91C_PIO_PA20 );
cfg_spi();
// тут происходят совершенно непонятные вещи
while(1)
{
for(i=0;i<256;i++,k++)
{ trash[i]=(unsigned short)k; }
txframe(0x100,1,SPIFRAME,(unsigned short *)trash);
/*
... тут происхотят всякие полезные вычисления числа пи...
*/
rxframe(0x100,1,SPIFRAME,(unsigned short *)cash);
j=1;
for(i=0;i<256;i++)
{ if (trash[i]!=cash[i]) j=0; }
if (j!=0)
{ if (AT91F_PIO_IsSet(AT91C_BASE_PIOA,AT91C_PIO_PA20))
AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, AT91C_PIO_PA20 );
else
AT91F_PIO_SetOutput( AT91C_BASE_PIOA, AT91C_PIO_PA20 );
}
}
}//* End