采用RT-Thread Studio搭建N32G43x开发环境-2
1、介绍基于前面的移植基础上,
开发环境-1网址:https://bbs.21ic.com/icview-3187236-1-1.html
本次完成了真对N32G43xCL-STB开发板的PIN接口和SPI接口驱动的移植,并通过测试了SPI驱动操作 W25Q80 串行Flash的读写相关过程。
2、PIN接口的完善 针对N32G435CBL7为48脚封装,所以,重新更新drv_gpio.c文件,并且增加新的宏定义
#define N32G43X_PIN_NUMBERS 48 //[48, 64, 100, 144 ]
同时,调整了static const struct pin_index pins[] =内容。详细内容参见板级支持包的文件。
3、SPI接口驱动本次移植以SPI1为例子,所以,下面的描述均针对SPI1来完成。 1) 首先,SPI1的IO端口初始化 增加SPI的初始化函数,函数中包括:外设时钟控制,IO引脚的配置。 #ifdef BSP_USING_SPI1 if(SPI1 == SPIx) { RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_SPI1, ENABLE); RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA | RCC_APB2_PERIPH_AFIO, ENABLE); /* Configure SPI_MASTER pins: SCK and MOSI */ GPIO_InitCtlStruct.GPIO_Slew_Rate = GPIO_Slew_Rate_High; GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitCtlStruct.GPIO_Alternate = GPIO_AF0_SPI1; GPIO_InitCtlStruct.Pin = GPIO_PIN_5 | GPIO_PIN_7; GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); /* miso */ GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_Input; GPIO_InitCtlStruct.GPIO_Alternate = GPIO_AF0_SPI1; GPIO_InitCtlStruct.Pin = GPIO_PIN_6; GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); } #endif 2) 其次,SPI外设驱动配置 从官方提供的驱动中,幅值drv_spi.c和drv_spi.h两个文件到板级支持包的Libraries/rt_drivers目录中,并修改。
4、SPI接口驱动测试测试对象为SPI-Flash W25Q80,完成flash的ID读取,扇区擦除,数据写入和数据读出。 1) 硬件连接 2) 软件测试代码 struct N32G43x_SPI_CS spi_cs; struct rt_spi_device *spi_dev; // projects\stm32l475_device_sample\applications\spi_sample.c
#define SPI_BUD_NAME "spi1" #define SPI_DEVICE_NAME "spi10" #define W25Q_FLASH_NAME "W25Q80"
#define SPI_CS_PIN 14
rt_uint8_t wData[4096] = {"SPI bus write data to W25Q flash."}; rt_uint8_t rData[4096];
struct rt_spi_device spi10_dev;
static int rt_hw_spi_flash_init(void) { spi_cs.GPIO_Pin = SPI_CS_PIN; spi_cs.GPIOx = GPIOA; rt_pin_mode(spi_cs.GPIO_Pin, PIN_MODE_OUTPUT); rt_pin_write(spi_cs.GPIO_Pin, PIN_HIGH);
if(rt_spi_bus_attach_device(&spi10_dev, SPI_DEVICE_NAME, SPI_BUD_NAME, (void *)&spi_cs) != RT_EOK) return -RT_ERROR;
return RT_EOK; } //INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);
static void spi_w25q_sample(void) { struct rt_spi_device *spi_dev_w25q = RT_NULL; struct rt_spi_message message; struct rt_spi_configuration config;
rt_uint8_t w25q_read_id[4] = {0x90, 0x00, 0x00, 0x00}; rt_uint8_t w25q_read_data[4] = {0x03, 0x00, 0x10, 0x00}; rt_uint8_t w25q_write_data[4] = {0x02, 0x00, 0x10, 0x00}; rt_uint8_t w25q_erase_sector[4] = {0x20, 0x00, 0x10, 0x00}; rt_uint8_t w25q_write_enable = 0x06; rt_uint8_t W25X_ReadStatusReg1 = 0x05; rt_uint8_t id[2] = {0}; rt_uint8_t status = 1;
spi_dev_w25q = (struct rt_spi_device *)rt_device_find(SPI_DEVICE_NAME); if(spi_dev_w25q == RT_NULL){ rt_kprintf("spi sample run failed! can't find %s device!\n", SPI_DEVICE_NAME); }else{ // config w25q spi config.mode = RT_SPI_MASTER | RT_SPI_MODE_3 | RT_SPI_MSB; config.data_width = 8; config.max_hz = 1 * 1000 * 1000;
rt_spi_configure(spi_dev_w25q, &config); rt_kprintf("spi10 config finish.\n");
// read w25q id rt_spi_send_then_recv(spi_dev_w25q, w25q_read_id, 4, id, 2); rt_kprintf("spi10 read w25q ID is:%2X%2X\n", id[0], id[1]);
// erase sector address 4096 rt_spi_send(spi_dev_w25q, &w25q_write_enable, 1); rt_spi_send(spi_dev_w25q, w25q_erase_sector, 4); // wait transfer finish while((status & 0x01) == 0x01) rt_spi_send_then_recv(spi_dev_w25q, &W25X_ReadStatusReg1, 1, &status, 1); rt_kprintf("spi10 erase w25q sector(address:0x1000) success.\n");
// write data to w25q address 4096 rt_spi_send(spi_dev_w25q, &w25q_write_enable, 1);
rt_spi_send_then_send(spi_dev_w25q, w25q_write_data,4, wData, 64); // memset(&message , 0, sizeof(message)); // message.send_buf = wData; // message.recv_buf = RT_NULL; // message.length = 64; // rt_spi_transfer_message(spi_dev_w25q, &message); // wait transfer finish status = 1; while((status & 0x01) == 0x01) rt_spi_send_then_recv(spi_dev_w25q, &W25X_ReadStatusReg1, 1, &status, 1); rt_kprintf("spi10 write data to w25q(address:0x1000) success.\n");
// read data from w25q address 4096 rt_spi_send_then_recv(spi_dev_w25q, w25q_read_data, 4, rData, 64); rt_kprintf("spi10 read data from w25q(address:0x1000) is:%s\n", rData); } }
MSH_CMD_EXPORT(spi_w25q_sample, spi w25q80 sample); 5、实测效果
注册了SPI1外设和用来完成flash操作的设备SPI10。 执行spi flash操作例程后 通过试验测试,spi驱动已经可以正确的完成flash的操作,spi驱动顺利完成了。 6、板级支持包更新
添加PIN和SPI驱动的板级支持包。
|