реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> проблемы с передачей по spi, sam7x+gcc
xelax
сообщение Aug 10 2007, 06:35
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Начал разбираться с spi на этом контроллере(Evalution Board at91sam7x-ek) и наткнулся на такую проблему.
Есть в нём такой режим, удерживать CS в активном состоянии, после окончания передачи.

Инициализирую SPI слудующим образом
Код

/* Configure PIOs for SPI */
AT91C_BASE_PIOA->PIO_ASR = AT91C_PA12_SPI0_NPCS0 | AT91C_PA16_SPI0_MISO |
                               AT91C_PA17_SPI0_MOSI  | AT91C_PA18_SPI0_SPCK;
AT91C_BASE_PIOA->PIO_BSR = 0;
AT91C_BASE_PIOA->PIO_PDR = AT91C_PA12_SPI0_NPCS0 | AT91C_PA16_SPI0_MISO |
                               AT91C_PA17_SPI0_MOSI  | AT91C_PA18_SPI0_SPCK;                                                      
    
    //enable the clock of SPI
    AT91C_BASE_PMC->PMC_PCER = 1<<AT91C_ID_SPI0;
                
    // инициализация spi
    // сброс и разрешение
    AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SPIDIS | AT91C_SPI_SWRST;
    // установка моды работы spi master, first peripherial active
    AT91C_BASE_SPI0->SPI_MR    = AT91C_SPI_MSTR | AT91C_SPI_LLB;
    // параметры общения с устройством на CS0  
    // скорость spi 24 МГц, задержка перед выдачей тактовой 300 нс.
    AT91C_BASE_SPI0->SPI_CSR[0] = AT91C_SPI_CPOL | AT91C_SPI_BITS_8 |
                                     (0x02 <<  8) | (0x0F << 16);// | AT91C_SPI_CSAAT;                                   
    // запрещаю все прерывания                                     
    AT91C_BASE_SPI0->SPI_IDR = 0xFFFFFFFF;
AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SPIEN;


процедура отправки байта, крутится в основном цикле (запускается раз в 1 секунду)
Код
   static unsigned char temp = 0;
       
   temp++;    
   AT91C_BASE_SPI0->SPI_TDR = temp;


так вот в чём проблема, когда добавляю бит AT91C_SPI_CSAAT (чтобы CS оставался активным) у меня передаётся один байт, псоле этого признак того, что передатчик пустой не появляется и запись в регистр SPI_TDR не приносит никакого эффекта.
Как только убираю бит AT91C_SPI_CSAAT всё начинает работать нормально.
Кто-нибудь сталкивался с таким эффектом.?

Что я делаю не так?
Как работать с устройствами, для сеанса обмена с которыми нужно удерживать CS активным (таже атмеловская флэшка на плате)?
И как себя ведёт CS в фиксированной моде, нужен ли ему AT91C_SPI_CSAAT, перестаёт ли он быть активным после передачи?

З.Ы, SPI работает сам на себя по локальной внутренней петле AT91C_SPI_LLB. При работе на внешнее устройство тот же эффект.
Go to the top of the page
 
+Quote Post
_dem
сообщение Aug 10 2007, 08:40
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970



отключите CS от периферийного модуля SPI, переключите на PIO и управляйте "вручную". в скорости не проиграете.

OFF :
ps. у меня после запуска SPI на AT91SAM7X256 осталось устойчивое впечатление, что это самый гнусный периферийный модуль у SAM, и делали его за день до выпуска кристалла... правда, пока не познакомился с TWI в этом чипе...

Сообщение отредактировал _dem - Aug 10 2007, 08:46
Go to the top of the page
 
+Quote Post
xelax
сообщение Aug 10 2007, 15:11
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



После всех сношений смог добиться странных результатов:

Ведёт себя очень странно. CS на высоких частотах делает неактивным после каждого сеанса связи, уменьшаю тактовую частоту и spi начинает делать cs неактивным через 1 мс. Есть большое подозрение, что просто где-то внутри логика начинает не успевать срабатывать. Так что стрёмно работать в таком режиме. Решил попробовать через DMA контроллер. Заработало так как хотел. Отправляет n байт при одной активности CS. Флэшка на плате ожила и отвечает. 08.gif
Причем DMA контроллеру вообще пофик усьановлен ли бит CSAAT или нет. И с ним и без него работает одинакого.

