STM32驱动Realtek RTL8189ES WiFi模块读取MAC地址并下载固件

本文主要是介绍STM32驱动Realtek RTL8189ES WiFi模块读取MAC地址并下载固件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

单片机:STM32F103RE
接口:SDIO
Keil 5工程下载链接:https://pan.baidu.com/s/1yIgUJUZcwWOL7xnwA9Rw2Q?pwd=ftxd

Wi-Fi模块电源引脚的连接方法:

【RTL8189ES读取片内MAC地址的代码】

/* 显示WiFi模块参数信息 */
void WiFi_ShowInfo(void)
{uint32_t temp32;WiFi_EFuseInfo efuse_info;temp32 = WiFi_ReadReg32(1, WIFI_SYS_CFG);printf("SYS_CFG=0x%08x\n", temp32);printf("IC version: %c_CUT\n", 'A' + ((temp32 >> 12) & 0x0f));WiFi_ParseEFuseTable(&efuse_info);printf("eFuse section count: %u\n", efuse_info.efuse_sec_cnt);printf("eFuse data size: %u\n", efuse_info.efuse_size);printf("eFuse usage: %u%%\n", efuse_info.efuse_usage);printf("MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n", efuse_info.mac_addr[0], efuse_info.mac_addr[1], efuse_info.mac_addr[2], efuse_info.mac_addr[3], efuse_info.mac_addr[4], efuse_info.mac_addr[5]);
}/* 读取并解析片内eFuse数据 */
void WiFi_ParseEFuseTable(WiFi_EFuseInfo *info)
{uint8_t table[36][WIFI_EFUSE_SECTION_SIZE];info->efuse_sec_cnt = sizeof(table) / sizeof(table[0]);info->efuse_size = WiFi_LoadEFuseTable(table, &info->efuse_sec_cnt);info->efuse_usage = (uint8_t)((info->efuse_size * 100) / WIFI_EFUSE_CAPACITY);memcpy(info->mac_addr, &table[35][2], WIFI_MACADDR_LEN);
}/* 读取全部片内eFuse数据并解压缩 */
uint16_t WiFi_LoadEFuseTable(uint8_t table[][WIFI_EFUSE_SECTION_SIZE], uint8_t *sec_num)
{uint8_t header[2];uint8_t i, n = 0;uint8_t section, mask;uint16_t addr = 0;memset(table, 0xff, *sec_num * 8);while ((header[0] = WiFi_ReadEFuse(addr)) != 0xff){addr++;if (addr >= WIFI_EFUSE_CAPACITY)break; // 头部字段后没有更多数据了, 退出if ((header[0] & 0x1f) == 0x0f){/* 扩展头部 */// 低5位为01111, 说明头部字段有两个字节header[1] = WiFi_ReadEFuse(addr);addr++;if (addr >= WIFI_EFUSE_CAPACITY)break;if ((header[1] & 0x0f) != 0x0f){// header[1][7:4] -> section[6:3]// header[1][3:0] -> mask// header[0][7:5] -> section[2:0]// header[0][4:0] -> 01111section = ((header[1] & 0xf0) >> 1) | (header[0] >> 5);mask = header[1] & 0x0f;}else{/* 无效头部 (数据出错) */continue;}}else{/* 普通头部 */// header[0][7:4] -> section// header[0][3:0] -> masksection = header[0] >> 4;mask = header[0] & 0x0f;}if (n < section + 1)n = section + 1;for (i = 0; i < WIFI_EFUSE_SECTION_SIZE; i += 2){if ((mask & 1) == 0){if (section < *sec_num)table[section][i] = WiFi_ReadEFuse(addr);addr++;if (addr >= WIFI_EFUSE_CAPACITY)break;if (section < *sec_num)table[section][i + 1] = WiFi_ReadEFuse(addr);addr++;if (addr >= WIFI_EFUSE_CAPACITY)break;}mask >>= 1;}}*sec_num = n;return addr;
}/* 读取单字节片内eFuse数据 */
uint8_t WiFi_ReadEFuse(uint16_t addr)
{uint8_t temp;WiFi_WriteReg(1, WIFI_EFUSE_CTRL + 1, addr & 0xff); // 地址低8位temp = WiFi_ReadReg(1, WIFI_EFUSE_CTRL + 2);WiFi_WriteReg(1, WIFI_EFUSE_CTRL + 2, (temp & 0xfc) | ((addr >> 8) & 0x03)); // 地址高2位temp = WiFi_ReadReg(1, WIFI_EFUSE_CTRL + 3);WiFi_WriteReg(1, WIFI_EFUSE_CTRL + 3, temp & ~_BV(7)); // 清除read-ready标志while ((WiFi_ReadReg(1, WIFI_EFUSE_CTRL + 3) & _BV(7)) == 0); // 等待read-ready置1HAL_Delay(1); // 延时, 防止读取错误temp = WiFi_ReadReg(1, WIFI_EFUSE_CTRL); // 读数据return temp;
}

【RTL8189ES固件下载代码】
先EnableCard,再DownloadFirmware。

/* 执行WiFi模块上电操作 */
void WiFi_EnableCard(void)
{uint8_t temp;uint16_t temp16;// Call power on sequence to enable cardWiFi_WriteReg(1, WIFI_RSV_CTRL, 0); // unlock ISO/CLK/Power control register// RTL8188E_TRANS_CARDDIS_TO_CARDEMUtemp = WiFi_ReadReg(1, 0x86);WiFi_WriteReg(1, 0x86, temp & ~_BV(0)); // set SDIO suspend local registerwhile ((WiFi_ReadReg(1, 0x86) & _BV(1)) == 0); // wait power state to suspendtemp = WiFi_ReadReg(1, 0x10005);WiFi_WriteReg(1, 0x10005, temp & ~(_BV(3) | _BV(4))); // enable WL suspend// RTL8188E_TRANS_CARDEMU_TO_ACTwhile ((WiFi_ReadReg(1, 0x10006) & _BV(1)) == 0); // wait till power readytemp = WiFi_ReadReg(1, 0x10002);WiFi_WriteReg(1, 0x10002, temp & ~(_BV(0) | _BV(1))); // reset BBtemp = WiFi_ReadReg(1, 0x10026);WiFi_WriteReg(1, 0x10026, temp | _BV(7)); // schmit triggertemp = WiFi_ReadReg(1, 0x10005);temp &= ~_BV(7);WiFi_WriteReg(1, 0x10005, temp); // disable HWPDN (control by DRV)temp &= ~(_BV(4) | _BV(3));WiFi_WriteReg(1, 0x10005, temp); // disable WL suspendtemp |= _BV(0);WiFi_WriteReg(1, 0x10005, temp); // polling until return 0while (WiFi_ReadReg(1, 0x10005) & _BV(0));temp = WiFi_ReadReg(1, 0x10023);WiFi_WriteReg(1, 0x10023, temp & ~_BV(4)); // LDO normal mode// Enable power down and GPIO interrupttemp16 = WiFi_ReadReg16(1, WIFI_APS_FSMCO);WiFi_WriteReg16(1, WIFI_APS_FSMCO, temp16 | WIFI_APS_FSMCO_ENPDN);// Enable MAC DMA/WMAC/SCHEDULE/SEC blocktemp16 = WiFi_ReadReg16(1, WIFI_CR);temp16 |= WIFI_CR_HCI_TXDMA_EN | WIFI_CR_HCI_RXDMA_EN | WIFI_CR_TXDMA_EN | WIFI_CR_RXDMA_EN;temp16 |= WIFI_CR_PROTOCOL_EN | WIFI_CR_SCHEDULE_EN | WIFI_CR_ENSEC | WIFI_CR_CALTMR_EN;WiFi_WriteReg16(1, WIFI_CR, temp16);
}/* 下载固件 */
void WiFi_DownloadFirmware(void)
{int curr, page;int i, j;uint8_t value;uint32_t value32;WiFi_FirmwareHeader *header = (WiFi_FirmwareHeader *)firmware_mp_8188e_t_fw_nic;// 显示固件信息printf("Firmware version: 0x%02x\n", header->version);printf("Firmware subversion: 0x%02x\n", header->subversion);printf("Firmware signature: 0x%04x\n", header->signature);printf("Firmware release time: %02x-%02x %02x:%02x\n", header->month, header->date, header->hour, header->minute);// 复位8051内核value = WiFi_ReadReg(1, WIFI_MCUFWDL);if (value & WIFI_MCUFWDL_RAM_DL_SEL){WiFi_WriteReg(1, WIFI_MCUFWDL, 0x00);WiFi_Reset8051();}// 开始下载固件value = WiFi_ReadReg(1, WIFI_MCUFWDL);WiFi_WriteReg(1, WIFI_MCUFWDL, value | WIFI_MCUFWDL_EN); // MCU firmware download enablevalue = WiFi_ReadReg(1, WIFI_MCUFWDL + 2);WiFi_WriteReg(1, WIFI_MCUFWDL + 2, value & 0xf7); // 8051 reset// 重置校验值value = WiFi_ReadReg(1, WIFI_MCUFWDL);WiFi_WriteReg(1, WIFI_MCUFWDL, value | WIFI_MCUFWDL_CHKSUM_RPT);// 发送固件数据page = 0;for (i = 32; i < sizeof(firmware_mp_8188e_t_fw_nic); i += curr){// 设置页号value = WiFi_ReadReg(1, WIFI_MCUFWDL + 2);value &= ~WIFI_BYTE2(WIFI_MCUFWDL_PAGE);value |= WIFI_BYTE2((page << WIFI_MCUFWDL_PAGE_Pos) & WIFI_MCUFWDL_PAGE);WiFi_WriteReg(1, WIFI_MCUFWDL + 2, value);page++;// 计算当前页的数据量curr = sizeof(firmware_mp_8188e_t_fw_nic) - i;if (curr > WIFI_FW_8188E_END_ADDRESS - WIFI_FW_8188E_START_ADDRESS + 1)curr = WIFI_FW_8188E_END_ADDRESS - WIFI_FW_8188E_START_ADDRESS + 1;// 发送当前页的数据for (j = 0; j < curr; j++)WiFi_WriteReg(1, WIFI_FW_8188E_START_ADDRESS + j, firmware_mp_8188e_t_fw_nic[i + j]);printf("Downloaded %d bytes of firmware (%d-%d)\n", j, i, i + j - 1);}// 等待固件校验完毕while ((WiFi_ReadReg32(1, WIFI_MCUFWDL) & WIFI_MCUFWDL_CHKSUM_RPT) == 0);// 结束下载固件value = WiFi_ReadReg(1, WIFI_MCUFWDL);WiFi_WriteReg(1, WIFI_MCUFWDL, value & ~WIFI_MCUFWDL_EN); // MCU firmware download disableWiFi_WriteReg(1, WIFI_MCUFWDL + 1, 0x00); // reserved for fw extension// 启动固件value32 = WiFi_ReadReg32(1, WIFI_MCUFWDL);value32 |= WIFI_MCUFWDL_RDY;value32 &= ~WIFI_MCUFWDL_WINTINI_RDY;WiFi_WriteReg32(1, WIFI_MCUFWDL, value32);WiFi_Reset8051();while ((WiFi_ReadReg32(1, WIFI_MCUFWDL) & WIFI_MCUFWDL_WINTINI_RDY) == 0);printf("Firmware is successfully downloaded\n");
}

【程序运行结果】

STM32F103RE RTL8189ES
[Clock] freq=400.0kHz, requested=400.0kHz, divider=178
Ignored CMD5 CRC error
RESPCMD63, RESP1_90fc0000
Ignored CMD5 CRC error
RESPCMD63, RESP1_90fc0000
Number of I/O Functions: 1
Memory Present: 0
Relative Card Address: 0x0001
Card selected. RESP1_00001e00
[Clock] freq=24000.0kHz, requested=25000.0kHz, divider=1
[CIS] func=0, ptr=0x00001000
Manufacturer Code: 0x024c
Manufacturer Information: 0x8179
Card Function Code: 0x0c
System Initialization Bit Mask: 0x00
Maximum Block Size: 8
Maximum Transfer Rate Code: 0x32
[CIS] func=1, ptr=0x00001100
Card Function Code: 0x0c
System Initialization Bit Mask: 0x00
Maximum Block Size: 512
SYS_CFG=0xc4403710
IC version: D_CUT
eFuse section count: 36
eFuse data size: 160
eFuse usage: 62%
MAC Address: 30:1B:97:41:C6:65
Firmware version: 0x1c
Firmware subversion: 0x00
Firmware signature: 0x88e1
Firmware release time: 05-05 14:27
Downloaded 4096 bytes of firmware (32-4127)
Downloaded 4096 bytes of firmware (4128-8223)
Downloaded 4096 bytes of firmware (8224-12319)
Downloaded 2942 bytes of firmware (12320-15261)
Firmware is successfully downloaded
SDIO->STA=0x00000000

【兼容最新的只有AC6编译器的Keil 5.38a版本】
1. 在ST官网下载en.stm32cubef1.zip(V1.8.0版本),将STM32Cube_FW_F1_V1.8.0/Drivers/CMSIS/Include/cmsis_armclang.h解压到项目的STM32F1xx_HAL_Driver目录中。(https://pan.baidu.com/s/1_tM1bBlx2Brg9mDPDWdVUg?pwd=sx6t)
2. 在项目属性中Target选项卡的ARM Compiler选择Use default compiler version 6,然后在C/C++ (AC6)选项卡的Define文本框中定义宏__FILE_INCOMPLETE=1。
3. 把WiFi.h里面的typedef __packed struct改为typedef struct __attribute__((packed))。
4. 把common.c中的#pragma import(__use_no_semihosting)改为:
// 禁用半主机模式 (不然调用printf就会进HardFault)
#ifdef __clang__
__asm(".global __use_no_semihosting\n\t");
#else
#pragma import(__use_no_semihosting)
#endif

这篇关于STM32驱动Realtek RTL8189ES WiFi模块读取MAC地址并下载固件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/212796

相关文章

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,

Mac系统下卸载JAVA和JDK的步骤

《Mac系统下卸载JAVA和JDK的步骤》JDK是Java语言的软件开发工具包,它提供了开发和运行Java应用程序所需的工具、库和资源,:本文主要介绍Mac系统下卸载JAVA和JDK的相关资料,需... 目录1. 卸载系统自带的 Java 版本检查当前 Java 版本通过命令卸载系统 Java2. 卸载自定

springboot下载接口限速功能实现

《springboot下载接口限速功能实现》通过Redis统计并发数动态调整每个用户带宽,核心逻辑为每秒读取并发送限定数据量,防止单用户占用过多资源,确保整体下载均衡且高效,本文给大家介绍spring... 目录 一、整体目标 二、涉及的主要类/方法✅ 三、核心流程图解(简化) 四、关键代码详解1️⃣ 设置

一文深入详解Python的secrets模块

《一文深入详解Python的secrets模块》在构建涉及用户身份认证、权限管理、加密通信等系统时,开发者最不能忽视的一个问题就是“安全性”,Python在3.6版本中引入了专门面向安全用途的secr... 目录引言一、背景与动机:为什么需要 secrets 模块?二、secrets 模块的核心功能1. 基

Python pip下载包及所有依赖到指定文件夹的步骤说明

《Pythonpip下载包及所有依赖到指定文件夹的步骤说明》为了方便开发和部署,我们常常需要将Python项目所依赖的第三方包导出到本地文件夹中,:本文主要介绍Pythonpip下载包及所有依... 目录步骤说明命令格式示例参数说明离线安装方法注意事项总结要使用pip下载包及其所有依赖到指定文件夹,请按照以

全屋WiFi 7无死角! 华硕 RP-BE58无线信号放大器体验测评

《全屋WiFi7无死角!华硕RP-BE58无线信号放大器体验测评》家里网络总是有很多死角没有网,我决定入手一台支持Mesh组网的WiFi7路由系统以彻底解决网络覆盖问题,最终选择了一款功能非常... 自2023年WiFi 7技术标准(IEEE 802.11be)正式落地以来,这项第七代无线网络技术就以超高速

SpringBoot读取ZooKeeper(ZK)属性的方法实现

《SpringBoot读取ZooKeeper(ZK)属性的方法实现》本文主要介绍了SpringBoot读取ZooKeeper(ZK)属性的方法实现,强调使用@ConfigurationProperti... 目录1. 在配置文件中定义 ZK 属性application.propertiesapplicati

Python中文件读取操作漏洞深度解析与防护指南

《Python中文件读取操作漏洞深度解析与防护指南》在Web应用开发中,文件操作是最基础也最危险的功能之一,这篇文章将全面剖析Python环境中常见的文件读取漏洞类型,成因及防护方案,感兴趣的小伙伴可... 目录引言一、静态资源处理中的路径穿越漏洞1.1 典型漏洞场景1.2 os.path.join()的陷

如何确定哪些软件是Mac系统自带的? Mac系统内置应用查看技巧

《如何确定哪些软件是Mac系统自带的?Mac系统内置应用查看技巧》如何确定哪些软件是Mac系统自带的?mac系统中有很多自带的应用,想要看看哪些是系统自带,该怎么查看呢?下面我们就来看看Mac系统内... 在MAC电脑上,可以使用以下方法来确定哪些软件是系统自带的:1.应用程序文件夹打开应用程序文件夹

Mac备忘录怎么导出/备份和云同步? Mac备忘录使用技巧

《Mac备忘录怎么导出/备份和云同步?Mac备忘录使用技巧》备忘录作为iOS里简单而又不可或缺的一个系统应用,上手容易,可以满足我们日常生活中各种记录的需求,今天我们就来看看Mac备忘录的导出、... 「备忘录」是 MAC 上的一款常用应用,它可以帮助我们捕捉灵感、记录待办事项或保存重要信息。为了便于在不同