一、概述
RVB2601采用平头哥低功耗,32位RISC-V玄铁E906处理器,搭载AliOS 物联网操作系统,通过端云一体的集成开发环境,快速接入芯片开放社区(OCC)获取开发资源, 进行便捷的应用开发。开发者可面向IoT接入、蓝牙、音频/播放等领域,做各种应用创新。可应用于智慧家居、影音播控、电子玩具、环境监测、健康医疗、教育学习等领域。
RVB2601 内置了联盛德公司高性能&安全的 WiFi4 芯片 W800,W800 通过 SPI 口与 CH2601 连接。可以通过AT指令实现W800芯片与MCU之间的命令传输与数据交互,快速实现联网的应用场景。本次将通过webplayer Demo学习W800 WiFI芯片的配网方法与网络播放器的实现。
二、网络配置
通过剑池CDK将webplayer Demo从OCC平台拉取下来,编译DownLoad之后,可以在串口收到如图所示的信息
此时,通过ifconfig ap wifiname wifipassword命令进行网络配置,其中wifiname为个人的wifi名字,wifipassword为个人的wifi密码,需要进行修改,配置成功后可通过ifconfig命令查询当前wifi连接状态以及相应的IP
之后可通过player play http://yocbook.oss-cn-hangzhou.aliyuncs.com/av_repo/alibaba.mp3命令实现从网络上拉取mp3歌曲进行播放。
三、代码分析
static void network_init()
{
w800_wifi_param_t w800_param;
/* init wifi driver and network */
w800_param.reset_pin = PA21;
w800_param.baud = 1*1000000;
w800_param.cs_pin = PA15;
w800_param.wakeup_pin = PA25;
w800_param.int_pin = PA22;
w800_param.channel_id = 0;
w800_param.buffer_size = 4*1024;
wifi_w800_register(NULL, &w800_param);
app_netmgr_hdl = netmgr_dev_wifi_init();
if (app_netmgr_hdl) {
utask_t *task = utask_new("netmgr", 2 * 1024, QUEUE_MSG_COUNT, AOS_DEFAULT_APP_PRI);
netmgr_service_init(task);
//netmgr_config_wifi(app_netmgr_hdl, "TEST", 4, "TEST1234", 10);
netmgr_start(app_netmgr_hdl);
}
}
上述代码通过串口终端输入命令进行网络配置,也可以通过
netmgr_config_wifi(app_netmgr_hdl, "TEST", 4, "TEST1234", 10);
进行网络配置,将TEST修改为自己的wifi名称,TSET1234修改为自己的wifi密码,避免每次复位后需要重新配置wifi信息。
__attribute__((weak)) int player_init()
{
static int inited = 0;
if (!inited) {
resample_register();
eqx_register();
aefx_register();
atempo_register();
avparser_register_all();
stream_register_all();
demux_register_all();
ad_register_all();
ao_register_all();
inited = 1;
}
return inited ? 0 : -1;
}
通过此函数将播放器进行初始化,在调用播放器其他接口之前,要初始化播放器模块。其主要功能为注册取流类型stream、解复用demux、解码器codec、音频输出ao等。
此外,还可以播放器模块中添加播放、暂停、恢复播放、跳转播放、停止播放、调整音量等功能。
static void *at_spi_init(const char *name, void *config)
{
int ret = 0;
w800_wifi_param_t *param = (w800_wifi_param_t *)config;
csi_pin_set_mux(PA16, PA16_SPI0_SCK);
csi_pin_set_mux(PA17, PA17_SPI0_MOSI);
csi_pin_set_mux(PA18, PA18_SPI0_MISO);
// csi_pin_set_mux(PA15, PA15_SPI0_CS); // CS
csi_pin_set_mux(param->cs_pin, PIN_FUNC_GPIO); // CS
csi_pin_set_mux(param->int_pin, PIN_FUNC_GPIO); // INT
csi_gpio_pin_init(&spi_int_pin, param->int_pin);
csi_gpio_pin_dir(&spi_int_pin,GPIO_DIRECTION_INPUT);
csi_gpio_pin_mode(&spi_int_pin,GPIO_MODE_PULLNONE);
csi_gpio_pin_debounce(&spi_int_pin, true);
csi_gpio_pin_attach_callback(&spi_int_pin, spi_in_int_cb, NULL);
csi_gpio_pin_irq_mode(&spi_int_pin,GPIO_IRQ_MODE_FALLING_EDGE);
csi_gpio_pin_irq_enable(&spi_int_pin, 1);
csi_gpio_pin_init(&spi_cs_pin, param->cs_pin);
csi_gpio_pin_mode(&spi_cs_pin,GPIO_MODE_PULLUP);
csi_gpio_pin_dir(&spi_cs_pin,GPIO_DIRECTION_OUTPUT);
CS_HIGH;
csi_gpio_pin_init(&spi_wakeup_pin, param->wakeup_pin);
csi_gpio_pin_mode(&spi_wakeup_pin,GPIO_MODE_PULLUP);
csi_gpio_pin_dir(&spi_wakeup_pin,GPIO_DIRECTION_OUTPUT);
csi_gpio_pin_write(&spi_wakeup_pin, GPIO_PIN_HIGH);
ret = csi_spi_init(&spi_handle, 0);
if (ret < 0) {
printf("csi spi init failed\r\n");
return NULL;
}
csi_spi_mode(&spi_handle, SPI_MASTER);
ret = csi_spi_baud(&spi_handle, param->baud);
LOGD(TAG, "#######################spi speed:%d\r\n", ret);
csi_spi_cp_format(&spi_handle, SPI_FORMAT_CPOL0_CPHA0);
csi_spi_frame_len(&spi_handle, SPI_FRAME_LEN_8);
csi_spi_select_slave(&spi_handle, 0);
#ifdef SPI_USE_DMA
csi_spi_attach_callback(&spi_handle, spi_event_cb, NULL);
csi_spi_link_dma(&spi_handle, NULL, &spi_recv_dma);
#endif
aos_task_t task;
ret = aos_sem_new(&spi_recv_sem, 0);
// aos_check(ret, NULL);
ret = aos_event_new(&spi_event, 0);
ret = aos_task_new_ext(&task, "spi_recv", at_spi_recv_task, NULL, 1536, 9);
// aos_check(ret, NULL);
spi_recv_buffer = (char *)aos_malloc_check(param->buffer_size);
ringbuffer_create(&spi_ringbuffer, spi_recv_buffer, param->buffer_size);
return (void*)1;
}
通过此函数初始化W800与SPI接口对应所需的端口。