Contributed by WT_0213, curated by Ai-Thinker
In Step 2 of the AP web provisioning implementation on the Ai-M61-32S, the WiFi information was already stored in flash.
[Reference] AP Web Provisioning on the Ai-M61-32S (Step 2) https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=43766
Next, read the WiFi information and connect to WiFi.
Create the WiFi-related code.
wifi/wifi_event.h
/**
* @file wifi_event.h
* @author your name ([email]you@domain.com[/email])
* @brief
* @version 0.1
* @date 2023-06-29
*
* @copyright Copyright (c) 2023
*
*/
#ifndef WIFI_EVENT_H
#define WIFI_EVENT_H
#include "stdint.h"
int wifi_start_firmware_task(void);
void wifi_event_handler(uint32_t code);
uint8_t wifi_connect(char* ssid, char* passwd);
#endifwifi/wifi_event.c
📜 Click to expand the full wifi_event.c code
/**
* @file wifi_event.c
* @author your name ([email]you@domain.com[/email])
* @brief
* @version 0.1
* @date 2023-06-29
*
* @copyright Copyright (c) 2023
*
*/
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include <lwip/tcpip.h>
#include <lwip/sockets.h>
#include <lwip/netdb.h>
#include "bl_fw_api.h"
#include "wifi_mgmr_ext.h"
#include "wifi_mgmr.h"
#include "bflb_irq.h"
#include "bflb_uart.h"
#include "bflb_l1c.h"
#include "bflb_mtimer.h"
#include "bl616_glb.h"
#include "rfparam_adapter.h"
#include "board.h"
#include "log.h"
#include "storage.h"
#define DBG_TAG "WIFI EVENT"
#define WIFI_STACK_SIZE (1024*4)
#define TASK_PRIORITY_FW (16)
static wifi_conf_t conf =
{
.country_code = "CN",
};
static TaskHandle_t wifi_fw_task;
static uint32_t sta_ConnectStatus = 0;
xQueueHandle queue;
/**
* @brief WiFi 任务
*
* @return int
*/
int wifi_start_firmware_task(void)
{
LOG_I("Starting wifi ...");
/* enable wifi clock */
GLB_PER_Clock_UnGate(GLB_AHB_CLOCK_IP_WIFI_PHY | GLB_AHB_CLOCK_IP_WIFI_MAC_PHY | GLB_AHB_CLOCK_IP_WIFI_PLATFORM);
GLB_AHB_MCU_Software_Reset(GLB_AHB_MCU_SW_WIFI);
/* set ble controller EM Size */
GLB_Set_EM_Sel(GLB_WRAM160KB_EM0KB);
if (0 != rfparam_init(0, NULL, 0)) {
LOG_I("PHY RF init failed!");
return 0;
}
LOG_I("PHY RF init success!");
/* Enable wifi irq */
extern void interrupt0_handler(void);
bflb_irq_attach(WIFI_IRQn, (irq_callback)interrupt0_handler, NULL);
bflb_irq_enable(WIFI_IRQn);
xTaskCreate(wifi_main, (char*)"fw", WIFI_STACK_SIZE, NULL, TASK_PRIORITY_FW, &wifi_fw_task);
return 0;
}
/**
* @brief wifi event handler
* WiFi 事件回调
*
* @param code
*/
void wifi_event_handler(uint32_t code)
{
sta_ConnectStatus = code;
BaseType_t xHigherPriorityTaskWoken;
switch (code) {
case CODE_WIFI_ON_INIT_DONE:
{
LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_INIT_DONE", __func__);
wifi_mgmr_init(&conf);
}
break;
case CODE_WIFI_ON_MGMR_DONE:
{
LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_MGMR_DONE", __func__);
}
break;
case CODE_WIFI_ON_SCAN_DONE:
{
char* scan_msg = pvPortMalloc(128);
memset(scan_msg, 0, 128);
wifi_mgmr_sta_scanlist();
LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_SCAN_DONE SSID numbles:%d", __func__, wifi_mgmr_sta_scanlist_nums_get());
sprintf(scan_msg, "{\"wifi_scan\":{\"status\":0}}");
// xQueueSend(queue, scan_msg, );
if (wifi_mgmr_sta_scanlist_nums_get()>0) {
xQueueSendFromISR(queue, scan_msg, &xHigherPriorityTaskWoken);
if (xHigherPriorityTaskWoken) {
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
vPortFree(scan_msg);
}
break;
case CODE_WIFI_ON_CONNECTED:
{
LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_CONNECTED", __func__);
void mm_sec_keydump();
mm_sec_keydump();
}
break;
case CODE_WIFI_ON_GOT_IP:
{
LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_GOT_IP", __func__);
}
break;
case CODE_WIFI_ON_DISCONNECT:
{
LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_DISCONNECT", __func__);
char* queue_buff = pvPortMalloc(128);
memset(queue_buff, 0, 128);
sprintf(queue_buff, "{\"wifi_disconnect\":true}");
xQueueSendFromISR(queue, queue_buff, pdTRUE);
vPortFree(queue_buff);
}
break;
case CODE_WIFI_ON_AP_STARTED:
{
LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_AP_STARTED", __func__);
}
break;
case CODE_WIFI_ON_AP_STOPPED:
{
LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_AP_STOPPED", __func__);
}
break;
case CODE_WIFI_ON_AP_STA_ADD:
{
LOG_I("[APP] [EVT] [AP] [ADD] %lld", xTaskGetTickCount());
}
break;
case CODE_WIFI_ON_AP_STA_DEL:
{
LOG_I("[APP] [EVT] [AP] [DEL] %lld", xTaskGetTickCount());
}
break;
default:
{
LOG_I("[APP] [EVT] Unknown code %u ", code);
}
}
}
uint8_t wifi_connect(char* ssid, char* passwd)
{
int ret = 255;
// struct fhost_vif_ip_addr_cfg ip_cfg = { 0 };
uint32_t ipv4_addr = 0;
char* queue_buff = pvPortMalloc(128);
memset(queue_buff, 0, 128);
if (NULL==ssid || 0==strlen(ssid)) {
return 1;
}
if (wifi_mgmr_sta_state_get() == 1) {
wifi_sta_disconnect();
}
if (wifi_sta_connect(ssid, passwd, NULL, NULL, 0, 0, 0, 1)) {
return 4;
}
LOG_I("Wating wifi connet");
//等待连接成功
sta_ConnectStatus = 0;
for (int i = 0;i<10*30;i++) {
vTaskDelay(100/portTICK_PERIOD_MS);
switch (sta_ConnectStatus) {
case CODE_WIFI_ON_MGMR_DONE:
// vTaskDelay(2000);
// LOG_I("wifi_mgmr_sta_scan:%d", wifi_mgmr_sta_scan(wifi_scan_config));
vPortFree(queue_buff);
return 3;
case CODE_WIFI_ON_SCAN_DONE:
// LOG_I("WIFI STA SCAN DONE %s", wifi_scan_config[0].ssid_array);
vPortFree(queue_buff);
return 2;
case CODE_WIFI_ON_DISCONNECT: //连接失败(超过了重连次数还没有连接成功的状态)
LOG_I("Wating wifi connet Faild");
// wifi_sta_disconnect();
vPortFree(queue_buff);
return 4;
case CODE_WIFI_ON_CONNECTED: //连接成功(表示wifi sta状态的时候表示同时获取IP(DHCP)成功,或者使用静态IP)
// LOG_I("Wating wifi connet OK \r\n");
break;
case CODE_WIFI_ON_GOT_IP:
wifi_sta_ip4_addr_get(&ipv4_addr, NULL, NULL, NULL);
LOG_I("wifi connened %s,IP:%s", ssid, inet_ntoa(ipv4_addr));
sprintf(queue_buff, "{\"ip\":{\"IP\":\"%s\"}}", inet_ntoa(ipv4_addr));
flash_erase_set(SSID_KEY, ssid);
flash_erase_set(PASS_KEY, passwd);
xQueueSend(queue, queue_buff, portMAX_DELAY);
LOG_I("Wating wifi connet OK and get ip OK");
vPortFree(queue_buff);
return 0;
default:
//等待连接成功
break;
}
}
vPortFree(queue_buff);
return 14; //连接超时
}Add the following to main.c:
.......
#include "wifi_event.h"
.......
/**
* @brief void queue_task(void* arg)
* 消息队列循环读取
* @param arg
*/
static void queue_task(void* arg)
{
char* ssid = NULL;
char* password = NULL;
ssid = flash_get_data(SSID_KEY, 32);
password = flash_get_data(PASS_KEY, 32);
if (ssid!=NULL && strlen(ssid) > 0)
{
printf("read flash ssid:%s password:%s\r\n", ssid, password);
wifi_connect(ssid, password);
}
else {
printf("ssid read value is NULL:%06X\r\n", SSID_KEY);
}
}
int main(void)
{
.......
// 初始化 存储
flash_init();
// 初始化tcp ip
tcpip_init(NULL, NULL);
// 启动WiFi任务
wifi_start_firmware_task();
char* ssid = NULL;
ssid = flash_get_data(SSID_KEY, 32);
if (ssid!=NULL && strlen(ssid) > 0){
xTaskCreate(queue_task, "queue task", 1024*6, NULL, 2, NULL);
}
.......
}Modify proj.conf to add the following:
## wifi
set(CONFIG_VIF_MAX 2)
set(CONFIG_STA_MAX 4)
set(CONFIG_MAC_TXQ_DEPTH 32)
set(CONFIG_MAC_RXQ_DEPTH 12)Modify CMakeLists.txt to add the following:
target_sources(app PRIVATE
wifi/wifi_event.c // 增加wifi相关代码
storage/storage.c
web/cJSON.c
web/mlwip_https.c
)The current solution has the following problems:
Operation Steps
Chinese WiFi names cannot be connected
The AP disappears after the WiFi info is set
Wrong WiFi info cannot be fixed, and recompiling doesn’t help either
Solutions:
Operation Steps (continued)
Use and connect to an English-named WiFi when possible
Re-flash the firmware
Erase the chip and flash.
In the flash_prog_cfg.ini configuration file
Change
[cfg] # 0: no erase, 1: programmed section erase, 2: chip erase
#0: no erase, 1:programmed section erase, 2: chip erase
erase = 1
to
[cfg] # 0: no erase, 1: programmed section erase, 2: chip erase
#0: no erase, 1:programmed section erase, 2: chip erase
erase = 2
Then run the make flash COMX=COM? [? stands for your COM number] command to erase the data.
At this point, the AP web provisioning implementation on the Ai-M61-32S is complete.
If you think it’s not bad, you can give it a
+ 1.
Have questions?
For other questions, please visit the unified discussion area: Ai-Thinker Discussions

