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

 
 
 
Reply to this topicStart new topic
> AT91SAM7X256 - SPI в PDC режиме, проблема при приеме
KolyanV
сообщение Jul 10 2008, 21:04
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 91
Регистрация: 1-06-05
Пользователь №: 5 621



Подключил к контроллеру AT91SAM7X256 по SPI интерфейсу микросхему CS5368.
Контроллер работает в Master режиме, прием/передача происходит с помощью PDC. Факт окончания операций записи/чтения определяется по прерываниям.
Проблема в следующем: при приеме данные смещаются на один байт. Т.е я программирую PDC на прием/передачу 3 байта данных, но в применом буфере полученные данные оказываются смещенными на один байт. Т.е байт, который должен находится в буфере со смещением 1 реально размещен со смещением 2. Причем смотрю осцилографом - ответ от микросхемы честный, начиная с 9-го клока шины данные добросовестно передаются. Т.е байт данных должен попасть в буфер со смещением 1 , а на практике попадает по смещению 2.

Инициализация SPI0 следующая:
Код
  // Конфигурирование PIO на предмет включения перефирии SPI0 к выводам порта A
  AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA,
                      AT91C_PA12_SPI0_NPCS0 | AT91C_PA16_SPI0_MISO | AT91C_PA17_SPI0_MOSI | AT91C_PA18_SPI0_SPCK,0);
  // Включение клоков для SPI0
  AT91F_SPI0_CfgPMC();
  // Конфигурирование SPI0
  AT91F_SPI_CfgMode(AT91C_BASE_SPI0, AT91C_SPI_MSTR | AT91C_SPI_PS_FIXED);  // Master, CS Fixed not decoded, Mode Fault Detection Enable, PCS=0 (NCS0 Active)
  AT91F_SPI_CfgCs(AT91C_BASE_SPI0, 0, AT91C_SPI_NCPHA | AT91C_SPI_BITS_8 | (16<<8));  // 8 бит, частота SPCK boudrate=MCK/16 = 3 Mhz

  // Конфигурирования прерываний по SPI
  AT91F_AIC_ConfigureIt(AT91C_BASE_AIC,
                        AT91C_ID_SPI0,
                        AT91C_AIC_PRIOR_HIGHEST,
                        AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL,
                        SPI0_Interrupt);
//  AT91F_SPI_EnableIt(AT91C_BASE_SPI0, AT91C_SPI_ENDTX);
  // Включение прерываний
  AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SPI0);
  // Включение SPI0
  AT91F_SPI_Enable(AT91C_BASE_SPI0);


Сам код для приема- передчаи данных по SPI:
Код
    CmdSndBuf[0]=CS5368_SPICMD_WRITE;
    CmdSndBuf[1]=Addr;
    // Настройка PDC для SPI
    *AT91C_SPI0_PTCR= AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS;  // Если были PDC трансферы в текущий момент - отключаем
    *AT91C_SPI0_TPR=  (unsigned)CmdSndBuf;
    *AT91C_SPI0_TCR=  2;
    *AT91C_SPI0_TNCR=  0;
    CmdSndFlag=false;
    // Запуск процесса отправки команды к АЦП cs5368
    *AT91C_SPI0_PTCR= AT91C_PDC_TXTEN;
    AT91F_SPI_EnableIt(AT91C_BASE_SPI0, AT91C_SPI_ENDTX);
    // Ожидание выполнения операции
    while (!CmdSndFlag);

    for (int zz=0;zz<20;zz++)
      __no_operation();

    // Подготовка буфера для отправки команды чтения данных
    CmdSndBuf[0]=CS5368_SPICMD_READ;
    CmdSndBuf[1]=0;
    CmdSndBuf[2]=0;
    // Настройка PDC для SPI
    *AT91C_SPI0_PTCR= AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS;
    *AT91C_SPI0_RPR=  (unsigned)CmdRcvBuf;
    *AT91C_SPI0_RCR=  3;
    *AT91C_SPI0_RNCR=  0;
    *AT91C_SPI0_TPR=  (unsigned)CmdSndBuf;
    *AT91C_SPI0_TCR=  3;
    *AT91C_SPI0_TNCR=  0;
    CmdRcvFlag=false;
    // Запуск процесса отправки команды к АЦП cs5368
    *AT91C_SPI0_PTCR= AT91C_PDC_TXTEN | AT91C_PDC_RXTEN;
    AT91F_SPI_EnableIt(AT91C_BASE_SPI0, AT91C_SPI_ENDRX);
    // Ожидание выполнения операции
    while (!CmdRcvFlag);



Обработка прерываний SPI:
Код
//---------------------------------------------------------------------
// Обработчик прерывания от SPI0
void SPI0_Interrupt()
{ if (*AT91C_SPI0_SR & AT91C_SPI_ENDTX)
     { CmdSndFlag=true;
       AT91F_SPI_DisableIt(AT91C_BASE_SPI0, AT91C_SPI_ENDTX);
     }
   if (*AT91C_SPI0_SR & AT91C_SPI_ENDRX)
     { CmdRcvFlag=true;
       AT91F_SPI_DisableIt(AT91C_BASE_SPI0, AT91C_SPI_ENDRX);
     }

   *AT91C_AIC_EOICR=AT91C_ID_SPI0;
}


В errata по данной ситуации никаких упоминаний нет. Не могу понять, где я глючу ?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 10 2008, 21:20
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



ИМХО, все правильно: при включении PDC приемника Вы тут же получаете последний байт, принятый при передаче предыдущей команды, когда PDC приемника был отключен. Сбросьте приемник.
Go to the top of the page
 
+Quote Post
KolyanV
сообщение Jul 10 2008, 21:49
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 91
Регистрация: 1-06-05
Пользователь №: 5 621



Цитата(aaarrr @ Jul 11 2008, 00:20) *
ИМХО, все правильно: при включении PDC приемника Вы тут же получаете последний байт, принятый при передаче предыдущей команды, когда PDC приемника был отключен. Сбросьте приемник.

Спасибо! Действительно, все оказалось до безобразия просто. Включил синхронную запись/чтение через PDC вместо "просто записи" и проблема решилась.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 10 2008, 21:53
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



На самом деле достаточно было бы просто прочитать SPI_RDR, но можно и так.
Go to the top of the page
 
+Quote Post

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

 


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


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