К стати как Вы умудрились запустить под управлением CS как обыкновенных выходов. Все мои усилия приводили к тому, что выходы начинали работать как надо, но умирал spi напрочь. smile3046.gif Танцы с бубном не помогли и я забил на попытки.

Если не секрет, то поделитесь тайным знанием настройки пинов и spi в таком режиме, так чтобы spi не умирал. smile.gif
Go to the top of the page
 
+Quote Post
_dem
сообщение Aug 14 2007, 09:04
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970



не секрет. вот прямо из исходника (тут еще может где-то попасться обработка внутреннего протокола, но суть понятна будет)

Код
void SPI_Connect(
        PSPIPort self
         )
{
    // CHECKING AND CONFIGURING
    if (self->BASE_SPI == AT91C_BASE_SPI0)     
        {
        self->SPI_ID = AT91C_ID_SPI0;
        self->BASE_SPI_PDC = AT91C_BASE_PDC_SPI0;
        /// PIO    
        #ifdef SAM7X
        AT91F_PIO_CfgPeriph(
            AT91C_BASE_PIOA, // PIO controller base address
            AT91C_PA17_SPI0_MOSI | AT91C_PA16_SPI0_MISO | AT91C_PA18_SPI0_SPCK ,     // Peripheral A
            0); // Peripheral B
        
        #else
        AT91F_PIO_CfgPeriph(
            AT91C_BASE_PIOA, // PIO controller base address
            AT91C_PA13_MOSI | AT91C_PA14_SPCK |AT91C_PA12_MISO, // Peripheral A
            0); // Peripheral B
        
        #endif
        
        // registering processor
        _spiports [ 0 ] = self;
        }
    
    #ifdef SAM7X
    if (self->BASE_SPI == AT91C_BASE_SPI1)     
        {     
        self->SPI_ID = AT91C_ID_SPI1;     
        self->BASE_SPI_PDC = AT91C_BASE_PDC_SPI1;
        // only SAM7X has 2nd SPI
        AT91F_PIO_CfgPeriph(
            AT91C_BASE_PIOA, // PIO controller base address
            0, // Peripheral A
            AT91C_PA22_SPI1_SPCK | AT91C_PA23_SPI1_MOSI | AT91C_PA24_SPI1_MISO); // Peripheral B
    
        // registering processor
        _spiports [ 1 ] = self;
        }
    #endif
    if (self->SPI_ID == 0) return;
    
    ///////////////////////////////////////////////////////////
    
    // enable clock
    AT91F_PMC_EnablePeriphClock( AT91C_BASE_PMC, ((unsigned int) 1 << self->SPI_ID));
    
    AT91F_SPI_Reset (self->BASE_SPI);
    
    if (self->slavemode)
        {
        AT91F_SPI_CfgMode( self->BASE_SPI,
                              AT91C_SPI_PS_FIXED | AT91C_SPI_MODFDIS |
                              ((unsigned int)(0x00<<16) & AT91C_SPI_PCS));
        }
    else
        {
        AT91F_SPI_CfgMode( self->BASE_SPI,
                              AT91C_SPI_MSTR | AT91C_SPI_PS_FIXED | AT91C_SPI_MODFDIS |
                              ((unsigned int)(0x00<<16) & AT91C_SPI_PCS));
        }
    
    // reset PDC channels
    self->BASE_SPI_PDC->PDC_TPR = 0;
    self->BASE_SPI_PDC->PDC_TCR = 0;    
    self->BASE_SPI_PDC->PDC_RPR = 0;
    self->BASE_SPI_PDC->PDC_RCR = 0;    
    
    self->BASE_SPI_PDC->PDC_PTCR = 0;
    
    // configure
    self->BASE_SPI->SPI_CSR[0]= AT91C_SPI_BITS_8 |
            ((unsigned int) self->clockdivider <<  8)| // (SPI) Serial Clock Baud Rate
            ((unsigned int) 0x00 << 16)| // (SPI) Delay Before SPCK
            ((unsigned int) SPI_DELAY_BETWEEN_TRANSFERS << 24); // (SPI) Delay Between Consecutive Transfers
    
    AT91F_SPI_Enable(self->BASE_SPI);
    
    // Init CS pins
    AT91C_BASE_PIOA->PIO_PER = DEV_CS_ALL_A;
    AT91C_BASE_PIOA->PIO_OER = DEV_CS_ALL_A;

    #ifdef SAM7X
    AT91C_BASE_PIOB->PIO_PER = DEV_CS_ALL_B;
    AT91C_BASE_PIOB->PIO_OER = DEV_CS_ALL_B;
    #endif
    
    // clearing remote side buffers
    #ifdef SPI_CLEAR_REMOTE_BUFFERS
    #ifndef SPI_SLAVE
    
    if (! self->slavemode )
        {
        memset( self->TXdata, SPI_CLEAR_BUFFERS, SPI_BUFFER_LENGTH );
        for (unsigned char zz = 0; zz < SPI_DEVICE_COUNT; zz++ )
            {
            __SPI_Send( self,
                   zz,
                   self->TXdata,
                   SPI_BUFFER_LENGTH,
                   0
                   );
                  
            }
        }
    #endif
    #endif    
          
    __SPI_UnSelectAll();
    
    /// CONNECT SPI  OKAY
    return;
}


