707 小核IIC1硬件从机
📎 原始文档:https://www.kdocs.cn/l/cqIsYeh9zCs8 707 小核IIC1硬件从机
背景
707 sensorhub的硬件IIC1从机只能放在小核,主机可以在大核使用
小核工程代码对应路径:SensorHub
大核工程代码对应路径:SDK
小核工程编译完后会生成p11_code.bin,不能直接烧录
大核工程编译完,烧录时,会一并将小核代码p11_code.bin烧录到指定位置
实现代码
小核部分
main.h新增IIC事件

iic_api.h增加接口声明

void hw_iic_slave_module_init();
- sdk_config.h使能IIC并配置IO和频率

- ld文件改动

*(.iic.text.cache.L1)
- iic_api.c改动 新增IIC从机初始化配置接口
#include "sensor_driver.h"
enum gpio_mode {
PORT_OUTPUT_LOW = 0,
PORT_OUTPUT_HIGH = 1,
PORT_HIGHZ = 2, //高阻模式
PORT_INPUT_FLOATING = 0x10, //浮空输入
PORT_INPUT_PULLUP_10K = 0x11,
PORT_INPUT_PULLUP_100K,
PORT_INPUT_PULLUP_1M,
PORT_INPUT_PULLDOWN_10K = 0x21,
PORT_INPUT_PULLDOWN_100K,
PORT_INPUT_PULLDOWN_1M,
PORT_KEEP_STATE = 0x30,
};
#define IIC_SCL_IO IO_PORTB_04
#define IIC_SDA_IO IO_PORTB_05
#define IIC_SLAVE_INDEX HW_IIC_0
#define SLAVE_BUF_TEST_ENABLE 1
#if SLAVE_BUF_TEST_ENABLE
u8 slave_tx_buf_test[16];
u8 slave_rx_buf_test[16];
#endif
AT(.iic.text.cache.L1)
// ___interrupt
void hw_iic_isr_fun_test()//slave test
{
putchar('a');
static int rx_state = 0, tx_cnt = 0, rx_cnt = 1;
u8 iic = IIC_SLAVE_INDEX;
// #if defined CONFIG_IIC_VERSION2
if ((hw_iic_get_pnd(iic, I2C_PND_START)) || (hw_iic_get_pnd(iic, I2C_PND_ADR_MATCH))) {
putchar('b');
// #else
// if (rx_state == 0) {
// #endif
rx_state = hw_iic_slave_rx_byte(iic, &slave_rx_buf_test[0]);//addr
if (rx_state == IIC_SLAVE_RX_ADDR_RX) { //rx
putchar('c');
hw_iic_slave_rx_prepare(iic, 1, 0);
} else if (rx_state == IIC_SLAVE_RX_ADDR_TX) { //tx
putchar('d');
//准备数据并发送(不能耗时太久)
hw_iic_slave_tx_byte(iic, slave_tx_buf_test[tx_cnt++]);
} else { //error
putchar('e');
printf("error iic slave rx addr error!\n");
rx_state = 0;
hw_iic_slave_rx_prepare(iic, 0, 0);
}
return;
}
if (hw_iic_get_pnd(iic, I2C_PND_STOP)) {
putchar('f');
hw_iic_clr_all_pnd(iic);
hw_iic_slave_rx_prepare(iic, 0, 0);
if (rx_state >= IIC_SLAVE_RX_ADDR_RX) { //rx
putchar('g');
printf("---sensorhub--- printf rx buf:\n");
put_buf(slave_rx_buf_test, rx_cnt);
//发送 事件 给大核
u8 msg[32]; // 最大支持32字节
memset(msg, 0, sizeof(msg));
msg[0] = MSG_P11_IIC_EVENT;
msg[1] = slave_rx_buf_test[0];
msg[2] = slave_rx_buf_test[1];
msg[3] = slave_rx_buf_test[2];
p2m_post_msg(MSG_APP, 0, (u8 *)msg, sizeof(msg));
// task_post_msg(NULL, 4, MSG_P11_IIC_EVENT, slave_rx_buf_test[0], slave_rx_buf_test[1], slave_rx_buf_test[2]);
}
rx_state = 0;
tx_cnt = 0;
rx_cnt = 1;
return;
}
if (hw_iic_get_pnd(iic, I2C_PND_TASK_DONE)) {
putchar('h');
if (rx_state == 0) { //error
putchar('i');
hw_iic_clr_all_pnd(iic);
hw_iic_slave_rx_prepare(iic, 0, 0);
} else if (rx_state == IIC_SLAVE_RX_ADDR_TX) { //tx
putchar('j');
if (hw_iic_slave_tx_check_ack(iic) == 0) { //no ack
putchar('k');
return;
}
hw_iic_slave_tx_byte(iic, slave_tx_buf_test[tx_cnt++]);
} else if (rx_state >= IIC_SLAVE_RX_ADDR_RX) { //rx
putchar('l');
hw_iic_slave_rx_byte(iic, &slave_rx_buf_test[rx_cnt++]);
// hw_iic_slave_rx_prepare(iic, 1, 0);
}
}
}
void hw_iic_slave_module_init()
{
printf("iic slave init\n");
struct hw_iic_slave_config hw_iic_config_test = {
.config.role = IIC_SLAVE,
.config.scl_io = IIC_SCL_IO + IIC_SLAVE_INDEX,
.config.sda_io = IIC_SDA_IO + IIC_SLAVE_INDEX,
.config.io_mode = PORT_INPUT_PULLUP_10K,//上拉或浮空
.config.hdrive = PORT_DRIVE_STRENGT_2p4mA, //enum GPIO_HDRIVE 0:2.4MA, 1:8MA, 2:26.4MA, 3:40MA
.config.ie_en = 0,
.config.irq_priority = 3,
.config.io_filter = 1,
// .slave_addr = 0xd0,
.slave_addr = 0x68,
.iic_slave_irq_func = NULL,
};
#if SLAVE_BUF_TEST_ENABLE
for (u16 i = 0; i < sizeof(slave_rx_buf_test); i++) {
slave_rx_buf_test[i] = 0;
}
for (u8 i = 0; i < sizeof(slave_tx_buf_test); i++) {
slave_tx_buf_test[i] = i;
}
#endif
#if 1//ie test
hw_iic_config_test.config.ie_en = 1;
hw_iic_config_test.iic_slave_irq_func = hw_iic_isr_fun_test;
enum iic_state_enum iic_init_state1 = hw_iic_slave_init(IIC_SLAVE_INDEX, &hw_iic_config_test);
if (iic_init_state1 == IIC_OK) {
printf("---sensorhub--- iic%d_slave init ok", IIC_SLAVE_INDEX);
}else{
printf("---sensorhub--- iic%d_slave init fail", IIC_SLAVE_INDEX);
}
#endif
}
大核部分
p11_app_msg.h新增对应事件,id要和小核保持一致

