Перейти к содержанию
    

Странное поведение ARM+SPI DataFlash

Имеется тестовый код для 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 нет (точнее есть один, в момент получения команды). Откуда берутся эти "мусорные" байты?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Откуда берутся эти "мусорные" байты?

Из приемного FIFO, надо полагать. SSP1Send его ведь не чистит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Первый 0xff это принятый байт соответствующий переданному байту команды.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Из приемного FIFO, надо полагать. SSP1Send его ведь не чистит.

 

Просто и логично) спасибо, помогло! Для тех, кто будет в том же танке что и я прилагаю код, который необходимо добавить:

BYTE i,Dummy;
for(i=0;i<FIFOSIZE;i++) Dummy=SSP1DR;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я недавно делал драйвер для обмена по ссп, ну и тоже намучился из-за собственной нелепой ошибки. Забыл о том, что прерывание приходит не по заполненности очереди приёмника до конца, а при заполненности наполовину, ну и гнал байты-заполнители для чтения лишние. Сейчас вот медитирую над нормальным использованием ПДП (у НХПшных МК контроллер централизованный, не как у АТМЕЛа, где у каждого СПИ или УСАРТа свой контроллер ПДП).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В продолжение темы.

При отладке 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?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

    /* Wait until the Busy bit is cleared */
    while ( !(SSP1SR & SSPSR_BSY) );

Сравните код и комментарий.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

может ли микросхема DataFlash сама поднимать Chip Select?

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...