WIZnet Developer Forum

[W5500] 개별 SPI 포트를 통한 2개 이상의 W5500 제어 문의

안녕하세요.

독립적인 2개의 SPI 포트를 사용하여 2개의 W5500을 각각 제어 하려고 합니다.

STM32F4 MCU의 SPI1 과 SPI2 포트가 각각의 W5500 Chip 에 연결되어 있고,
W5500 HAL Interface 라이브러리(version 1.0.0, <date 2013/10/21>, <Revision 2015/02/05>)를
사용하고 있습니다.

W5500 한개만 활성화 하는 방식으로, 각각의 SPI 포트를 통해 제어 했을 때는
정상적으로 동작하는것을 확인 하였습니다.
하지만 2개의 W5500을 동시에 활성화 하여 제어하려고 하니,
마지막으로 활성화 한 SPI 포트에 연결된 Chip 만 정상적으로 동작합니다.

사용하고 있는 '“W5500 HAL Interface 라이브러리” 확인해보니,
제어 시 SPI 포트를 특정하여 제어하는것이 가능하지 않은 것 같아
SPI 포트를 특정하여 제어 할 수 있는 방법을 문의 드립니다.

아래는 기본 소스의 W5500_init() 함수를 SPI 포트별로 Init 해보려고
수정해본 내용 입니다. (개별 SPI 포트를 사용하도록 Callback 을 분리하여 등록하여 보았는데,
동작하지는 않습니다.)

    void W5500_Init(SPI_TypeDef* SPIx)
    {
        /*!< Deselect the FLASH: Chip Select high */
        if (SPIx == ETH1_SPI) {wizchip_deselect();}
        else                  {wizchip_deselect2();}
    
        // Wiznet
        if (SPIx == ETH1_SPI) {
            reg_wizchip_cs_cbfunc(wizchip_select, wizchip_deselect);
            reg_wizchip_spi_cbfunc(wizchip_read, wizchip_write);
        }
        else {
            reg_wizchip_cs_cbfunc2(wizchip_select2, wizchip_deselect2);
            reg_wizchip_spi_cbfunc2(wizchip_read2, wizchip_write2);     
        }
    
        /* wizchip initialize*/
      uint8_t tmp;
        uint8_t memsize[2][8] = { {2,2,2,2,2,2,2,2},{2,2,2,2,2,2,2,2}};
    

       
        if(ctlwizchip(CW_INIT_WIZCHIP,(void*)memsize) == -1) {
            #ifdef DEV_INFO_PRINT_EN
            uPrintf(DBG_PORT, "WIZCHIP Initialized fail.\r\n");
            #endif
            return;
        }  // **<=== 이런부분에서 어떤 SPI 포트를 통해 제어가 되는것인지... ** 


    
        /* PHY link status check */
      do {
          if(ctlwizchip(CW_GET_PHYLINK, (void*)&tmp) == -1) {
              uPrintf(DBG_PORT, "Unknown PHY Link status.\r\n");
              return;
          }
      } while (tmp == PHY_LINK_OFF);
    }

//-----------------------------------------------------------------------------------------------------------------------------------
// Callback 함수 아래와 같이 분리해 보았습니다.

    void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb))
    {
       while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_));
    
       if(!spi_rb || !spi_wb)
       {
          WIZCHIP.IF.SPI._read_byte   = wizchip_spi_readbyte;
          WIZCHIP.IF.SPI._write_byte  = wizchip_spi_writebyte;
       }
       else
       {
          WIZCHIP.IF.SPI._read_byte   = spi_rb;
          WIZCHIP.IF.SPI._write_byte  = spi_wb;
       }
    }
            
    void reg_wizchip_spi_cbfunc2(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb))
    {
       while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_));
    
       if(!spi_rb || !spi_wb)
       {
          WIZCHIP.IF.SPI._read_byte   = wizchip_spi_readbyte;
          WIZCHIP.IF.SPI._write_byte  = wizchip_spi_writebyte;
       }
       else
       {
          WIZCHIP.IF.SPI._read_byte   = spi_rb;
          WIZCHIP.IF.SPI._write_byte  = spi_wb;
       }
    }

//-----------------------------------------------------------------------------------------------------------------------------------

쉬운 답변이 안나오네요.
콜백을 나누어서 Init 하신 시도는 맞는 것 같은데,
다른 함수들은 칩인덱스 같은 것을 받지 않기 때문에 (즉, 모든 함수에 init에서 수정하신 대로 SPI_TypeDef* SPIx을 넘겨줘서 어떤 칩을 제어할 것인지 함수가 알도록 하고 내부 내용도 수정하고 해야 하는데, 현재 드라이버는 그런 설계가 안되어 있죠 )
말씀하신 대로 뒤에 당연히 마지막에 활성화 한 SPI 에 연결된 칩만 정상동작할 것입니다.

이렇게 주석을 작성해 두셨는데, 주석에 언급한대로 ctlwizchip() 이란 함수는 따로 2개의 인터페이스로 동작하는 것을 가정한 게 아니므로 최종 활성화된 정보가 덮어써지는 개념이 되니 그냥 마지막에 등록된 SPI로만 동작이 될 것입니다.
쉽지 않네요. 기존의 드라이버가 2개 이상을 가정하고 설계된 것이 아니라 전체적으로 다 손을 봐야 합니다.
한다고 결정을 해도 드라이버를 업데이트 하는 작업 일정이 쉽게 끝날 것 같지 않습니다.

해결 솔루션을 드리지 못해 죄송합니다. 그래도 하나 아이디어를 생각해보면

Ethernet/wizchip_conf.h 에 보면,

extern _WIZCHIP_T_  WIZCHIP;  ///< @ref WIZCHIP is an instance of @ref _WIZCHIP_T_ to access @ref _WIZCHIP_.

이 구조체는 현재 1개만을 사용하는 것으로 가정하고 있기 때문에 질문 주신 형태로 구성하려면 최소 2개의 구조체 인스턴스가 선언되고, 이것을 각각 불러 쓰도록 모든 함수에 변경을 해 나가면 길이 보일 것 같습니다.

답변 감사합니다.

하드웨어 설계해놓고 잘 안되서 들여다 보기 시작한 부분인데, 역시나 그렇군요…ㅜㅜ
일단 답변주신 방법으로 시도를 해보도록 하겠습니다.

[추가질문]
추가적으로 문의 드리고 싶은 부분은 2개 이상의 W5500 Chip을 사용하는 경우
하드웨어 상에서 SPI 포트를 공유하고, Chip Select 라인을 개별제어 하게 되면
제공하는 W5500 HAL Interface 라이브러리를 사용해서 제어가 가능 할까요?

2개 이상의 동일 칩셋을 사용하는 경우에 대해 WIZnet 에서 권장하는 설계 가이드라인이
있는지 확인 부탁드립니다.

위에서 말씀하신거처럼 변경을 하실경우 HAL 라이브러리를 사용할수 있을 것으로 보입니다.
2개 이상의 동일한 칩셋을 사용하는 경우의 하드웨어 가이드는 별도로 제공하고 있지는 않습니다.

그렇지만 하드웨어 설계가 완료된 후, 하드웨어 엔지니어에서 해당 회로도를 컨펌 받으실 수 있습니다.

Copyright © 2017 WIZnet Co., Ltd. All Rights Reserved.