sensor_driver_p11.c修改接受handler 增加对MSG_P11_IIC_EVENT的解析
static void p11_msg_handler(void *priv, u8 *buf, u32 len)
{
u8 msg[32];
ASSERT(len <= sizeof(msg),"p11_msg_handler: len=%d, too long");
memcpy(msg, buf, len);
printf("p11_msg_handler: %d, len: %d\n", msg[0], len);
put_buf(msg, len);
switch (msg[0]) { // 默认按照u8组包
case MSG_P11_SENSOR_INFO:
// p11_sensor_dev_begin = msg[1] + P11_RAM_BASE;
// p11_sensor_dev_end = msg[2] + P11_RAM_BASE;
u32 *msg_i = (u32 *)msg;
p11_sensor_dev_begin = msg_i[1]; // 直接拿完整地址
p11_sensor_dev_end = msg_i[2];
printf("p11_sensor_dev_begin=%x end=%x", p11_sensor_dev_begin, p11_sensor_dev_end);
break;
case MSG_P11_SENSOR_EVENT:
break;
case MSG_P11_ALGORITHM_EVENT:
sport_health_manager_msg_post(SHM_MOD_DET_WRIST, SHM_CMD_UPDATE, (void *)msg[1], 0);
break;
case MSG_P11_IIC_EVENT:
// printf("MSG_P11_IIC_EVENT\n");
printf("MSG_P11_IIC_EVENT (0x%x, 0x%x, 0x%x)\n", msg[1], msg[2], msg[3]);
break;
default:
break;
}
}
- 板级打开宏 TCFG_SENSOR_HUB&&TCFG_SENSOR_HUB_P11

注意事项
sensorhub一共只有32kram,如果在大小核中传输大量数据,参考如下形式,在小核中创建全局数组(例如4k的buf)
通过p2m_post_msg进行大小核通信时(最大支持传输32字节),将sensorhub的4k数组起始地址传给大核,sensorhub的ram大核可以直接访问
验证
1、读0x34(0x68右移一位)设备,0x02寄存器,长度为5

2、写0xab 0xba
