HXDSP2441
HXDSP2441
1.SPI
1.1裸机
HXDSP2441在BSP中提供的SPI裸机驱动接口具体查询《HXDSP2441裸机驱动用户手册》4.4。需要特别说明的是,因为BSP内提供的所有SPI相关接口均针对Flash器件,如果SPI所控为非Flash器件,则需要仔细阅读BSP源码并在必要时重新实现驱动接口。由于Demo板通过SPI接口控制ADC器件(MAX11635),所以对BSP的SPI相关源码进行修改,以下涉及源码文件均在BSP包的drivers/spi/文件夹下。
以spi_write接口为例,分析其调用路径:
spi_write(spidrv.c)->spi_transfer_wait(spidrv.c)->spi_transfer_wait_poll(spidrv.c)->spi_transfer(spidrv.c)->spi_unload(spidrv.c)->spi_transfer_data(spidrv.c)->handle_message(spidrv.c)->resolve_command(spi_bus.c)
spi_write传入spi_bus结构体,最终由resolve_command函数解析结构体成员spi_bus.spi_message.flag进而确认SPI操作Flash的命令字,原本flag为SPI_WRITE时对应写flash_readwrite的写功能,将flash_readwrite对应改为我自己实现的spi_readwrite函数,spi_read接口同理,spi_readwrite函数实现如下(spi_readwrite接口并不需要device_type,只为与原有接口保持一致)。
1 /*
2 *功能:SPI RAW 读写
3 *参数:总线结构
4 */
5 spi_status_code spi_readwrite(spi_bus *bus,uint32_t device_type){
6 uint64_t base = bus->base;
7 uint32_t status = 0;
8
9 /*
10 * 写入的字节数
11 */
12 int count = bus->msg->len;
13 /*
14 * 写入的缓冲区
15 */
16 uint8_t *wbuf = bus->msg->buf;
17 uint8_t *rbuf = bus->msg->buf;
18 epos_interrupt_disable(0);
19 uint32_t fake_data = 0;
20 uint32_t tx_cnt=0, rx_cnt=0;
21 for(;tx_cnt<count || rx_cnt < count;){
22 status = *((volatile uint32_t*)base + SSI_SR_OFFSET);
23 if((tx_cnt<count) && (status & SR_TFNF)){
24 *((volatile uint32_t*)base + SSI_DR_OFFSET) = wbuf[tx_cnt];
25 tx_cnt++;
26 }
27 if((rx_cnt < count) && (status & SR_RFNE)){
28 rbuf[rx_cnt] = *((volatile uint32_t*)base + SSI_DR_OFFSET);
29 rx_cnt++;
30 }
31 }
32 wait_spi_completion(base);
33 epos_interrupt_enable(0);
34
35 return SPI_SUCCESSFUL;
36 }
2.I2C
HXDSP2441在BSP中提供通过I2C协议与EEPROM进行通信的接口,Demo板通过M24M01器件对I2C接口进行测试,测试代码如下。
1 #define CONFIGURE_INIT
2
3 #include <drivers/xconfig_baseparm.h>
4
5 #include "sys_cfg.h"
6
7 #define I2C_DEV_NO 0
8 #define I2C_BUS_NO 0
9 #define DATA_SIZE 256
10
11 int main(int argc, char* argv[]) {
12 i2c_status_code ret = 0;
13 int slave_addr = 0x50;
14 epos_libio_init_args_t init_args = {
15 .data0 = (I2C_BUS_NO) | (slave_addr << 16)};
16
17 ret = m24m01_driver_initialize(I2C_DEV_NO, &init_args);
18 if (ret != I2C_SUCCESSFUL) {
19 printf("m24m01_driver_initialize fail.\n");
20 return -1;
21 }
22
23 epos_libio_rw_args_t rw_args;
24
25 char send_buf[DATA_SIZE];
26
27 for (int i = 0; i < DATA_SIZE; i++)
28 send_buf[i] = 0x5a + i;
29
30 rw_args.data0 = 0; // 总线号
31
32 rw_args.buffer = send_buf; // 发送缓冲区的首地址
33 rw_args.count = DATA_SIZE; // 发送数量
34 rw_args.offset = 0;
35
36 ret = m24m01_driver_write(0, &rw_args);
37 if (ret != I2C_SUCCESSFUL) {
38 printf("i2cmaster_driver_write fail.\n");
39 return -1;
40 }
41
42
43 char recv_buf[DATA_SIZE];
44 memset(recv_buf, 0, sizeof(recv_buf));
45 rw_args.data0 = 0; // 总线0
46
47 rw_args.count = DATA_SIZE; // 读取数量
48 rw_args.buffer = recv_buf; // 读取至内存的首地址
49 ret = m24m01_driver_read(0, &rw_args);
50
51 if (ret != I2C_SUCCESSFUL){
52 printf("i2cmaster_driver_read fail.\n");
53 return -1;
54 }
55
56 int check_ok = 1;
57
58 for(int i=0;i<DATA_SIZE;i++){
59 if(recv_buf[i] != send_buf[i]){
60 printf("M24M01 byte%d check fail, expect 0x%x but get 0x%x\n", i, send_buf[i], recv_buf[i]);
61 check_ok = 0;
62 // break;
63 }
64 }
65 if(check_ok){
66 printf("M24M01 check pass.\n");
67 }
68
69
70 return 0;
71 }
浙公网安备 33010602011771号