и отправка данных

Код
short __SPI_Send(
            PSPIPort self,
                   unsigned char devnum,
            unsigned char * data,
            unsigned short count,
            unsigned short timeout
            )
{
    if (!timeout)
        timeout = _SPI_TIMEOUT;
    if (!(count))
        return SPI_ERROR;
    
    __SPI_Select( devnum );
    
    OSSemSet(self->ENDTXSemaphore, 0, &self->last_error);

    unsigned long sr = self->BASE_SPI->SPI_SR;

    // preparing buffer
    self->BASE_SPI_PDC->PDC_TPR = (unsigned int) (char *)data;
    self->BASE_SPI_PDC->PDC_TCR = count;    

    // enabling SEND PDC
    
    // reset IRQ
    self->BASE_SPI->SPI_IDR = (SPI_PDC_TX_FINISHED_FLAG );
    sr = self->BASE_SPI->SPI_SR = 0;
    self->BASE_SPI->SPI_IER = (SPI_PDC_TX_FINISHED_FLAG );
    
    self->BASE_SPI_PDC->PDC_PTCR = AT91C_PDC_TXTEN;
    
    OSSemPend(self->ENDTXSemaphore, timeout , &self->last_error);
    self->BASE_SPI->SPI_IDR = (SPI_PDC_TX_FINISHED_FLAG );

    // need to read it - SPI SAM7 bug
    (unsigned long)self->BASE_SPI->SPI_RDR;
    // reading status to clear it
    (unsigned long)self->BASE_SPI->SPI_SR;
    (unsigned long)self->BASE_SPI->SPI_RDR;
    
    __SPI_UnSelectAll();    
    
    // disabling SEND PDC
    self->BASE_SPI_PDC->PDC_PTCR = AT91C_PDC_TXTDIS;
    
    short res = count - (self->BASE_SPI_PDC->PDC_TCR);
    
    (void)data;

    return res;
}


и выбор чипа

