君正x1600适配pan3028无线收发模块

文章目录

概述

本项目硬件平台采用君正x1600平台,使用pan3028(调制解调技术的低功耗远距离无线收发芯片)做无线传输。

硬件连接

比较简单,不再详细说明
这里说下主要涉及的引脚接口,连接方式不限于此
pan3028 <> soc(jz-x1600)
spi接口 <
> spi0
irq引脚 <==> pb15

分析

官方的pan3028测试程序是基于STM32 HAL库的,因此需要准备
1、SOC:spi、gpio hal层接口
2、SOC:spi platform驱动和spi设备驱动

另外要考虑pan3028使用的引脚,是否被其他驱动模块使用,例如君正i2c驱动默认使用了pb15引脚作为clk

移植

准备工作

1、安装驱动
# lsmod
Module Size Used by Tainted: G
spidev 5936 0
spidev_helper 1958 0
soc_gpio 5086 0
soc_spi 12984 0
utils 13815 3 spidev_helper,soc_gpio,soc_spi

2、在官网下载pan3028 demo

移植

pan3028 demo使用的平台接口是stm32 hal库接口,移植工作主要是移植平台接口,主要包括如下内容

初始化gpio

pan3028发送或接收完毕后,均会触发irq引脚拉高,故需要对irq引脚初始化,并判断其电平
拷贝君正libhardware/gpio.c到demo中,并修改demo-init接口初始化gpio方式

        char *func[] = {"func1"};
        g_gpio_fd = gpio_open();
        if (g_gpio_fd < 0)
            return FAIL;
        gpio_set_func(g_gpio_fd, IRQ_GPIO, func, 1);

初始化spi

x1600 spi0传输频率最高10M,pan3028设置为200k或400k即可。
注意,spi传输模式必须和pan3028数据手册上的时序图一致,为SPI_MODE_0,否则会spi会读写失败

    int platform_spi_init(char *cs_pin)
    {
        int spi_fd = 0;
        /* 1.spi初始化 */
        register_data.cs_gpio = cs_pin;
        register_data.busnum = 0;

        // 1.1.注册spi设备
    	if(spi_add_device(&register_data) < 0) {
            printf("spi register fail\n");
            return -1;
        }

        // 延时等待设备节点生成
        usleep(1000*1000);

        // 1.2.打开spi设备
        spi_fd = spi_open(register_data.spidev_path);
        if (spi_fd < 0) {
            printf("spi open fail,spi_fd=%d\n",spi_fd);
    		return -1;
        }

        // 1.3.设置spi传输模式
        if (spi_set_mode(spi_fd, SPI_MODE_0) < 0) {
            printf("spi set mode fail \n");
            return -1;
        }

        // 1.4.设置spi传输速率
        if (spi_set_speed(spi_fd, 400*1000) < 0) {
            printf("spi set speed fail\n");
            return -1;
        }

        // 1.5.设置spi传输的数据位数
        if (spi_set_bits(spi_fd, 8) < 0) {
            printf("spi set bits fail\n");
            return -1;
        }

        // 1.6.设置spi传输数据高低位发送顺序
        if (spi_set_lsb(spi_fd, 0) < 0) {
            printf("spi set lsb fail \n");
            return -1;
        }

        printf("spi init ok\n");
        return spi_fd;
    }

pan3028初始化

pan3028初始化主要通过soc的spi接口,下发配置寄存器值,需注意:
linux内核spi收发接口,每读写一次,内部cs会先拉选中,后恢复
具体过程如下:

jz_spi_transfer_one_message
    //如果spi模式和初始模式不一致,则重新配置
    jz_spi_config
    //使能CS
    if (cs_change)
        enable_cs(hw, spi);
    //发送数据
    jz_spi_transfer
    //关闭CS
    if (cs_change && !list_is_last(&xfer->transfer_list, &msg->transfers))
        disable_cs(hw, spi);

而pan3028要求,读写设备寄存器按如下格式:

读寄存器:
    addr_r + 0x00
写寄存器:
    addr_w + u8_data

其中地址,高7位为地址,第一位为读写位,0=读,1=写
因此,读写寄存器需一次发送两个字节(地址字节+数据字节),中间CS不能被disable,否则读写失败。

rx、tx测试

整体采用demo的代码即可,但需注意如下几点:
第一个usleep:不加读取irq寄存器为空
第二个usleep:如果休眠时间较长,无法触发rx irq,获取rx数据

    while(1)
    { 	
        if(g_run_mode == em_TX_MODE || g_run_mode == em_TXRX_MODE) {
            printf("start to send tx data\n");
    		if(!rf_single_tx_data(send_buff, sizeof(send_buff), &tx_time)) {
    		    printf("wait send finish...\n");
    			while(pan3028_radio_process()){   // 等待发送完成              
                    usleep(200*1000); //必须等待,否则设备IRQ寄存器值会被刷掉
    			}
    		}	
    		printf("send finish !\n");
    	}
    	if(g_run_mode == em_RX_MODE || g_run_mode == em_TXRX_MODE) {
    		/* 接收处理 */
    		printf("start to recv rx data\n");
    		pan3028_radio_process();
    	}
    	usleep(200*1000);
    }	
  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值