2014년 11월 26일 수요일

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

    [code lang=cpp]
    //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);

    [/code]

  • Interrupt Reauest (IRQ) pin Configaration

    [code lang=cpp]
    //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
    [/code]

  • Reset pin configration

    [code lang=cpp]
    //static void __init w5300e01_init(void)

    /* W5500 Reset pin */
    s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP);
    s3c2410_gpio_setpin(S3C2410_GPF6, 1);
    [/code]

  • Virtual Base address configration

    [code lang=cpp]
    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 }
    };

    [/code]



W5500 Linux Driver Porting



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


  • Enable PCLK into SPI block

    [code lang=cpp]
    //dev.c
    void iinchip_spiclock_init(void)
    {
    ...
    reg = ioremap((unsigned long)rCLKCON, 4);
    *reg |= 0x40000;
    ...
    }
    [/code]

  • Control: polling mode / SPI Clock enable / master select / CPOL =0 / CPHA =0 /etc...

    [code lang=cpp]
    //spi.h
    (*(volatile unsigned char *)(_rSPCON0) = (0x18))
    [/code]

  • baudrate: PCLK / 2 / ((SPPRE0) + 1)

    [code lang=cpp]
    //spi.h
    (*(volatile unsigned char *)(_rSPPRE0) = (0x02));
    [/code]

  • IRQ

    [code lang=cpp]
    //module.c
    wiz_module_init(void)
    {
    ...
    gDrvInfo.irq = IRQ_EINT10;
    ...
    }
    [/code]

  • Chip Select

    [code lang=cpp]
    //spi.h
    #define IINCHIP_CSon(Cs) (*_rGPFDAT) |= 0x2
    #define IINCHIP_CSoff(Cs) (*_rGPFDAT) &= 0xfffffffd
    [/code]

  • Default MAC address
    W5500에 Default MAC address를 Write하는 부분이며, kernel에서 ifconfig를 이용하여 MAC Address를 변경할 수 도 있다.

    [code lang=cpp]
    //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);
    ...
    }
    [/code]

  • Socket buffer size 설정
    W5500에는 8개의 Socket이 존재하나, MACRAW type으로 W5500을 MAC/PHY로 사용할 것이기 때문에
    Socket 0번에만 TX/RX buffer를 각각 8KBytes로 설정한다. (MACRAW mode는 Socket 0번 사용가능하다.)

    [code lang=cpp]
    //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]);

    ...
    }
    [/code]

  • SPI READ / WRITE Functions
    Target MCU가 변경시 아래의 #define부분 들을 수정하여 SPI Read/Write를 구현할 수 있다.

    [code lang=cpp]
    //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()

    [/code]

  • Hardware Reset for W5500

    [code lang=cpp]
    //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.
    }

    [/code]



NEXT: Note4 - How to test the W5500 Linux driver