cs8900內部有兩種訪問內部寄存器的方式:
cs8900a網卡驅動移植
cs8900內部有兩種訪問內部寄存器的方式:
1. I/O模式: 就是非統一編址的情況中使用in/out等特殊指令訪問的方式。接到獨立的io總線上面。
2. memory模式: 統一編址,和訪問內存一樣,接到地址總線上。
由兩根線決定使用I/O模式還是memory模式,AEN 和 A[24]
___ _____
AEN + A[24] ---> I/O 模式
AEN + A[24] ---> memory 模式
cs8900接在2號blank中,所以基地址爲0x18000000,但是由因爲s3c2440是統一編址的,所以我們需要選用memory模式,所以第24位一定要1,所以我們訪問cs8900的時候基地址爲0x19000000.
cs8900訪問寄存器的方法比較特別,0x19000000其實還不是寄存器的基地址,手冊告訴我們"I/O Base Address"是0x300,所以基地址是0x19000300. 而只cs8900只有3個地址可以訪問:
0x19000300 + 0x00 Tx/Rx data 這個地址用來發送和接收數據用的。
如果要訪問其他的寄存器,就要用下面的方法:
1. 0x19000300 + 0x0a 把我們要訪問的寄存器的偏移寫到這個地址中,告訴cs8900我們要訪問那個寄存器
2. 0x19000300 + 0x0c 現在我們可以通過訪問這個地址來操作那個寄存器。
注意,cs8900的所有數據和寄存器都是16位的。
中斷:
+--------+ +---------+
電頻中斷 | | 邊沿觸發 | |
.------| CS8900 |--. .--. .--. | arm920t |
-----' | | '--' '--' '--| |
物理網口 +--------+ EINT9 外部中斷 +---------+
test_setup:
1. ioremap 0x19000000 --> virt
2. base_addr = virt + 0x300
test_open:
1. 用base_addr + 0x0a 寫寄存器的地址
用base_addr + 0x0c 操作這個地址就可以操作對應的寄存器,包括讀和寫
2. request_irq
test_tx:
1. 配置相應的寄存器
2. 將要發送的數據連續寫入base_addr+0x00
test_rx:
1. 讀取相應寄存器的狀態
2. 從base_addr+0x00連續讀入收到的地址
cs8900關於內存的初始化有兩個寄存器:
1. BWSCON 設置2號blank的位寬,cs8900用16位寬,設置enable
WAIT,因爲cs8900採用20M的時鐘,不能像內存那麼快,所以我們要wait.還有要設置UB/LB,這一位是什麼意思呢?就是說如果上面我們選用了16bit的位寬,但是又想以字節爲單位訪問內存,如果不設置這一位的話,用ldrb指令也不能按照bytes來取數據,這個能不能按照bytes來取數據最後還是要看接在總線上的設備支不支持,所以不是所有接在總線上面的設備都可以按照byte來訪問。
2. BANKCON1 設置cs8900在內存控制器這邊的時序,cs8900的時序在手冊中找到。
3.由於每個板子的地址不一樣,那些引腳的初始化,還有讀寫的執行。沒有提到。
一. 根據原理圖,確認網卡的地址和中斷號
地址:0x19000000
中斷號: EINT9
二. 修改drivers/net/ethernet/cirrus/cs89x0.c,指定CS8900A使用的資源
186 #elif defined(CONFIG_ARCH_S3C2410)
187 #include <mach/regs-mem.h>
188 #define S3C24XX_PA_CS8900 0x19000000
189 static unsigned int netcard_portlist[] __initdate = {0, 0};
190 static unsigned int cs8900_irq_map[] = {IRQ_EINT9, 0, 0, 0};
三. 修改入口函數cs89x0_probe
1.
#if defined(CONFIG_ARCH_S3C2410)
unsigned int oldval_bwscon;
unsigned int oldval_bankcon3;
#endif
2. 設置MAC,總線寬度等:
#if defined(CONFIG_ARCH_S3C2410)
if(netcard_portlist[0])
return -ENODEV;
netcard_portlist[0] = (unsigned int)ioremap(S3C24XX_PA_CS8900, SZ_1M) + 0x300;
dev->dev_addr[0] = 0x08;
dev->dev_addr[1] = 0x89;
dev->dev_addr[2] = 0x89;
dev->dev_addr[3] = 0x89;
dev->dev_addr[4] = 0x89;
dev->dev_addr[5] = 0x89;
oldval_bwscon = *((volatile unsigned int *)S3C2410_BWSCON);
*((volatile unsigned int *)S3C2410_BWSCON) = (oldval_bwscon & ~(3<<12)) | S3C2410_BWSCON_DW3_16 | S3C2410_BWSCON_WS3 | S3C2410_BWSCON_ST3;
oldval_bankcon3 = *((volatile unsigned int *)S3C2410_BANKCON3);
*((volatile unsigned int *)S3C2410_BANKCON3) = 0x1f7c;
#endif
3. 出錯退出
out:
#if defined(CONFIG_ARCH_S3C2410)
iounmap(netcard_portlist[0]);
netcard_portlist[0] = 0;
*((volatile unsigned int *)S3C2410_BWSCON) = oldval_bwscon;
*((volatile unsigned int *)S3C2410_BANKCON3) = oldval_bankcon3;
#endif
free_netdev(dev);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.