【CC1352P测评】无线CPU和主CPU的通信方式
[复制链接]
CC1352 的无线部分由一颗 ARM Cortex-m0 的 CPU 负责,那么它和主 CPU 是怎么使用片上资源的,又如何协同工作的呢?
SDK 中并没有包含任何 Cortex-m0 CPU 的代码相关的任何东西,因此不需要对它进行编程。与 ST STM32WB55 不同的是,CC1352 的这个 Cortex-m0 CPU 并不使用系统 Flash 来存放程序——它使用自己的 ROM. 这样就不支持软件升级,也不怕被误操作破坏固件。
手册上的这个图显示了两个 CPU 的子系统如何连接和通信。
按照手册的说法,系统 RAM 和 Radio RAM 是两个CPU都可以访问的,数据可以放在任何一块 RAM 中共享,以便数据传递(也可以由DMA在它们之间搬运数据)。Radio RAM 有一部分是可以在低功耗模式下保持数据的,因此可以实现主 CPU、SRAM 掉电后无线部分以极低功耗待机,并在需要的时候唤醒系统。
Radio Doorbell 提供了两个 CPU 之间的消息通信渠道,因为 Doorbell 可以向两个 CPU 分别产生 IRQ. 在 Cortex-m4 主CPU这一边有4个IRQ: RF_CPE0, RF_CPE1, RF_HW 以及 RF_CMD_ACK. 寄存器数量不多,除了与中断相关的,有意思的是 CMDR 和 CMDSTA 两个寄存器。
这里“命令”(CMD)的含义,并不是给 Doorbell 这个硬件设备的命令,而是要向无线子系统发出的命令,即给 Cortex-m0 CPU 传递的命令。寄存器表示的命令内容只有软件才可以解析,不过仅仅这一个 32-bit 寄存器,如何包括命令的全部内容?再细看 CMDR 的说明就大致明白了:
也就是,CMDR 可以传递一个“直接”的命令,或者一个 32-bit 对齐了的地址。联想到我在分析 rfEasylink_nortos 例子的时候见到的 RF 命令结构体,可以猜想一定就是把 RF 命令结构变量的地址写到了 Doorbell.
不妨再找 SDK 中 RF 驱动代码来看看。在 RFCC26X2_multiMode.c 中,RF_dispatchNextCmd() 函数里有如下的代码片段:
/* Decode the radio operation itself. */
RF_Op* pOp = (RF_Op*)pNextCmd->pOp;
/* Send the radio operation to the RF core. */
RFCDoorbellSendTo((uint32_t)pOp);
而 RFCDoorbellSendTo() 函数是这样实现的:
uint32_t RFCDoorbellSendTo(uint32_t pOp)
{
// Wait until the doorbell becomes available
while(HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDR) != 0);
RFCAckIntClear();
// Submit the command to the CM0 through the doorbell
HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDR) = pOp;
// Wait until the CM0 starts to parse the command
while(!HWREG(RFC_DBELL_BASE + RFC_DBELL_O_RFACKIFG));
RFCAckIntClear();
// Return with the content of status register
return(HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDSTA));
}
没错,的确就是把 RF_Op 类型指针写到了 CMDR 寄存器里面。然后无线专用的 CPU 会根据地址去解析命令、读取命令包含的数据。
CC13x2 的手册中用了一百多页的篇幅列出了各类命令的数据包结构定义。虽然开发比如 BLE, Zigbee 这样的应用不需要去了解到如此底层的细节,TI将MCU作为一个器件,其手册的完备性是可圈可点。
|