[W5100] SPI 연결시 RD 문제

[W3150A+] [W5100] [W5200] [W5300] [W5500] [W5100S]

사용 중인 제품 명을 위와 같이 제목에 명기하시면 더 빠른 응답을 받으실 수 있습니다.
본 Template을 삭제 후 문의 내용을 남겨 주세요. :slight_smile:

안녕하세요. 5200만 쓰다가 5100을 더 레커맨드 하신다고 해서 이번에 칩을 바꿨습니다.
더불어 CPU 도 바꾸면서 라이브러리까지 (STM LL driver ) 변경하게되니 문제가 많은것 같습니다.
그전에 5200에서는 제공되는 방법으로 SPI 방식의 WR, RD 가 문제가 없었는데, 이번에 5100으로 READ 하는부분에서는 문제가 되는데요,
제공된 함수를 사용하여, WR는 성공하였습니다. ( 어떻게 아냐면, IP 설정후 ping을 걸어보면 chip에 저장이 되었으니 응답을 했겠지요)
그런데 inchip_read를 해보면 한바이트 걸러 타임아웃이 걸려서 잘못읽어옵니다.
in chip 에서 마지막 바이트가 아니고 더미바이트 보내는 부분에서 읽으면 한번은 0, 한번은 2로 읽어오고요.
그래서 inchip read 에서 일부러 두번을 보내서 두번째 읽는 바이트로 제대로된 결과를 읽어오기는 했는데 ( 코멘트해놓은 부분의 이유) 막상 셋팅말고 핑으로 테스트를 해보니 안되네요. 그전에 5200에서 사용하던 소스를 이용해서 핑은 바로 될줄알았거든요. 0x63이 들어옵니다. 데이터시트에 없는값이던데여…
별짓 다해봐도 이현상이 해결되지 않네요…

스코프를 이용해서 찍어보니, 바이트 바이트 보낼때 MISO신호가 가끔 다음바이트 까지 떨어지지 않고 유지되것을 확인할 수 있었습니다. 나머지 타이밍은 모두 체크해서 안전 타이밍 확인했습니다. 외국포럼에 타이밍이 문제가 되어 읽히지 않았다는 글을보고 모두 늘여봤습니다… 안되네요
addr라인을 풀다운을 걸지 않았는데 혹시 이런 이유때문일까요? 비슷한 현상을 보신 분이 있는지요?
도움 부탁드립니다.

#define IINCHIP_SpiSendData     SPI2_SendByte

uint8_t SPI2_SendByte(uint8_t byte)
{
    TimeOutSPI2 = SPI_TIMEOUT_MAX;
    while( !LL_SPI_IsActiveFlag_TXE(SPI2) ){
        if (TimeOutSPI2-- == 0) return IOE_TIEMOUT;
    }    
    *((__IO uint8_t *)&SPI2->DR) = byte;
    //LL_SPI_TransmitData8(SPI2, byte);
    
    TimeOutSPI2 = SPI_TIMEOUT_MAX;
    while( !LL_SPI_IsActiveFlag_RXNE(SPI2) ){
        if (TimeOutSPI2-- == 0) return IOE_TIEMOUT;
    }
    return SPI2->DR;//LL_SPI_ReceiveData8(SPI2);
}

uint8 IINCHIP_WRITE(uint16 addr,uint8 data)
{
    IINCHIP_ISR_DISABLE();                      // Interrupt Service Routine Disable

	IINCHIP_CS_L;                            // CS=0, SPI start

	IINCHIP_SpiSendData(0xF0);  
	IINCHIP_SpiSendData((uint8)((addr & 0xFF00) >> 8));  // Address byte 1
	IINCHIP_SpiSendData((uint8)(addr & 0x00FF));         // Address byte 2

	IINCHIP_SpiSendData(data);                      // Data write (write 1byte data)
    
	IINCHIP_CS_L;                               // CS=0, SPI start
	IINCHIP_CS_H;                               
    
    IINCHIP_ISR_ENABLE();                           // Interrupt Service Routine Enable
        
	return 1;
}

uint8 IINCHIP_READ(uint16 addr)
{
	uint8 data;
    
	IINCHIP_ISR_DISABLE();                       // Interrupt Service Routine Disable
        
	IINCHIP_CS_L;                               // CS=0, SPI start
    
    IINCHIP_SpiSendData(0x0F);  
	
    IINCHIP_SpiSendData((addr & 0xFF00) >> 8);   // Address byte 1
	IINCHIP_SpiSendData(addr & 0x00FF);          // Address byte 2
	IINCHIP_SpiSendData(0x00);
    data = IINCHIP_SpiSendData(0x00);
    IINCHIP_CS_L;                            // CS=0, SPI start
    
    IINCHIP_CS_H;                               // CS=1,  SPI end
    
	/*IINCHIP_CS_L;                               // CS=0, SPI start    
	IINCHIP_ISR_DISABLE();                       // Interrupt Service Routine Disable
        IINCHIP_SpiSendData(0x0F);  
	
        IINCHIP_SpiSendData((addr & 0xFF00) >> 8);   // Address byte 1
	IINCHIP_SpiSendData(addr & 0x00FF);          // Address byte 2
	IINCHIP_SpiSendData(0x00);
	data = IINCHIP_SpiSendData(0x00);            // Data read (read 1byte data)
    
	IINCHIP_CS_L;                               // CS=0, SPI start
        IINCHIP_CS_H;                               // CS=1,  SPI end
    */
    IINCHIP_ISR_ENABLE();                        // Interrupt Service Routine Enable
	return data;
}

IINCHIP_READ 함수에서…

  IINCHIP_SpiSendData(0x0F);  
  IINCHIP_SpiSendData((addr & 0xFF00) >> 8);   // Address byte 1
  IINCHIP_SpiSendData(addr & 0x00FF);          // Address byte 2
//IINCHIP_SpiSendData(0x00);
data = IINCHIP_SpiSendData(0x00);

데이터를 한번 보내고 읽으셨네요.
변경 후 테스트 해보시길 바랍니다.

thanks,
irina