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

 
 
> Странное поведение ARM+SPI DataFlash
lecko
сообщение Oct 3 2011, 13:59
Сообщение #1





Группа: Участник
Сообщений: 10
Регистрация: 22-08-11
Пользователь №: 66 820



Имеется тестовый код для 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 нет (точнее есть один, в момент получения команды). Откуда берутся эти "мусорные" байты?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 7)
aaarrr
сообщение Oct 3 2011, 14:12
Сообщение #2


Гуру
******

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



Цитата(lecko @ Oct 3 2011, 17:59) *
Откуда берутся эти "мусорные" байты?

Из приемного FIFO, надо полагать. SSP1Send его ведь не чистит.
Go to the top of the page
 
+Quote Post
skripach
сообщение Oct 3 2011, 14:16
Сообщение #3


■ ■ ■ ■
*****

Группа: Свой
Сообщений: 1 100
Регистрация: 9-08-06
Пользователь №: 19 443



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


--------------------
Делай что должен и будь что будет.
Go to the top of the page
 
+Quote Post
lecko
сообщение Oct 3 2011, 14:23
Сообщение #4





Группа: Участник
Сообщений: 10
Регистрация: 22-08-11
Пользователь №: 66 820



Цитата(aaarrr @ Oct 3 2011, 18:12) *
Из приемного FIFO, надо полагать. SSP1Send его ведь не чистит.


Просто и логично) спасибо, помогло! Для тех, кто будет в том же танке что и я прилагаю код, который необходимо добавить:
Код
BYTE i,Dummy;
for(i=0;i<FIFOSIZE;i++) Dummy=SSP1DR;
Go to the top of the page
 
+Quote Post
SII
сообщение Oct 3 2011, 14:48
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414



Я недавно делал драйвер для обмена по ссп, ну и тоже намучился из-за собственной нелепой ошибки. Забыл о том, что прерывание приходит не по заполненности очереди приёмника до конца, а при заполненности наполовину, ну и гнал байты-заполнители для чтения лишние. Сейчас вот медитирую над нормальным использованием ПДП (у НХПшных МК контроллер централизованный, не как у АТМЕЛа, где у каждого СПИ или УСАРТа свой контроллер ПДП).
Go to the top of the page
 
+Quote Post
lecko
сообщение Oct 5 2011, 06:44
Сообщение #6





Группа: Участник
Сообщений: 10
Регистрация: 22-08-11
Пользователь №: 66 820



В продолжение темы.
При отладке 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?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Oct 5 2011, 07:31
Сообщение #7


Гуру
******

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



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

Сравните код и комментарий.
Go to the top of the page
 
+Quote Post
SII
сообщение Oct 5 2011, 10:31
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414



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


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

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

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 14:49
Рейтинг@Mail.ru


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