基于stm32f429-discovery开发板的u-boot进行修改
cp -r u-boot ./u-boot_gd32450i-eval
cd u-boot_gd32450i-eval
make
make成功后再进行修改。
HSE 25MHZ,SystemCoreClock 200MHZ, 在u-boot_gd32450i-eval/include/configs/stm32f429i-discory.h中配置锁相环参数: M = 25, N = 400, P = 2, Q = 9。
网络芯片使用LAN8720,时钟是由GD32F450 PA8脚提供的50MHZ。
修改drivers/gpio/stm32f2_gpio.c
中的stm32f2_gpio_config函数,和af_val数组,为PA8新增AF0,CLKOUT功能。
修改include/asm-arm/arch/stm32f2_gpio.h
新增CLKOUT的AF配置选项
修改driver/net/stm32_eth.c
新增PA8口的配置,在RCC_CFG0寄存器中使能CLKOUT0功能,配置为50MHZ。
linux系统下的管脚修改在linux/arch/arm/mach-stm32/iomux.c
里的stm32_iomux_init(void)
函数里。
#if defined(CONFIG_STM32_MAC)
do {
static struct stm32f2_gpio_dsc mii_gpio[] = {
{0, 1}, {0, 2}, {0, 7},
{1, 5}, {1, 8},
{2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5},
{6, 11}, {6, 13}, {6, 14},
{7, 2}, {7, 3}, {7, 6}, {7, 7},
{8, 10}
};
static struct stm32f2_gpio_dsc rmii_gpio[] = {
{0, 1}, {0, 2}, {0, 7},
{2, 1}, {2, 4}, {2, 5},
{1, 11}, {6, 13}, {6, 14},
};
int i;
if (platform == PLATFORM_STM32_STM_SOM ||
platform == PLATFORM_STM32_STM_DISCO ||
platform == PLATFORM_STM32_STM_STM32F439_SOM ||
platform == PLATFORM_STM32_STM_STM32F7_SOM ||
platform == PLATFORM_STM32_STM32F7_DISCO) {
for (i = 0; i < ARRAY_SIZE(rmii_gpio); i++) {
stm32f2_gpio_config(&rmii_gpio[i],
STM32F2_GPIO_ROLE_ETHERNET);
}
} else {
for (i = 0; i < ARRAY_SIZE(mii_gpio); i++) {
stm32f2_gpio_config(&mii_gpio[i],
STM32F2_GPIO_ROLE_ETHERNET);
}
}
} while (0);
#endif
linux/drivers/net/arm/stm32_eth.c
中的stm32_eth_hw_start
函数,新增MAC软复位的代码,第8行至第25行为新增代码。/*
* Hw initialization
*/
static int stm32_eth_hw_start(struct net_device *dev)
{
struct stm32_eth_priv *stm = netdev_priv(dev);
int i, rv;
int timeout = 2000; //2s
stm->regs->dmabmr |= STM32_MAC_DMABMR_SR;
rv = -1;
while(timeout-->0){
if(stm->regs->dmabmr & STM32_MAC_DMABMR_SR){
msleep(1);
} else {
timeout = 0;
rv = 0;
}
}
if(rv != 0)
{
printk("Software reset MAC timeout!\n");
goto out;
}
/*
* Reset and configure
*/
stm32_eth_hw_stop(dev);
在参考工程根目录下执行make clone new=new_project_name
来创建一个新工程。
修改project/gd32450i-eval/gd32450i-eval.kernel.STMDISO
文件,将0xD0000000改为0xC0000000。
这个文件里的参数应该和u-boot的配置匹配。
u-boot的启动在lib_arm/board.c
中的start_armboot
内存报错
上面的错误是SDRAM没配置好引起的,将内存参数改成下面的就好了。注意配置的是SDRAM控制器0,而不是原来的SDRAM控制器1.
内存报错,GD32F450比STM32F429多了一个SDRAM的读采样控制寄存器,寄存器地址为0XA0000180.只需将0x11写入即可。让读延时一个时钟周期。
ucLinux的自启动脚本是project/gd32450i-eval/local/rc
网络ping大包丢包 ping 192.168.0.1 -s 350,当单包数据超过350字节时丢包率超过90%
在GD32的网卡配置里使能存储转发功能就可以了。
/*
* DMAOMR reg fields
*/
#define STM32_MAC_DMAOMR_SR (1 << 1) /* Start/stop rx */
#define STM32_MAC_DMAOMR_ST (1 << 13) /* Start/stop tx */
#define STM32_MAC_DMAOMR_FTF (1 << 20) /* Flush tx FIFO */
#define STM32_MAC_DMAOMR_TSF (1 << 21) /* Start/stop rx */ 新增
#define STM32_MAC_DMAOMR_RSF (1 << 25) /* Start/stop tx */ 新增
static int stm32_eth_hw_start(struct net_device *dev)里新增一句
stm->regs->dmabmr = (32 << STM32_MAC_DMABMR_PBL_BIT) |
(32 << STM32_MAC_DMABMR_RDP_BIT) |
(STM32_MAC_DMABMR_RTPR_2_1 <<
STM32_MAC_DMABMR_RTPR_BIT) |
STM32_MAC_DMABMR_FB | STM32_MAC_DMABMR_USP |
STM32_MAC_DMABMR_AAB;
stm->regs->dmaomr |= (STM32_MAC_DMAOMR_TSF | STM32_MAC_DMAOMR_RSF); 新增
/*
* Set MAC
*/
stm->regs->maca0hr = (dev->dev_addr[5] << 8) |
(dev->dev_addr[4] << 0);
stm->regs->maca0lr = (dev->dev_addr[3] << 24) |
(dev->dev_addr[2] << 16) |
(dev->dev_addr[1] << 8) |
(dev->dev_addr[0] << 0);