Porting Guides

LinuxNote List-page
PREVIOUS: Note2 – Hardware Connections

Hardware Configuration in mach-W5300e-1.c

아래 경로의 Target board 설정파일인 mach-w5300e01.c를 이용하여 W5500관련한 Hardware관련 Configuration을 한다.
linux/arch/arm/mach-s3c2410/

  • SPI pin configuration
    //static void __init w5300e01_init(void)
    
    /* W5500 SPI pin */
    s3c2410_gpio_cfgpin(S3C2410_GPF1, S3C2410_GPF1_OUTP); //SCS
    s3c2410_gpio_setpin(S3C2410_GPF1, 1); //low active
    s3c2410_gpio_cfgpin(S3C2410_GPE13, S3C2410_GPE13_SPICLK0); //SCLK
    s3c2410_gpio_setpin(S3C2410_GPE13, 1);
    s3c2410_gpio_cfgpin(S3C2410_GPE12, S3C2410_GPE12_SPIMOSI0); //MOSI
    s3c2410_gpio_setpin(S3C2410_GPE12, 1);
    s3c2410_gpio_cfgpin(S3C2410_GPE11, S3C2410_GPE11_SPIMISO0); //MISO
    s3c2410_gpio_setpin(S3C2410_GPE11, 1);
    
    
  • Interrupt Reauest (IRQ) pin Configaration
    //static void __init w5300e01_init(void)
    
    /* W5500 interrupt pin */
    s3c2410_gpio_cfgpin(S3C2410_GPG2, S3C2410_GPG2_EINT10); //GPG2 Interrupt
    s3c2410_gpio_setpin(S3C2410_GPG2, 1); //low active
    
  • Reset pin configration
    //static void __init w5300e01_init(void)
    
    /* W5500 Reset pin */
    s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP);
    s3c2410_gpio_setpin(S3C2410_GPF6, 1);
    
  • Virtual Base address configration
    static struct map_desc w5300e01_iodesc[] __initdata = {
      { 0xf0000000, __phys_to_pfn(S3C2410_CS2), SZ_1M, MT_DEVICE },
      { 0xf8000000, __phys_to_pfn(S3C2410_CS3), SZ_1M, MT_DEVICE },
      { 0xe8000000, __phys_to_pfn(S3C2410_PA_SPI), SZ_1M, MT_DEVICE } 
    };
    
    

W5500 Linux Driver Porting

이부분은 Target MCU와 Target MCU의 SPI에 의존적인 부분으로 Target MCU와 SPI의 특성을 이해하고 설정하여야 한다.

  • Enable PCLK into SPI block
    //dev.c
    void iinchip_spiclock_init(void)
    {
        ...
        reg = ioremap((unsigned long)rCLKCON, 4);
        *reg |= 0x40000;
        ...
    }
    
  • Control: polling mode / SPI Clock enable / master select / CPOL =0 / CPHA =0 /etc…
    //spi.h
    (*(volatile unsigned char *)(_rSPCON0) = (0x18)) 
    
  • baudrate: PCLK / 2 / ((SPPRE0) + 1)
    //spi.h
    (*(volatile unsigned char *)(_rSPPRE0) = (0x02));
    
  • IRQ
    //module.c
    wiz_module_init(void)
    {
        ...
        gDrvInfo.irq  = IRQ_EINT10;
        ...
    }
    
  • Chip Select
    //spi.h
    #define IINCHIP_CSon(Cs)                    (*_rGPFDAT) |= 0x2
    #define IINCHIP_CSoff(Cs)                   (*_rGPFDAT) &= 0xfffffffd
    
  • Default MAC address
    W5500에 Default MAC address를 Write하는 부분이며, kernel에서 ifconfig를 이용하여 MAC Address를 변경할 수 도 있다.

    //module.c
    static unsigned char defmac[] = { 0x00, 0x08, 0xDC, 0x91, 0x97, 0x98 };
    
    static int __init
    wiz_module_init(void)
    {
        ...
        /* mac address */
        memcpy(gDrvInfo.macaddr, defmac, 6);
        ...
    }
    
  • Socket buffer size 설정
    W5500에는 8개의 Socket이 존재하나, MACRAW type으로 W5500을 MAC/PHY로 사용할 것이기 때문에
    Socket 0번에만 TX/RX buffer를 각각 8KBytes로 설정한다. (MACRAW mode는 Socket 0번 사용가능하다.)

    //dev.cstatic unsigned char txsize[MAX_SOCK_NUM] = {
    8, 0, 0, 0, 0, 0, 0, 0
    };
    static unsigned char rxsize[MAX_SOCK_NUM] = {
    8, 0, 0, 0, 0, 0, 0, 0
    };
    
    void iinchip_sysinit(void)
    {
        ...
        for (i = 0 ; i < MAX_SOCK_NUM; i++) {
    
            /* Set Buffer Size */
            iinchip_outb(TX_BUF_SIZE_PTR(i), txsize[i]);
            iinchip_outb(RX_BUF_SIZE_PTR(i), rxsize[i]);
    
        ...
    }
    
  • SPI READ / WRITE Functions
    Target MCU가 변경시 아래의 #define부분 들을 수정하여 SPI Read/Write를 구현할 수 있다.

    //spi.h
    #define SPI0_RxData()                   (*(volatile unsigned char *)(_rSPRDAT0)) //(ioread8(_rSPRDAT0))
    
    #define SPI0_TxData(Data)               (*(volatile unsigned char *)(_rSPTDAT0) = (Data)) //(iowrite8(Data, _rSPTDAT0
    #define SPI0_WaitForSend()              while(!((*(volatile unsigned char *)(_rSPSTA0)) & 0x01)) //while(!(ioread8(_rSPSTA0) & 0x01))
    
    #define SPI0_SendByte(Data)             SPI0_TxData(Data);SPI0_WaitForSend()
    #define SPI0_RecvBute()                 SPI0_RxData()
    
    
  • Hardware Reset for W5500
    //dev.c
    void iinchip_hwreset(void)
    {
        s3c2410_gpio_setpin(S3C2410_GPF6, 0);
        mdelay(1);
        s3c2410_gpio_setpin(S3C2410_GPF6, 1);
        mdelay(2);
        mdelay(3000);// WIZ550IO Need for MCU which is embedded on Board.
    }
    
    

NEXT: Note4 – How to test the W5500 Linux driver

Leave a comment