5.7:通过硬件 UART 读取芯片 ID
1. 适用设备
适用设备为 PW200/PW300。
PWX1 在当前文档时间编写时,不支持 UART 读取芯片 ID,未来会开放 UART 功能。
2. 准备工作
2.1 升级固件
升级固件到1.99.03 以上,专版电子烟固件。
2.2 工程设置以及接线图参考
2.2.1 设备供电方式
当选择从VIN 给设备供电时,请注意电压范围:3.3V~5.5V,超过5.5V 时,可能导致设备损毁,低于3.3V 时,设备可能无法工作。
2.2.2 工程设置参考以及接线
主控型号:当前演示选的 PY32F030xx3 芯片。
擦除方式:选不擦除,避免将电子烟的意外擦掉。
接口电平:
方式1(推介):选5V,并且烧录器的VREF 不接,悬空,如下图所示:
方式2(当方式1 无法读取ID时):选外部输入,接给电子烟的供电口连接在一起,如下图所示:
当选择外部输入时,请和电子烟的USB 供电连一起,电压不要超过5.5V,以及由于电子元器件会存在公差,最好是不要超过5.3V,否则可能由于元器件误差,导致发热,或者影响寿命(内部有稳压管),不要接比如 12V,24V,否则会因为超出烧录器的设计负载能力而烧毁烧录器。
编程速度:选用1Mhz 即可。
选项字模式:选无操作到无操作。
2.3 启用 AT 功能并加载项目
在菜单栏、设置、设备首选项中开启 AT 功能(UART)。
2.4 加载工程到设备
选择好芯片之后,加载空工程到设备中,如下所示:
由于只需要读取芯片 ID,只需要一个空工程即可,无需添加数据。
3. 开源 AT API 接入
3.1 针对电子烟测试的简化流程
3.1.1 读取目标芯片 ID
调用 powerwriter_at_target_id 发送读取目标芯片 ID 命令,如果读取正常,将会返回 ATCmdRspTargetChipID 命令,如果失败,则会返回 ATCmdStatusError。
读取目标芯片 ID(未加密时):
//50 57 41 54 18 00 00 00 66 00 00 00 04 00 00 00 00 00 00 00 d3 b7 4e 74
// 固定头部 | 帧长度 |0x66为读取ID | 0x04命令长度 | 命令保留值 | crc32 |
返回值为 ATCmdRspTargetChipID 或者是 ATCmdStatusError(未加密时):
#define PW_TARGET_ID_MAX 16 // Target chip ID MAX size
typedef struct S_ATCmdRspTargetChipID
{
uint8_t m_CIDSize; // Target chip ID size
uint8_t m_CIDData[PW_TARGET_ID_MAX]; // Target chip ID data
} S_ATCmdRspTargetChipID;
/* ATCmdRspTargetChipID */
/*
50 57 41 54 25 00 00 00 67 00 00 00 11 00 00 00 10 32 30 53 41 13 33 32 33 33
固定头部 | 帧长度 |ATCmdRspTargetChipID | 0x11 命令长度|ID 长度|ID 值
22 6e 10 78 b1 01 56 84 6b 94 1e
| CRC32 |
*/
/* Get target id */
S_ATCmdRspTargetChipID m_target_id;
if (!powerwriter_at_target_id(channel, &m_target_id))
{
powerwriter_at_log(LOGE, "[%08X]:powerwriter get target id failure ...\r\n",
powerwriter_at_last_error(channel));
return false;
}
object_print(m_target_id.m_CIDData, m_target_id.m_CIDSize, "Target chip id");
powerwriter_at_log(LOGD, "powerwriter get target id successfully ...\r\n");
3.1.2 读取目标芯片数据(版本信息)
不同的读取地址和长度,指令的CRC32 不是固定的,可以通过源码的sample 抓取收发数据来抄,或者联系创芯工坊的技术支持,让其协助给出16进制序列。
调用 powerwriter_at_target_read发送读取目标芯片数据命令,如果读取正常,将会返回 ATCmdRspTargetMemory命令,如果失败,则会返回 ATCmdStatusError (结构见上一节)。
读取目标芯片ID(未加密时):
//固定头部(4) | 帧长度(4) |0x68为读芯片数据|0x08命令长度| 读取地址 | 读取长度 | crc32 |
//50 57 41 54 1c 00 00 00 68 00 00 00 08 00 00 00 00 10 00 20 02 00 00 00 62 dd 55 8b //从0x20001000读取2字节
//50 57 41 54 1c 00 00 00 68 00 00 00 08 00 00 00 00 10 00 08 20 00 00 00 12 de df 70 //从0x08001000读取32字节
//50 57 41 54 1c 00 00 00 68 00 00 00 08 00 00 00 20 10 00 20 20 00 00 00 81 d8 18 78 //从0x20001020读取32字节
返回值为 ATCmdRspTargetMemory 或者是 ATCmdStatusError(未加密时):
#define PW_PACKAGE_SIZE 256 // Buffer size of block data
typedef struct S_ATCmdTargetMemory
{
uint32_t m_address; // Current data address
uint32_t m_size; // Current data size
uint8_t m_buffer[PW_PACKAGE_SIZE]; // Current data buffer (fixed length)
} S_ATCmdRspTargetMemory,
/* ATCmdRspTargetMemory */
/*
50 57 41 54 //固定头部
1c 01 00 00 //帧长度
69 00 00 00 //69 表示返回数据
08 01 00 00 //0x108 标识数据长度
00 10 00 20 //表示读取的地址为 0x20001000
02 00 00 00 //表示读取的数据长度
//下面表示256 字节的缓冲区,有效数据是前两个
ba 8c 33 43 46 37 43 45 43 42 45 30 34 30 36 44
32 45 37 32 31 46 38 42 31 35 32 43 30 31 34 32
31 2e 34 00 00 00 00 00 31 2e 30 30 2e 30 36 00
31 2e 30 31 2e 33 32 00 b2 d1 0a 6b e7 40 1a ed
e7 30 b5 68 4b 00 21 68 4c 4b 44 19 70 0a 46 7c
44 55 00 65 5b 85 42 00 d1 01 21 52 1c 02 2a f7
d3 19 70 00 29 01 d0 00 20 30 10 b5 00 23 02 e0
cc 5c c4 54 5b 1c 93 42 fa d3 10 bd 10 b5 00 22
ff 23 03 e0 4a 29 04 d0 83 54 52 1c 8a 42 f9 d3
10 bd 84 18 40 34 e4 7f 84 54 f6 e7 40 1a ed e7
30 b5 68 4b 00 21 68 4c 4b 44 19 70 0a 46 7c 44
55 00 65 5b 85 42 00 d1 01 21 52 1c 02 2a f7 d3
19 70 00 29 01 d0 00 20 30 bd 01 20 30 bd f0 b5
5c 4c 16 46 0f 46 05 46 4c 44 00 2b 18 d0 5b 48
57 4a e0 60 00 20 4a 44 90 32 2b 5c 11 18 4b 70
3b 5c 40 1c 4b 74 10 28 f7 db 51 48 4b 22 48 44
b0 07 eb 06 //命令的CRC32
*/
收发数据可以通过 demo 抓取分析。
#ifdef AT_ONLINE_READ_DATA_SAMPLE
// example is G32F350xB ,128 KB Flash & 16K sram
int i = 0;
powerwriter_at_log(LOGD, "powerwriter read target memory starting ...\r\n");
S_ChipMemoryCfg m_chip_memory[] = {
{.m_s_addr = 0x20001000,
.m_e_addr = 0x20001002,
.m_name = "2byte SRAM"},
{.m_s_addr = 0x08001000,
.m_e_addr = 0x08001020,
.m_name = "32 byte Flash"},
{.m_s_addr = 0x20001020,
.m_e_addr = 0x20001040,
.m_name = "32 byte SRAM"},
};
S_ATCmdRspTargetMemory *mem = 0;
for (i = 0; i < ARRAY_SIZE(m_chip_memory); i++)
{
uint32_t addr = m_chip_memory[i].m_s_addr;
do
{
int read_size = MIN(PW_PACKAGE_SIZE, m_chip_memory[i].m_e_addr - addr);
if (!powerwriter_at_target_read(channel, addr, read_size, &mem))
{
powerwriter_at_log(LOGE, "[%08X]:powerwriter read target memory failure ...\r\n",
powerwriter_at_last_error(channel));
return false;
}
powerwriter_at_log(LOGD, "(%s)memmory addr: 0x%08X, memory size: %d\r\n", m_chip_memory[i].m_name,
mem->m_address, mem->m_size);
object_print(mem->m_buffer, mem->m_size, "data block:");
addr += mem->m_size;
} while (addr < m_chip_memory[i].m_e_addr);
}
powerwriter_at_log(LOGD, "powerwriter read target memory test passed ...\r\n");
#endif
3.1.3 写SRAM 数据
由于读取芯片ID 时,会暂停芯片的执行,所以在连接,读取CID 之后,需要对产品进行功能复位,否则可能需要对设备进行断电,或者手动重启设备,才能恢复产品的功能(比如电子烟不出烟了)。
复位目标芯片(未加密时):
// 口数清零 puff 操作 0x20001000-0x20001001 共 2个byte
50 57 41 54 1e 00 00 00 6d 00 00 00 0a 00 00 00 00 10 00 20 02 00 00 00 00 00 2c 52 b4 c5
// 固定头部 | 帧长度 |0x6d 为写数据| 0x0a命令长度 | 写入地址 | 写入长度 | 写为0 | crc32
返回值为 ATCmdStatusOk 或者是 ATCmdStatusError(未加密时),参考连接芯片时的错误码。
3.1.4 特别说明
读写不同的地址,crc32 不一样,如果不清楚值为多少,可以咨询技术支持,获取指令序列,或者自行基于 AT code 开源库,进行数据抓取。
3.2 PowerWriter 开源 AT 源码
参考文档地址:4.3:AT 开源接口 | PowerWriter文档中心,下载源码包,如下图所示:
下载后解压,可以看到如下的目录,其中 source 目录有跨平台的 API 源码:
powerwriter_at_core 为跨平台实现,只需要适配串口收发,以及时间戳实现接口等,即可在几乎所有平台运行,目前提供的 demo 为 windows 版本,其他平台暂未提供 demo,可以参考 powerwriter_at_samples.c 进行实现。
4. 注意事项
4.1 关于默认的通信波特率
PowerWriter AT 端口的默认波特率为:9600,当使用PowerWriter 客户端连接过后,AT 端口的波特率会变成 115200,当断开PowerWriter 客户端连接时,波特率将恢复默认的 9600,如果无法通信,请重新将PowerWriter 设备重新上电之后再试。
请注意通信的波特率。
4.2 关于设备供电和VREF电压范围
请特别注意:VREF 和 VIN,USB 的安全供电范围,都不要超过5.5V(设计极限),否则可能导致烧录器损坏,或者降低烧录器的使用寿命。