risc-v内核中科蓝讯bt8922开发(代码片段)

aron566 aron566     2023-03-20     369

关键词:

RISC-V内核中科蓝讯BT8922开发

BT8922

GPIO配置

官方说明部分

GPIOAFEN      //0:当作通用GPIO使用   //1:当作其它功能性IO,如串口/SPI..
GPIOADE       //数字IO使能: 0为模拟IO, 1 为数字IO,    //如作为AUX/MIC输入的IO口就需要设置成模拟IO, 减少数字IO对AUX的干扰.
GPIOADIR      //控制IO的方向:  0为输出, 1为输入.
GPIOA         //IO方向为输入时,读此寄存器的值即得到引脚的高低状态  //IO为输出时, 设置此寄存器的高低即设置对应引脚的高低输出.
GPIOADRV      //0 输出驱动为8mA   //1 输出驱动为32 mA   //IO方向为输出时有效
  
//以下寄存器控制上拉或下拉, 注意只有当IO设置为输入时, 上下拉才有效.  //IO方向为输出时上下拉自动无效  
GPIOAPU          //10K上拉使能
GPIOAPD          //10K下拉使能
GPIOAPU200K      //200K上拉使能
GPIOAPD200K      //200K下拉使能
GPIOAPU300       //300欧上拉使能
GPIOAPD300       //300欧下拉使能

//作为输出时,输出电平的高低也可以通过设置GPIOASET/GPIOACLR来快速实现,注意GPIOASET/GPIOACLR只对写1的位有效.
GPIOASET = BIT(0);    //PA0输出高, 等效于 GPIOA |= BIT(0);其它位状态不变.
GPIOACLR = BIT(0);    //PA0输出低, 等效于GPIOA &= ~BIT(0);其它位状态不变.   

常见输入输出使用示例: 1. PA0输出高低(点LED灯)示例:

int main(void)

    //示例开始
    GPIOAFEN &= ~BIT(0);   //PA0作为GPIO使用
    GPIOADE  |= BIT(0);    //PA0设置为数字IO
    GPIOADIR &= ~BIT(0);   //PA0方向设置为输出
    WDT_DIS();          //测试程序关看门狗,防止看门狗复位
    while(1) 
        GPIOA |= BIT(0);       //PA0输出高, 等效于GPIOASET = BIT(0);
        delay_ms(100);
        GPIOA &= ~BIT(0);      //PA0输出低, 等效于GPIOACLR = BIT(0);
        delay_ms(100);

配置得到PA0引脚状态(作用输入)示例:

int main(void)

    //示例开始
    GPIOAFEN &= ~BIT(0);   //PA0作为GPIO使用
    GPIOADE  |= BIT(0);    //PA0设置为数字IO
    GPIOADIR |= BIT(0);    //PA0方向设置为输入
    GPIOAPU  |= BIT(0);    //作为输入,为了有稳定的输入状态(1或0),在外部没上拉或下拉时,需要根据实际情况开内部上拉或下拉
    WDT_DIS();             //测试程序关看门狗,防止看门狗复位
    while(1) 
        delay_ms(100);
        printf("GPIOA0 = 0x%X\\n",GPIOA & BIT(0));    //打印读到的PA0状态

关于 GPIOASET/ GPIOACLR: 只对写入为1的位有效, 写入为0的位则不影响它以前的状态的. 如PA0输出高低

GPIOASET = BIT(0);    //PA0输出高, 等效于 GPIOA |= BIT(0);
GPIOACLR = BIT(0);    //PA0输出低, 等效于GPIOA &= ~BIT(0);   

GPIO输出控制优化加速

此两个寄存器, 主要是优化IO输出高低电平而设置. 如设置PA0为高, 为了不影响GPIOA上的其它IO的操作, 以前程序一般这样写GPIOA |= BIT(0); 这里实际上有三个步骤:

1) 先读出GPIOA
2) 再把GPIOA | BIT(0)
3) 把或后的结果再写回GPIOA

而使用GPIOASET效优化后, 直接一步GPIOASET = BIT(0);
即达到 上面三步才能达到的效.
GPIOADE  &= ~BIT(7);//模拟:0 or 数字:1

/* 功能选择 */
GPIOAFEN &= ~BIT(7);//普通IO:0 or 复用IO:1

/* 上下拉控制 */
GPIOAPU  &= ~BIT(7);//10Kohm 上拉使能(输入有效) 0不用 1使能
GPIOAPU200K  &= ~BIT(7);//200Kohm 上拉使能(输入有效) 0不用 1使能
GPIOAPU300  &= ~BIT(7);//300ohm 上拉使能(输入有效) 0不用 1使能
GPIOAPD  &= ~BIT(7);//10Kohm 下拉使能(输入有效) 0不用 1使能
GPIOAPD300  &= ~BIT(7);//300ohm 下拉使能(输入有效) 0不用 1使能
GPIOAPD200K  &= ~BIT(7);//200Kohm 下拉使能(输入有效) 0不用 1使能

/* 输入输出控制 */
GPIOADIR |= BIT(7);//方向选择 0输出 1输入

/* 驱动能力控制 */
GPIOADRV |= BIT(7);//驱动电流 写0 8 or 写1 32mA

/* 端口功能映射控制 */
FUNCMCON0 =31:28】UART1 RX mapping
0000: no affect
0001: map to G1
0010: map to G2
0011: map to TX pin by UT1TXMAP select
1111: Clear these bits
【27:24】UART1 TX mapping
0000: no affect
0001: map to G1
0010: map to G2
1111: Clear these bits
【15:12】UART0 RX mapping
0000: no affect
0001: map to G1
0010: map to G2
0011: map to G3
0100: map to G4
0101: map to G5
0110: map to G6
0111: map to TX pin by UT0TXMAP select
1111: Clear these bits
【11:8】UART0 TX mapping  
0000: no affect
0001: map to G1
0010: map to G2
0011: map to G3
0100: map to G4
0101: map to G5
0110: map to G6
0111: map to G7
1111: Clear these bits
【7:4】SPI0 mapping
0000: no affect
0001: map to G1
0010: map to G2
0011: map to G3
1111: Clear these bits
【3:0】SD0 mapping
0000: no affect
0001: map to G1
0010: map to G2
0011: map to G3
0100: map to G4
0101: map to G5
0110: map to G6
1111: Clear these bits
 
FUNCMCON1 =11:8】UART2 RX mapping 
0000: no affect
0001: map to G1
0010: map to G2
0011: map to TX pin by UT2TXMAP select
1111: Clear these bits
【7:4】UART2 TX mapping
0000: no affect
0001: map to G1
0010: map to G2
1111: Clear these bits
  
FUNCMCON2 = /* 设置定时器 */
  
FUNCMCON2 = /* 设置MPDM interface mapping 和 PDM interface mapping */  

对于G1这种IO组合名称定义,查阅config_define.h,以及在Datasheet文件中找到相关定义

配置一个端口为串口

GPIOADE  |= BIT(7);//数字
GPIOAPU  |= BIT(7);//上拉10Kohm
GPIOADIR |= BIT(7);//方向选择1输入
GPIOAFEN |= BIT(7);//功能复用IO
GPIOADRV |= BIT(7);//驱动电流32mA
#define URX0MAP_TX	(7<<12) //0111 0000 0000 0000
#define UTX0MAP_PA7 (1 << 8)//0000 0001 0000 0000
FUNCMCON0 = URX0MAP_TX | UTX0MAP_PA7;//RX0 Map To TX0, TX0 Map to G1

通过对照手册,设定UART1的相关寄存器设置,在config_define.h中

PS:数据手册中对UART1的RX脚没有G2相关描述,不过控制寄存器中存在G2组,这是datasheet无法与用户手册对应的地方!!!

/*****************************************************************************
 * Module    : uart1 Mapping选择列表 用户手册与数据手册冲突,以数据手册为准
 *****************************************************************************/
#define UTX1MAP_PA7     (1 << 24)        //G1 uart1 tx: PA7
#define UTX1MAP_VUSB    (3 << 24)        //G3 uart1 tx: VUSB

#define URX1MAP_PA6     (1 << 28)        //G1 uart1 rx: PA6

/*****************************************************************************
 * Module    : uart2 Mapping选择列表 以数据手册为准
 *****************************************************************************/
#define UTX2MAP_PB2     (2 << 4)        //G2 uart2 tx: PB2
#define UTX2MAP_VUSB    (3 << 4)        //G3 uart2 tx: VUSB
#define UTX2MAP_CLR     (0xF << 4)      //清除映射

#define URX2MAP_PB1     (2 << 8)        //G2 uart2 rx: PB1
#define URX2MAP_CLR     (0xF << 8)      //清除映射

配置为普通GPIO

/*****************************************************************************
* Module    : GPIO list
*****************************************************************************/
#define IO_NONE             0
#define IO_PA0              1
#define IO_PA1              2
#define IO_PA2              3
#define IO_PA3              4
#define IO_PA4              5
#define IO_PA5              6
#define IO_PA6              7
#define IO_PA7              8
#define IO_PB0              9
#define IO_PB1              10
#define IO_PB2              11
#define IO_PB3              12
#define IO_PB4              13
#define IO_PE0              14
#define IO_PE1              15
#define IO_PE2              16
#define IO_PE3              17
#define IO_PE4              18
#define IO_PE5              19
#define IO_PE6              20
#define IO_PE7              21
#define IO_PF0              22
#define IO_PF1              23
#define IO_PF2              24
#define IO_PF3              25
#define IO_PB5              26
#define IO_MAX_NUM          26

#define IO_MUX_SDCLK        27
#define IO_MUX_SDCMD        28
#define IO_MUX_PWRKEY       29
#define IO_MUX_MICL         30

typedef struct 
    psfr_t sfr;             //GPIO SFR ADDR
    u8 num;
    u8 type;                //type = 1,高压IO,没有300R的强上下拉电阻。 type = 0, 普通IO, 有内部300R上下拉电阻。
 gpio_t;

/* 配置IO,io_num就是上表中数字 */
gpio_cfg_init(gpio_t *g, u8 io_num);

简化普通GPIO配置

/* GPIO基础配置 */
#define GET_GPIO_DE_REG(port)             GPIO##port##DE
#define GET_GPIO_FEN_REG(port)            GPIO##port##FEN
#define GET_GPIO_DIR_REG(port)            GPIO##port##DIR
#define GET_GPIO_DRV_REG(port)            GPIO##port##DRV
#define GET_GPIO_DATA_REG(port)           GPIO##port
#define GET_GPIO_SET_REG(port)            GPIO##port##SET
#define GET_GPIO_CLR_REG(port)            GPIO##port##CLR

/* 上拉控制 */
#define GET_GPIO_10K_PUP_REG_ADDR(port)   GPIO##port##PU
#define GET_GPIO_200K_PUP_REG_ADDR(port)  GPIO##port##PU200K
#define GET_GPIO_300_PUP_REG_ADDR(port)   GPIO##port##PU300
#define GET_GPIO_10K_PUP_REG_ADDR(port)   GPIO##port##PU

/* 下拉控制 */
#define GET_GPIO_10K_PD_REG_ADDR(port)    GPIO##port##PD
#define GET_GPIO_200K_PD_REG_ADDR(port)   GPIO##port##PD200K
#define GET_GPIO_300_PD_REG_ADDR(port)    GPIO##port##PD300
#define GET_GPIO_10K_PD_REG_ADDR(port)    GPIO##port##PD

/**
 * @brief 配置32mA电流输出端口
 * @param port 端口
 * @param pin  引脚号PAx
 * 
 */
#define GPIO_CONFIG_OUTPUT_MODE(port, pin) \\
  do \\
    GET_GPIO_DE_REG(port) |= BIT(pin); \\
    GET_GPIO_FEN_REG(port) &= ~BIT(pin); \\
    GET_GPIO_DIR_REG(port) &= ~BIT(pin); \\
    GET_GPIO_DRV_REG(port) |= BIT(pin); \\
    GET_GPIO_CLR_REG(port) = BIT(pin); \\
  while(0)

/**
 * @brief 配置8mA低电流驱动输出
 * @param port 端口
 * @param pin  引脚号PAx
 * 
 */
#define GPIO_CONFIG_SAMALL_OUTPUT_MODE(port, pin) \\
  do \\
    GET_GPIO_DE_REG(port) |= BIT(pin); \\
    GET_GPIO_FEN_REG(port) &= ~BIT(pin); \\
    GET_GPIO_DIR_REG(port) &= ~BIT(pin); \\
    GET_GPIO_DRV_REG(port) &= ~BIT(pin); \\
    GET_GPIO_CLR_REG(port) = BIT(pin); \\
  while(0)

/**
 * @brief 配置引脚输入模式,默认10K上拉
 * @param port 端口
 * @param pin  引脚号PAx
 * 
 */
#define GPIO_CONFIG_INPUT_MODE(port, pin) \\
  do \\
    GET_GPIO_DE_REG(port) |= BIT(pin); \\
    GET_GPIO_FEN_REG(port) &= ~BIT(pin); \\
    GET_GPIO_DIR_REG(port) |= BIT(pin); \\
    GET_GPIO_DRV_REG(port) |= BIT(pin); \\
    GET_GPIO_10K_PUP_REG_ADDR(port) |= BIT(pin); \\
  while(0)

/**
 * @brief 设置引脚高电平
 * @param port 端口
 * @param pin  引脚号PAx
 * 
 */
#define SET_GPIO_TO_HIGH(port, pin) \\
  do \\
    GET_GPIO_SET_REG(port) = BIT(pin); \\
  while(0)

/**
 * @brief 设置引脚低电平
 * @param port 端口
 * @param pin  引脚号PAx
 * 
 */
#define SET_GPIO_TO_LOW(port, pin) \\
  do \\
    GET_GPIO_CLR_REG(port) = BIT(pin); \\
  while(0)

/**
 * @brief 获取引脚电平
 * @param port 端口
 * @param pin  引脚号PAx
 * 
 */
#define GET_GPIO_DATA(port, pin) \\
  (GET_GPIO_DATA_REG(port) & BIT(pin))

  
static void Test_GPIO_Init(void)

  // /* 使能数字GPIO PE5 */
  // GPIOEDE |= BIT(5);

  // /* 普通IO口功能 */
  // GPIOEFEN &= ~BIT(5);

  // /* 设置为输出 */
  // GPIOEDIR &= ~BIT(5);

  // /* 设置高电流驱动 */
  // GPIOEDRV |= BIT(5);

  // /* 设置为低电平 */
  // GPIOE &= ~BIT(5);
  GPIO_CONFIG_OUTPUT_MODE(E, 5);


static void Test_GPIO_Out(uint8_t GPIO_State)

  if(GPIO_State)
  
    // GPIOE |= BIT(5);
    SET_GPIO_TO_HIGH(E, 5);
  
  else
  
    // GPIOE &= ~BIT(5);
    SET_GPIO_TO_LOW(E, 5);
  

简化后的GPIO配置自定义LED

蓝讯有配置LED闪烁方式的工具(download),默认高电平点亮,内部配置IO看不到,所以在自己的电路中如果灯是低电平点亮,就无法使用工具进行配置LED,需要我们做下修改(配置IO、设置高低电平的接口由我们自己代码定义,闪烁周期方式由配置工具定义
并不推荐这么做,功能由sdk实现的就尽量不动里面的代码,对后续升级sdk方便一点
1、在port_led.c文件中增加如下接口

我们在bsp_led.c中实现这些接口:注意代码放置在.com区域

#查看详情  

rk3399平台开发系列讲解(系统篇)1.20android9.0下中科微gnsshal的移植过程(代码片段)

...及硬件接口描述2.2、GNSS服务加入inet用户组2.3、GNSSHAL平台内核版本安卓版本RKPX30Linux4.4Android9.01、介绍客户指定用Android9.0系统,最终选用瑞芯微的RKPX30方案,此方案需要外接GNSS芯片,并且没有GNSSHAL。硬件方案中外接GNSS芯片为中... 查看详情

ab32vg1开发板学习创建工程+下载程序(代码片段)

...#xff0c;3个月前,也就是2021年10月份时,我买了一个中科蓝讯的开发板AB32VG1,但让它在角落吃了3个月的灰尘(不过我买的绝大多数开发板都是样的待遇),今天我突然来了兴致,想玩玩(学学)RT... 查看详情

全志v853芯片在tina下risc-v核e907启动方式的选择(代码片段)

1.主题TinaV85xE907启动方式选择2.问题背景TinaV85x平台E907支持2种启动方式,分别是boot0启动和内核启动。TinaV85xSDK默认配置一般是不启动E907,为方便用户配置开发,下面以V853perf1方案为例,介绍具体的操作步骤。3.解决办法一、boot0... 查看详情

全网首家支持使用buildroot2021构建全志risc-v64架构哪吒d1开发板(代码片段)

文章目录项目仓库汇总编译完整系统或者各个部分构建完整系统镜像单独编译各个部分烧写启动ToDoList已实现功能未实现计划实现如何参与此项目提交PR提交issues项目仓库汇总buildrootgithub仓库地址https://github.com/100askTeam/neza-d1-buildr... 查看详情

[转帖]risc-v加速芯片,496核!rtl开源!(代码片段)

RISC-V加速芯片,496核!RTL开源!https://news.cnblogs.com/n/653553/   来源:wikichip  Celerity是在多家大学共同努力下,而创造的一个开源多核RISC-V分层(tiered)加速器芯片。该项目是DARPA快速电路实现(CircuitRealizationAtFasterTimescale... 查看详情

risc-v架构下fpucontext的动态保存和恢复(代码片段)

...布:https://club.rt-thread.org/ask/article/248051628070d52e.html在RISC-V移植那些事中文章中提到了对RISC-V架构FPU移植部分的优化,最近找工作,这件事做的断断续续,终于完成了。开发环境硬件这次选用了Nuclei和中国移 查看详情

risc-v架构下fpucontext的动态保存和恢复(代码片段)

...布:https://club.rt-thread.org/ask/article/248051628070d52e.html在RISC-V移植那些事中文章中提到了对RISC-V架构FPU移植部分的优化,最近找工作,这件事做的断断续续,终于完成了。开发环境硬件这次选用了Nuclei和中国移 查看详情

品三国论国产risc-v芯片天下大势(代码片段)

 §01沁恒RISC-V卓老师您好,第十六智能车竞赛已顺利收官,非常荣幸沁恒微电子自研的RISC-VMCU能够参与其中。虽然MCU的资源让部分学生施展不开。沁恒大容量高性能的RISC-VMCUCH32V307系列已批量,近期可以发样,近... 查看详情

nxp恩智浦vega织女星开发板免费申请!(代码片段)

...控芯片——NXP推出的RV32M1异构4核MCU芯片,片上集成两个RISC-V架构内核和两个ARM架构内核,对于AR 查看详情

renode应用:在risc-v核上运行freertos(代码片段)

本篇记录通过Renode在RISC-V核上运行FreeRTOSdemo的情况。本来不准备写这一篇,但是发现近期工作学习密度实在太大,上周工作的中间结果这周竟然完全想不起来了,不得不又花了一些时间从头摸索着重新配置了一遍࿰... 查看详情

risc-v学习笔记(代码片段)

RISC-V学习笔记(1)作者:夏风喃喃参考:计算机组成与设计:硬件/软件接口(RISC-V版)文章目录RISC-V学习笔记(1)第1章计算机抽象及相关技术1.6性能1.6.1性能的定义1.6.2性能的度量1.6.3CPU性能... 查看详情

为risc-v64架构全志哪吒d1开发板构建ubuntu20发行版系统并使用githubactions自动化管理更新!(代码片段)

文章目录1.搭建开发环境1.1开发涉及的环境/工具:1.2安装qemu虚拟化工具1.2.1apt安装1.2.2手动交叉编译安装2.获取riscv架构ubuntu根文件系统3.Vmwareubuntu挂载riscv架构ubuntu文件系统3.1.解压缩riscv架构ubuntu文件系统到ubuntu下3.1.2拷贝qemu... 查看详情

risc-v学习笔记(代码片段)

RISC-V学习笔记(2)作者:夏风喃喃参考:计算机组成与设计:硬件/软件接口(RISC-V版)文章目录RISC-V学习笔记(2)第2章计算机的语言2.1引言2.2计算机硬件的操作2.3计算机硬件的操作数(加... 查看详情

芯片开发语言:verilog在左,chisel在右

来源|老石谈芯在最近召开的RISC-V中国峰会上,中科院计算所的包云岗研究员团队正式发布了名为“香山”的开源高性能处RISC-V处理器。前不久我有幸和包老师就这个事情做了一次深度的交流,我们聊了关于RISC-V、还有“... 查看详情

兆易创新首款risc-v开发板——gd32vf103-eval开箱评测

...llo,各位朋友大家好!今天我们来开箱兆易半导体的一款RISC-V开发板——GD32VF103V-EVAL。今年可以说是RISC-V比较火的一年,关注RISC-V的朋友可能都知道,2019年8月份的时候,兆易创新发布了国内第一款基于RISC-V内核的32位通用MCU—... 查看详情

risc-v指令学习笔记(基于ch32v103)(代码片段)

文章目录RISC-V指令学习笔记(基于CH32V103)一、指令结构分类二、寄存器功能三、加载存储指令四、算数运算指令五、移位指令六、逻辑操作指令七、跳转指令7.1条件跳转7.2无条件跳转八、比较判断九、CSR操作指令RISC-V指... 查看详情

risc-v指令学习笔记(基于ch32v103)(代码片段)

文章目录RISC-V指令学习笔记(基于CH32V103)一、指令结构分类二、寄存器功能三、加载存储指令四、算数运算指令五、移位指令六、逻辑操作指令七、跳转指令7.1条件跳转7.2无条件跳转八、比较判断九、CSR操作指令RISC-V指... 查看详情