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

 
 
> проблемы с передачей по 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
 
Start new topic
Ответов
xelax
сообщение Jan 9 2008, 12:53
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 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
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 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
Сообщение #4


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

Группа: Модераторы
Сообщений: 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
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 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

Сообщений в этой теме
- xelax   проблемы с передачей по spi   Aug 10 2007, 06:35
- - _dem   отключите CS от периферийного модуля SPI, переключ...   Aug 10 2007, 08:40
- - xelax   После всех сношений смог добиться странных результ...   Aug 10 2007, 15:11
|- - _dem   не секрет. вот прямо из исходника (тут еще может г...   Aug 14 2007, 09:04
- - prottoss   Привет всем! Осваиваю SPI на AT91SAM7X256 - бо...   Jan 8 2008, 10:57
|- - xelax   Цитата(prottoss @ Jan 8 2008, 13:57) Прив...   Jan 9 2008, 07:28
|- - prottoss   Цитата(xelax @ Jan 9 2008, 14:28) Не поня...   Jan 9 2008, 11:55
- - prottoss   Наконец то разобрался в своей проблеме:-) До этого...   Jan 11 2008, 15:40
- - xelax   Вообще конечно ATMEL неприятно удивил своей реализ...   Jan 14 2008, 06:35
- - vdik   Сейчас вот разбираюсь с SPI, чтоб не плодить темы,...   Feb 13 2008, 07:49
- - prottoss   Цитата(vdik @ Feb 13 2008, 14:49) Как наи...   Feb 13 2008, 07:55


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

 


RSS Текстовая версия Сейчас: 6th September 2025 - 13:06
Рейтинг@Mail.ru


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