Имеется тестовый код для ARM7, запрашивающий ID у микросхемы Atmel SPI DataFlash: Код (Text): 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 На практике имеем следующее: Код (Text): 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 нет (точнее есть один, в момент получения команды). Откуда берутся эти "мусорные" байты?
Lecko Не читал даташит, но чисто интуитивно (пальцем в небо) отсутствует ожидание после записи внутри SSP1Receive: Код (Text): ... SSP1DR = 0xFF; while ( !(SSP1SR & SSPSR_BSY) ); //<-- missing line while ( !(SSP1SR & SSPSR_RNE) ); *buf = SSP1DR; ...
В продолжение темы. При отладке SPI столкнулся с очень странным глюком. Я пытаюсь послать команду на запись в буфер DataFlash последовательности байт по нулевому адресу. Код выглядит так: Код (Text): BYTE init_buffer[]={0x84,0x00,0x00,0x00};//опкод и адрес FIO4CLR=1<<21;//инверсный Chip Select SSP1Send(init_buffer,4);//собственно, послали ... FIO4SET=1<<21;инверсный Chip Select Вот так выглядит функция SSP1Send: Код (Text): 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?
Предыдущая ошибка найдена. неверная функция SSP1Send. Должно быть так: Код (Text): 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|SSPSRBSY)!=SSPSR_TNF) ); SSP1DR = *buf; buf++; /* Wait until the Busy bit is cleared */ while ( (SSP1SR & SSPSR_BSY) ); } return; } но возник следующий вопрос: почему сразу после команды записи из буфера на SPI DataFlash может не отрабатывать команда чтения? Микропроцессор ARM7 NXP LPC2478, микросхема памяти Atmel 45DB321D