Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Странное поведение ARM+SPI DataFlash
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
lecko
Имеется тестовый код для ARM7, запрашивающий ID у микросхемы Atmel SPI DataFlash:
Код
void SSP1Send( BYTE *buf, DWORD Length )
{
  DWORD i;  
  for ( i = 0; i < Length; i++ )
  {
    /* as long as TNF bit is set (TxFIFO is not full), I can always transmit */
    while ( !(SSP1SR & SSPSR_TNF) );
    SSP1DR = *buf;
    buf++;
    /* Wait until the Busy bit is cleared */
    while ( !(SSP1SR & SSPSR_BSY) );
  }
  return;
}  

void SSP1Receive( BYTE *buf, DWORD Length )
{
  DWORD i;
  for ( i = 0; i < Length; i++ )
  {
    /* As long as Receive FIFO is not empty, I can always receive. */
    /* since it's a loopback test, clock is shared for both TX and RX,
    no need to write dummy byte to get clock to get the data */
    /* if it's a peer-to-peer communication, SSPDR needs to be written
    before a read can take place. */
    SSP1DR = 0xFF;
    while ( !(SSP1SR & SSPSR_RNE) );
    *buf = SSP1DR;
    buf++;
  }
  return;  
}

...
for (n = 0; n < 3; n++) {
UART_printf(0,"Try readback ID from DataFlash: ");
data_send[0]=0x9f;
  
SSP1Send(data_send,1);
FIO4CLR = 1<<21;
SSP1Receive(data_recv,7);
FIO4SET = 1<<21;
TFT_printf(0,"Read: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x \n\r",data_recv[0],data_recv[1],data_recv[2],data_recv[3],data_recv[4],data_recv[5],data_recv[6]);
  }

В соответствии с даташитом ответ должен быть такой: 0x1f 0x27 0x1 0x0

На практике имеем следующее:
Код
Try readback ID from DataFlash:
Read: 0xff 0x1f 0x27 0x1 0x0 0x0 0x0
Try readback ID from DataFlash:
Read: 0xff 0xff 0x1f 0x27 0x1 0x0 0x0
Try readback ID from DataFlash:
Read: 0xff 0xff 0x1f 0x27 0x1 0x0 0x0

Логический анализатор показал, что все нормально, на нем этих 0xff нет (точнее есть один, в момент получения команды). Откуда берутся эти "мусорные" байты?
aaarrr
Цитата(lecko @ Oct 3 2011, 17:59) *
Откуда берутся эти "мусорные" байты?

Из приемного FIFO, надо полагать. SSP1Send его ведь не чистит.
skripach
Первый 0xff это принятый байт соответствующий переданному байту команды.
lecko
Цитата(aaarrr @ Oct 3 2011, 18:12) *
Из приемного FIFO, надо полагать. SSP1Send его ведь не чистит.


Просто и логично) спасибо, помогло! Для тех, кто будет в том же танке что и я прилагаю код, который необходимо добавить:
Код
BYTE i,Dummy;
for(i=0;i<FIFOSIZE;i++) Dummy=SSP1DR;
SII
Я недавно делал драйвер для обмена по ссп, ну и тоже намучился из-за собственной нелепой ошибки. Забыл о том, что прерывание приходит не по заполненности очереди приёмника до конца, а при заполненности наполовину, ну и гнал байты-заполнители для чтения лишние. Сейчас вот медитирую над нормальным использованием ПДП (у НХПшных МК контроллер централизованный, не как у АТМЕЛа, где у каждого СПИ или УСАРТа свой контроллер ПДП).
lecko
В продолжение темы.
При отладке SPI столкнулся с очень странным глюком. Я пытаюсь послать команду на запись в буфер DataFlash последовательности байт по нулевому адресу. Код выглядит так:

Код
BYTE init_buffer[]={0x84,0x00,0x00,0x00};//опкод и адрес
FIO4CLR=1<<21;//инверсный Chip Select
SSP1Send(init_buffer,4);//собственно, послали
...
FIO4SET=1<<21;инверсный Chip Select


Вот так выглядит функция SSP1Send:
Код
void SSP1Send( BYTE *buf, DWORD Length )
{
  DWORD i;  
  for ( i = 0; i < Length; i++ )
  {
    /* as long as TNF bit is set (TxFIFO is not full), I can always transmit */
    while ( !(SSP1SR & SSPSR_TNF) );
    SSP1DR = *buf;
    buf++;
    /* Wait until the Busy bit is cleared */
    while ( !(SSP1SR & SSPSR_BSY) );
  }
  return;
}


На логическом анализаторе видно, что после отправки 1 байта (0х84) Chip Select самопроизвольно переходит обратно в единицу, таким образом все последующие байты игнорируются. Если вызвать функцию SSP1Send с такими параметрами 2 раза, то же происходит после отправки 3 байт. Что это такое? может ли микросхема DataFlash сама поднимать Chip Select?
aaarrr
Код
    /* Wait until the Busy bit is cleared */
    while ( !(SSP1SR & SSPSR_BSY) );

Сравните код и комментарий.
SII
Цитата(lecko @ Oct 5 2011, 10:44) *
может ли микросхема DataFlash сама поднимать Chip Select?


Естественно, нет: она только принимает сигнал. А вообще, _внимательно_ прочитайте раздел насчёт контроллеров SSP и изучите приведённые в нём диаграммы работы интерфейса SPI. В двух возможных режимах (сочетаниях CPOL и CPHA) из четырёх SSP будет на короткое время убирать SSEL после отправки каждого символа, даже если в FIFO есть другие символы для отправки. Ну и уж в любом случае SSEL будет снят, если передача завершена (FIFO опустел), так что для поддержания непрерывно низкого уровня SSEL надо не только указать правильные CPOL и CPHA, но ещё и успевать засовывать в SSP новый символ до того, как завершится передача предыдущего.

Пы.Сы. Приводимый в сообщениях код я принципиально не смотрю. ИМХО, каждый должен _сам_ искать у себя ошибки, ну а дело форумов и т.п. -- подсказывать общую идею или ещё что в этом роде.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.