Код
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
__inline void __SPI_Select( unsigned char devnum )
{
    #ifdef SPI_SLAVE
        (void)devnum;
        return;
    #else
    if (devnum > 8)
        return;
    
    #ifdef SPI_STAY_SELECTED
    if (devnum == spi_last_selected) return;
        devnum = spi_last_selected;
    #endif    
    
    // first disabling all
    AT91C_BASE_PIOA->PIO_SODR = DEV_CS_ALL_A;
    AT91C_BASE_PIOA->PIO_CODR = DEV_CS_A[ devnum ];
    
    #ifdef SAM7X
    AT91C_BASE_PIOB->PIO_SODR = DEV_CS_ALL_B;
    AT91C_BASE_PIOB->PIO_CODR = DEV_CS_B[ devnum ];
    #endif

    #endif // SPI_SLAVE
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
__inline void __SPI_UnSelect( unsigned char devnum )
{
    #ifdef SPI_SLAVE

    (void)devnum;
    return;
    
    #else

    if (devnum > 8)
        {
        return;
        }
    // disabling all
    AT91C_BASE_PIOA->PIO_SODR = DEV_CS_A[ devnum ];

    #ifdef SAM7X
    
    AT91C_BASE_PIOB->PIO_SODR = DEV_CS_B[ devnum ];
    
    #endif    // SAM7X

    #endif //SPI_SLAVE
}
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 8 2008, 10:57
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Привет всем! Осваиваю SPI на AT91SAM7X256 - боард от Argussoft - AS-SAM7X - аналог AT91SAM7X-EK.

Сотврил драйвер для SPI0 - можно менять софтовое дергание CSx на хардварное - но не работает!!! Вроде уяснил, то, что написано в топике, но чего то не допонял 05.gif

Кстати, с хардварным SPI, если ставить точку останова перед процедурой передачи - то данные передаются! В программе - нет! Хэлп-хэлп!
Прикрепленные файлы
Прикрепленный файл  SPI.RAR ( 1.64 килобайт ) Кол-во скачиваний: 67
 


--------------------
Go to the top of the page
 
+Quote Post
xelax
сообщение Jan 9 2008, 07:28
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Цитата(prottoss @ Jan 8 2008, 13:57) *
Привет всем! Осваиваю SPI на AT91SAM7X256 - боард от Argussoft - AS-SAM7X - аналог AT91SAM7X-EK.

Сотврил драйвер для SPI0 - можно менять софтовое дергание CSx на хардварное - но не работает!!! Вроде уяснил, то, что написано в топике, но чего то не допонял 05.gif

Почитай errata, там очень много всего про SPI написанно.

Цитата(prottoss @ Jan 8 2008, 13:57) *
Кстати, с хардварным SPI, если ставить точку останова перед процедурой передачи - то данные передаются! В программе - нет! Хэлп-хэлп!

Не понятно, если точка останова перед процедурой передачи, то как данные передаются 07.gif
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 9 2008, 11:55
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(xelax @ Jan 9 2008, 14:28) *
Не понятно, если точка останова перед процедурой передачи, то как данные передаются 07.gif
А что непонятного? Поставили точку останова перед процедурой передачи - дошли, запустили дальше - данные передались... Если точку останова не ставить то чаще облом 05.gif


--------------------
Go to the top of the page
 
+Quote Post
xelax
сообщение Jan 9 2008, 12:53
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Вот как у меня запускается приём или передача

Код


if (SPI_WRITE == DiscriptorSpi1->rwHeader)    
{
  AT91C_BASE_SPI1->SPI_TPR = (uint32_t)(DiscriptorSpi1->pHeader);
  AT91C_BASE_SPI1->SPI_TCR = DiscriptorSpi1->bSizeHeader;
  AT91C_BASE_SPI1->SPI_IER = AT91C_SPI_TXBUFE;    
}
else // SPI_READ
{
  uint32_t dummy;
  while (AT91C_BASE_SPI1->SPI_SR & AT91C_SPI_RDRF)
     dummy = AT91C_BASE_SPI1->SPI_RDR;
  AT91C_BASE_SPI1->SPI_RPR = (uint32_t)(DiscriptorSpi1->pHeader);
  AT91C_BASE_SPI1->SPI_RCR = DiscriptorSpi1->bSizeHeader;
  AT91C_BASE_SPI1->SPI_IER = AT91C_SPI_RXBUFF;    
      
  AT91C_BASE_SPI1->SPI_TPR = (uint32_t)(DiscriptorSpi1->pHeader);
  AT91C_BASE_SPI1->SPI_TCR = DiscriptorSpi1->bSizeHeader;
}


настраивается примерно также как и у вас.
Различие в том, что я не в цикле опрашиваю

/* Wait for transmitter/receiver complete */
while(0 == (AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_ENDTX));
while(0 == (AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_ENDRX));

а обрабатываю прерывание от BUFF empty и full. Попробуйте тоже ориентироваться на эти события. И ещё PDC у меня разрешается сразу при настройке, а транзакция запускается записью в регистр SPI_TCR.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 9 2008, 13:05
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(xelax @ Jan 9 2008, 19:53) *
Вот как у меня запускается приём или передача
Спасибо, буду пробовать... Хотя мне не понятна разница между ожиданием флагов окончания приема-передачи и сигналом от обработчика прерывания на чисто физическом уровне...

В любом случае SPI + CS работают аппаратно... Я не имею ввиду программне дергание CS это у меня почему то вообще не работает 05.gif


--------------------
Go to the top of the page
 
+Quote Post
KRS
сообщение Jan 9 2008, 13:17
Сообщение #10


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(prottoss @ Jan 9 2008, 16:05) *
Спасибо, буду пробовать... Хотя мне не понятна разница между ожиданием флагов окончания приема-передачи и сигналом от обработчика прерывания на чисто физическом уровне...

А вы почитайте errata, у них как раз бага с CSAAT и LASTXFER, да и вообще что бы запустить аппаратные чипселекты надо поплясать с бубном, на разных семействах разные баги и особенности.
Проще всего взять осцилограф и смотреть как работает.

Я выбрал такой алгоритм, он правильно работатет везде - посылаю через DMA (все данные гарантировано уходят при низком CS) что бы дернуть CS или переключится на другой надо убедится что DMA пуст и передача завершена ((*AT91C_SPI_SR & (AT91C_SPI_TXEMPTY | AT91C_SPI_TXBUFE))== (AT91C_SPI_TXEMPTY | AT91C_SPI_TXBUFE))

Отсальные варианты то на SAM7X, то на SAM7S работают криво.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 9 2008, 14:26
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(KRS @ Jan 9 2008, 20:17) *
Отсальные варианты то на SAM7X, то на SAM7S работают криво.
БОЛЬШОЕ спасибо за разъяснение проблемы - теперь более-менее встало все на свои места - все читается-пишется, НО опять же с аппаратным CS 05.gif

Программный так и не могу заставить работать... Осциллографа, к сожалению, счас под рукой нет, но нога CS программно дрыгается - проверил тестером smile.gif
Вот код инициализации:


Код
void SPI_Init(void)
{
/* Configure PIOs */
AT91C_BASE_PIOA->PIO_ASR =
#ifndef  SPI_SOFT_CHIP_SELECT
    AT45DB_CS_LINE | /* Configure CS line SPI#0 */
#endif /* #ifdef  SPI_SOFT_CHIP_SELECT */
    
  AT91C_PA16_SPI0_MISO | /* MISO SPI#0 */
  AT91C_PA17_SPI0_MOSI | /* MOSI SPI#0 */
  AT91C_PA18_SPI0_SPCK; /* SCK SPI#0 */

AT91C_BASE_PIOA->PIO_PDR =  

#ifndef  SPI_SOFT_CHIP_SELECT
    AT45DB_CS_LINE | /* Configure CS line SPI#0 */
#endif /* #ifdef  SPI_SOFT_CHIP_SELECT */
  
    AT91C_PA16_SPI0_MISO | /* MISO SPI#0 */
  AT91C_PA17_SPI0_MOSI | /* MOSI SPI#0 */
  AT91C_PA18_SPI0_SPCK; /* SCK SPI#0 */

/* Enable CLock */
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_SPI0;

/* Reset the SPI */
AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SWRST;

    /* Configure SPI in Master Mode with No CS selected !!! */
AT91C_BASE_SPI0->SPI_MR =
    (24 << AT45DB_DLYBCS) |
    AT91C_SPI_MSTR   |
  AT91C_SPI_MODFDIS  |
  AT91C_SPI_PCS;

/* Configure CS1 line */
UINT32 csr =
  (AT91C_SPI_CPOL |
  ((BOARD_CPU_GetClkFreq() / AT45DB_SPI_CLK) << 8)|
  (AT91C_SPI_DLYBS & (AT45DB_DLYBS   << 16))  |
  (AT91C_SPI_DLYBCT  & (AT45DB_DLYBCT  << 24))
  );
AT91C_BASE_SPI0->SPI_CSR[1] = csr;

#ifdef  SPI_SOFT_CHIP_SELECT
/* Configure CS1 in PIO mode (bug fix for SAM7X256) */
AT91C_BASE_PIOA->PIO_PER = AT45DB_CS_LINE; /* Enable line */
    AT91C_BASE_PIOA->PIO_OER = AT45DB_CS_LINE;  /* Enable output */
AT91C_BASE_PIOA->PIO_IDR = AT45DB_CS_LINE;  /* Disable interrupt */

/* Enable peripheral clock */
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOA;

/* Chip deselect */
CHIP_OFF(AT45DB_CS_LINE);
#endif /* #ifdef  SPI_SOFT_CHIP_SELECT */

/* Configure SPI CS1 for Serial DataFlash AT45DBxx */
AT91C_BASE_SPI0->SPI_MR &= ~(0x2 << 16); /* clear bit CS line bit */

/* SPI_Enable */
AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SPIEN;

/* Disable Transmitter and Reseiver transfers and clear DMA buffers */
    AT91C_BASE_SPI0->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
AT91C_BASE_SPI0->SPI_RCR = 0;
    AT91C_BASE_SPI0->SPI_TCR = 0;
}


Вот код обмена данными:

Код
void SPI_Xfer(SPI_XDesc_t *desc)
{
   CHIP_OFF(AT45DB_CS_LINE); /* Chip deselect */
CHIP_ON(AT45DB_CS_LINE); /* Chip select */

/* read rx data register and status register for
clear previos transfers flag */
(UINT32)AT91C_BASE_SPI0->SPI_RDR;
(UINT32)AT91C_BASE_SPI0->SPI_SR;
(UINT32)AT91C_BASE_SPI0->SPI_RDR;
  
   /* Initialize the Transmit and Receive Pointers */
    AT91C_BASE_SPI0->SPI_RPR = (UINT32)desc->rx_curr_data;
    AT91C_BASE_SPI0->SPI_TPR = (UINT32)desc->tx_curr_data;

    /* Intialize the Transmit and Receive Counters */
    AT91C_BASE_SPI0->SPI_RCR = desc->rx_curr_len;
    AT91C_BASE_SPI0->SPI_TCR = desc->tx_curr_len; /* Start transfer */

if(desc->tx_next_len != 0)
{
    /* Initialize the Next Receive Pointer and Next Receive Counter */
     AT91C_BASE_SPI0->SPI_RNPR = (UINT32)desc->rx_next_data;
  AT91C_BASE_SPI0->SPI_RNCR = desc->rx_next_len;
    
     /* Initialize the Next Transmit Pointer and Next Transmit Counter */
     AT91C_BASE_SPI0->SPI_TNPR = (UINT32)desc->tx_next_data;
  AT91C_BASE_SPI0->SPI_TNCR = desc->tx_next_len;
    }

/* Start transfer */
AT91C_BASE_SPI0->SPI_PTCR = AT91C_PDC_RXTEN + AT91C_PDC_TXTEN;

/* Wait for transmitter/receiver complete */
#if 0
while(0 == (AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_ENDTX));
while(0 == (AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_ENDRX));
#endif

/* Wait for DMA empty */
   while((AT91C_BASE_SPI0->SPI_SR &
     (AT91C_SPI_TXEMPTY | AT91C_SPI_TXBUFE | AT91C_SPI_RXBUFF)) !=
    (AT91C_SPI_TXEMPTY | AT91C_SPI_TXBUFE | AT91C_SPI_RXBUFF));
    
/* Disable Transmitter and Reseiver transfers */
    AT91C_BASE_SPI0->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
  
/* Chip deselect */
   CHIP_OFF(AT45DB_CS_LINE); /* Chip deselect */
}


--------------------
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 11 2008, 15:40
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Наконец то разобрался в своей проблеме:-) До этого использовал хардварный CS, потому как совсем голова шла кругом от этого SPI! Все было просто - я в пылу экспериментов установил значения макросов AT45DB_DLYBS, AT45DB_DLYBCT, AT45DB_DLYBCS на максимум, т.е 0xff. После установки их в 0 все заработало!


