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
댓글 없음:
댓글 쓰기