lecko 0 3 октября, 2011 Опубликовано 3 октября, 2011 · Жалоба Имеется тестовый код для 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 68 3 октября, 2011 Опубликовано 3 октября, 2011 · Жалоба Откуда берутся эти "мусорные" байты? Из приемного FIFO, надо полагать. SSP1Send его ведь не чистит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
skripach 5 3 октября, 2011 Опубликовано 3 октября, 2011 · Жалоба Первый 0xff это принятый байт соответствующий переданному байту команды. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lecko 0 3 октября, 2011 Опубликовано 3 октября, 2011 · Жалоба Из приемного FIFO, надо полагать. SSP1Send его ведь не чистит. Просто и логично) спасибо, помогло! Для тех, кто будет в том же танке что и я прилагаю код, который необходимо добавить: BYTE i,Dummy; for(i=0;i<FIFOSIZE;i++) Dummy=SSP1DR; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SII 0 3 октября, 2011 Опубликовано 3 октября, 2011 · Жалоба Я недавно делал драйвер для обмена по ссп, ну и тоже намучился из-за собственной нелепой ошибки. Забыл о том, что прерывание приходит не по заполненности очереди приёмника до конца, а при заполненности наполовину, ну и гнал байты-заполнители для чтения лишние. Сейчас вот медитирую над нормальным использованием ПДП (у НХПшных МК контроллер централизованный, не как у АТМЕЛа, где у каждого СПИ или УСАРТа свой контроллер ПДП). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lecko 0 5 октября, 2011 Опубликовано 5 октября, 2011 · Жалоба В продолжение темы. При отладке 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 68 5 октября, 2011 Опубликовано 5 октября, 2011 · Жалоба /* Wait until the Busy bit is cleared */ while ( !(SSP1SR & SSPSR_BSY) ); Сравните код и комментарий. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SII 0 5 октября, 2011 Опубликовано 5 октября, 2011 · Жалоба может ли микросхема DataFlash сама поднимать Chip Select? Естественно, нет: она только принимает сигнал. А вообще, _внимательно_ прочитайте раздел насчёт контроллеров SSP и изучите приведённые в нём диаграммы работы интерфейса SPI. В двух возможных режимах (сочетаниях CPOL и CPHA) из четырёх SSP будет на короткое время убирать SSEL после отправки каждого символа, даже если в FIFO есть другие символы для отправки. Ну и уж в любом случае SSEL будет снят, если передача завершена (FIFO опустел), так что для поддержания непрерывно низкого уровня SSEL надо не только указать правильные CPOL и CPHA, но ещё и успевать засовывать в SSP новый символ до того, как завершится передача предыдущего. Пы.Сы. Приводимый в сообщениях код я принципиально не смотрю. ИМХО, каждый должен _сам_ искать у себя ошибки, ну а дело форумов и т.п. -- подсказывать общую идею или ещё что в этом роде. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться