WB2 SPI测试

闲言碎语
最近水逆,被老板叼难,头都整大了,有没有老哥有工作推荐.
关于hosal库
测试wb2的spi发现一直溢出,用的是 WB2-12Fkit
开发板,跑园长的demo点亮ws2812卡在了spi初始化,发现论坛也有大佬卡在了初始化.
使用printf大法一点点跟踪,发现具体卡在了GPIO的初始化这个函数
static void hosal_spi_gpio_init(hosal_spi_dev_t *arg)
{
if (!arg) {
blog_error("arg err.\r\n");
return;
}
GLB_GPIOgeng huan_Type gpiopins[4];
gpiopins[0] = 22; //这里注释掉就可以初始化完成
gpiopins[1] = arg->config.pin_clk;
gpiopins[2] = arg->config.pin_mosi;
gpiopins[3] = arg->config.pin_miso;
GLB_GPIO_Func_Init(GPIO_FUN_SPI,gpiopins,sizeof(gpiopins)/sizeof(gpiopins[0]));
if (arg->config.mode == 0) {
GLB_Set_SPI_0_ACT_MOD_Sel(GLB_SPI_PAD_ACT_AS_MASTER);
} else {
GLB_Set_SPI_0_ACT_MOD_Sel(GLB_SPI_PAD_ACT_AS_SLAVE);
}
return;
}
不明白为什么将SPI的GPIO除了用到的引脚还初始化22号引脚,看手册上12F不能用这个引脚,把它给注释掉了,然后只初始化CLK MOSI MISO这三个引脚,然后就能正常完初始化.但是发送数据依旧报溢出的问题.
不死心,自己写一个spi发送的demo依然溢出.
更换SDK
折腾了两天解决不了,然后尝试换博流的SDK,看文档说对bl602/bl604支持SPI但未测试,心凉一半.
写了发送1234...的demo用编译烧录,又又出错了,再次搬出printf大法跟踪,定位到 board.c
文件的这里
void board_spi0_gpio_init()
{
// struct bflb_device_s *gpio;
// gpio = bflb_device_get_by_name("gpio");
// bflb_gpio_init(gpio, GPIO_PIN_18, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
// bflb_gpio_init(gpio, GPIO_PIN_19, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
// bflb_gpio_init(gpio, GPIO_PIN_20, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
}
使用SPI的引脚引脚需要自己实现初始化(它这里给注释掉了,表示需要按照实际的引脚来用).
查手册,看支持的SPI引脚不少,选了IO3 IO4 IO5
再次烧录测试,能够成功发送数据,接受方也表示没毛病.
但是神奇的事情发生了,再次用 Ai-Thinker-WB2
sdk烧录程序,怎么都烧录不进去,用 bouffalo
的sdk就可以正常烧录,有大佬知道这是什么原因吗?
然后尝试点亮WS2812灯珠的示例:
#include "bflb_mtimer.h"
#include "bflb_spi.h"
#include "board.h"
#include "bflb_gpio.h"
#include <stdio.h>
#define SPI_MASTER_CASE 0
#define SPI_SLAVE_CASE 1
#define SPI_CASE_SELECT SPI_MASTER_CASE
// SPI数据为0的时序
#define SPI_NEO0 ((uint8_t)0b11000000)
// SPI数据为1的时序
#define SPI_NEO1 ((uint8_t)0b11111100)
#define BITS_PER_LED_COLOR (sizeof(color_t) * 8)
#define BUFF_LEN (8 * 1024)
uint32_t tx_buff[BUFF_LEN / 4];
uint32_t rx_buff[BUFF_LEN / 4];
struct bflb_device_s *spi0;
typedef struct {
uint8_t r;
uint8_t g;
uint8_t b;
} color_t;
typedef struct {
uint16_t led_counts; // LED数量
uint8_t *color_datas; // 24位颜色数据
uint16_t color_data_size; // 颜色数据长度
color_t *led_colors; // LED颜色
bool inited; // 是否初始化,1表示已经初始化,0则表示未初始化
} ws2812b_t;
ws2812b_t ws2812b = {
.inited = false,
.led_counts = 1,
};
color_t RED = { 255, 0, 0 };
color_t GREEN = { 0, 255, 0 };
color_t BLUE = { 0, 0, 255 };
void ws2812b_init(ws2812b_t *ws2812b)
{
if (ws2812b == NULL) {
return;
}
// 分配24位颜色数据内存
ws2812b->color_datas = (uint8_t *)malloc(
ws2812b->led_counts * BITS_PER_LED_COLOR + 32);
// 分配LED颜色数据内存
ws2812b->led_colors = (color_t *)malloc(
sizeof(color_t) * ws2812b->led_counts);
if (ws2812b->color_datas && ws2812b->led_colors) {
ws2812b->inited = true;
ws2812b->color_data_size = ws2812b->led_counts * BITS_PER_LED_COLOR; //+32
} else {
ws2812b->inited = false;
}
}
// 生成24位颜色数据序列
void __build_led_color_data(ws2812b_t *ws2812b)
{
for (int i = 0; i < ws2812b->led_counts; i++) {
uint8_t m = 0b10000000;
for (int b = 0; b < 8; b++) {
ws2812b->color_datas[BITS_PER_LED_COLOR * i + b] =
ws2812b->led_colors[i].g & m ? SPI_NEO1 : SPI_NEO0;
m >>= 1u;
}
m = 0b10000000;
for (int b = 0; b < 8; b++) {
ws2812b->color_datas[BITS_PER_LED_COLOR * i + b + 8] =
ws2812b->led_colors[i].r & m ? SPI_NEO1 : SPI_NEO0;
m >>= 1u;
}
m = 0b10000000;
for (int b = 0; b < 8; b++) {
ws2812b->color_datas[BITS_PER_LED_COLOR * i + b + 16] =
ws2812b->led_colors[i].b & m ? SPI_NEO1 : SPI_NEO0;
m >>= 1u;
}
}
}
void ws2812b_set_color(ws2812b_t *ws2812b, uint16_t index, color_t color)
{
if (index >= ws2812b->led_counts && ws2812b->inited) {
return;
}
ws2812b->led_colors[index] = color;
}
void ws2812b_show(ws2812b_t *ws2812b)
{
if (!ws2812b->inited) {
return;
}
__build_led_color_data(ws2812b);
//hosal_spi_send(&spi, ws2812b->color_datas,ws2812b->color_data_size,1000);
printf("countsize=%d\r\n", ws2812b->color_data_size);
for (int i = 0; i < ws2812b->color_data_size; i++) {
bflb_spi_poll_send(spi0, ws2812b->color_datas[i]);
}
}
void board_spi0_gpiomy_init()
{
struct bflb_device_s *gpio;
gpio = bflb_device_get_by_name("gpio");
bflb_gpio_init(gpio, GPIO_PIN_3, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
bflb_gpio_init(gpio, GPIO_PIN_4, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
bflb_gpio_init(gpio, GPIO_PIN_5, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
}
/* poll test func */
/* main */
int main(void)
{
board_init();
board_spi0_gpiomy_init();
struct bflb_spi_config_s spi_cfg = {
#if (SPI_CASE_SELECT == SPI_MASTER_CASE)
.freq = 8 * 1000 * 1000,
.role = SPI_ROLE_MASTER,
#else
.freq = 32 * 1000 * 1000,
.role = SPI_ROLE_SLAVE,
#endif
.mode = SPI_MODE3,
.data_width = SPI_DATA_WIDTH_8BIT,
.bit_order = SPI_BIT_MSB,
.byte_order = SPI_BYTE_LSB,
.tx_fifo_threshold = 0,
.rx_fifo_threshold = 0,
};
spi0 = bflb_device_get_by_name("spi0");
bflb_spi_init(spi0, &spi_cfg);
//uint32_t mess = 0;
printf("start\r\n");
// bflb_spi_poll_send(spi0, mess);
ws2812b_init(&ws2812b);
printf("ws2812b task start...\r\n");
while (1) {
// bflb_mtimer_delay_ms(2000); /* delay for slave device prepare ok */
// bflb_spi_poll_send(spi0, mess);
// mess++;
for (size_t i = 0; i < ws2812b.led_counts; i++) {
ws2812b_set_color(&ws2812b, i, RED);
}
ws2812b_show(&ws2812b);
bflb_mtimer_delay_ms(1000);
for (size_t i = 0; i < ws2812b.led_counts; i++) {
ws2812b_set_color(&ws2812b, i, GREEN);
}
ws2812b_show(&ws2812b);
bflb_mtimer_delay_ms(1000);
for (size_t i = 0; i < ws2812b.led_counts; i++) {
ws2812b_set_color(&ws2812b, i, BLUE);
}
ws2812b_show(&ws2812b);
bflb_mtimer_delay_ms(1000);
}
}
编译烧录
make CHIP=BL602 BOARD=bl602dk
make flash CHIP=BL602 COMX=/dev/ttyUSB0
嘿,你猜怎么着,WB2-12F-kit上边的灯珠颗RGB5050灯珠,用单线协议没用,直接用高低电平控制的,只能用用逻辑分析仪检测一下控制逻辑是否正确.


已经解析出来WS2812协议了
ok
其他
其实我之前画过WB2-12f的测试版,要驱动IIC用的,上边刚好有一颗WS2812灯珠接在io5上.想把上边程序下载上去验证,但一直无法烧录(用 Ai-Thinker-WB2SDK
就可以正常烧录程序),简直是倒反天罡.我就说水逆吧.
还有个问题,我没明白博流sdk 的spi如何为功能引脚指定GPIO引脚.求评论区大佬解答.