--------------------
Go to the top of the page
 
+Quote Post
xelax
сообщение Jan 14 2008, 06:35
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Вообще конечно ATMEL неприятно удивил своей реализацией SPI и TWI интерфесов в этих микроконтроллерах. И тот и другой заводится после танцев с бубном. sad.gif
Go to the top of the page
 
+Quote Post
vdik
сообщение Feb 13 2008, 07:49
Сообщение #14





Группа: Новичок
Сообщений: 8
Регистрация: 30-10-07
Из: Петрозаводск
Пользователь №: 31 873



Сейчас вот разбираюсь с SPI, чтоб не плодить темы, спрошу здесь smile.gif.
Составляю УСЛОВИЕ ГОТОВНОСТИ SPI к передаче-приему, как должен выглядеть статус-регистр (SPI_SR)?
Первое, что пришло в голову - это TXEMPTY==1 (регистр и буфер передачи пусты), но так не срабатывает (видимо при начальной загрузке здесь=0).
Далее, пришел к такому:
TXBUFE == 1 --- буфер-передатчик опустошен
RXBUFF == 0 --- буфер-приемник не заполнен
TDRE == 1 --- регистр для передачи пуст
RDRF == 0 --- регистр приема не заполнен
но почему-то работает при RXBUFF == 1 (остальные 3 условия без изменений).
Как наиболее полно должно выглядеть условие готовности SPI, чтоб в нем точно ничего нету, можно запускать передачу-прием ?


--------------------
~Venerium Rerum Omnium~
Go to the top of the page
 
+Quote Post
prottoss
сообщение Feb 13 2008, 07:55
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(vdik @ Feb 13 2008, 14:49) *
Как наиболее полно должно выглядеть условие готовности SPI, чтоб в нем точно ничего нету, можно запускать передачу-прием ?
См. пост №10


--------------------
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 10:42
Рейтинг@Mail.ru


Страница сгенерированна за 0.01577 секунд с 7
ELECTRONIX ©2004-2016