調試MPC8315E SPI EEPROM心得
最近領導交代任務,說幫忙改一個MPC8315E的U-boot程序,添加幾個命令,主要是處理spi eeprom和nvram相關東西的。好吧,領導都開口了,我弄沒弄過u-boot都得直接上了。好吧,我以前沒有弄過。
從領導那里將u-boot的拷貝過來,用之前自己搭建8315開發(fā)環(huán)境,編譯直接過了。下載調試發(fā)現(xiàn)是工程上的源碼。好了,想想NVRAM就是直接操作內存啊,沒啥難度。就先搞spi eeprom了。
測試驅動
先看了看u-boot的源碼結構,源碼版本是u-boot1.3.4的,發(fā)現(xiàn)在 drivers/spi/mpc8xxx_spi.c 對比下發(fā)現(xiàn)適用于MPC8315E,好了先直接嘗試默認程序是否可用吧。這里就不賣關子了。主要操作我寫在下面:
-
在相關板子頭文件中添加相關定義,舉例如下: include/configs/MPC8315ERDB.h 添加下列定義:
#define CONFIG_MPC8XXX_SPI #define CONFIG_HARD_SPI
如果添加的位置正確,相關的spi驅動會被編譯成*.o文件,這里我的驅動在編譯完成在: drivers/spi/mpc8xxx_spi.o 中。
-
由于該驅動框架貌似不完整,需要添加點內容,這里我在mpc8xxx_spi.c文件進行了補充如下:
/* * The following are used to control the SPI chip selects for the SPI command. */ #ifdef CONFIG_MPC8XXX_SPI #define SPI_CS_MASK 0x80000000 int spi_cs_is_valid(unsigned int bus, unsigned int cs) { return bus == 0 && cs == 0; } void spi_cs_activate(struct spi_slave *slave) { volatile gpio83xx_t *iopd = &((immap_t *)CFG_IMMR)->gpio[0]; iopd->dir |= SPI_CS_MASK; iopd->dat &= ~SPI_CS_MASK; } void spi_cs_deactivate(struct spi_slave *slave) { volatile gpio83xx_t *iopd = &((immap_t *)CFG_IMMR)->gpio[0]; iopd->dat |= SPI_CS_MASK; } #endif /* CONFIG_HARD_SPI */
說明如下,這里主要是操作片選,片選地址由SPI_CS_MASK宏定義決定,具體對應于哪個GPIO。相應修改即可。
-
驅動默認的初始化還是蠻合理的,在上面相關板子中定義宏定義后,芯片會在board.c文件中進行相關spi初始化。詳見 lib_ppc/borad.c文件。只是初始化函數(shù) spi_slave_init()有調用malloc的函數(shù),如果想用這個函數(shù)需要將該函數(shù)放在malloc功能初始化之后。我這里圖方便好找。放在了 board.c文件中board_init_r()函數(shù)最后面 main_loop上面。這里貼出來寫的 spi_slave_init()函數(shù):
struct spi_slave *spi_slave_init(void) { struct spi_slave *slave; unsigned int bus = 0; unsigned int cs = 12; unsigned int mode = SPI_MODE_0; slave = spi_setup_slave(bus, cs, 10000000, mode); if (!slave) { printf("Invalid device %d:%d\n", bus, cs); return NULL; } spi_claim_bus(slave); return slave; }
同時在 spi_setup_slave 我嫌麻煩直接屏蔽了以下代碼:
// if (!spi_cs_is_valid(bus, cs))
// return NULL;
由于SPI eeprom支持到20MHz速率。默認配置是16MHz速率。但是實際上使用起來還是有問題,這里我將速率直接降到5.33MHz。沒有啥問題了。相關代碼如下:
spi->mode = 0| SPI_MODE_REV | SPI_MODE_MS | SPI_MODE_EN | (1<<19);
spi->mode = (spi->mode & 0xfff0ffff) | (4 << 16); // 5.33mhz
- 為了測試方便,我這里直接在board.c中main_loop之前進行相關測試。包括有讀ID.讀狀態(tài),寫狀態(tài),改變寫保護,讀數(shù)據(jù),寫數(shù)據(jù)等等。均無誤。
- 下一步就是添加相關命令處理了。這里為了方便簡要敘述下添加命令的過程:
添加命令
-
在 include/configs/MPC8315ERDB.h 中添加相關命令定義:
#define CONFIG_CMD_EEPROM_E
在 common/目錄中添加相關文件,這里我添加文件為 cmd_eeprom_e.c,參考目錄中其他相關cmd_xxx.c文件編寫相關命令,包括如何解析參數(shù),如何進行運行等。
-
在 common/Makefile 中添加下列內容:
COBJS-$(CONFIG_CMD_EEPROM_E) += cmd_eeprom_e.o
-
這里貼一個簡要的cmd_eeprom_e.c 內容,讀者請自行發(fā)散。
#include <common.h> #include <config.h> #include <command.h> #include <spi.h> #if defined(CONFIG_CMD_EEPROME_E) extern struct spi_slave *slave; int do_eeprome(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { printf("hello world\n"); return 1; } U_BOOT_CMD ( eeprome, 1, 1, do_eeprome, "eeprome - erase the whole eeprom \n", "this command will erase entire eeprom \n" "please make sure!!!!! \n" ); #endif
分享完畢。fighting