KDocs 研发资料库
  • 手表穿戴技术应用文档入口汇总
  • JL707N穿戴客述问题FAQ
  • 彩屏仓 硬件开发指南 与 量产作业流程规范
  • 彩屏仓 AC98N和JL701烧录升级注意事项
  • JL707 硬件开发资料
  • JL707 手表硬件设计注意事项 总结
  • 穿戴生产烧录OTA和key文件添加使用说明
  • JL707N-入门到进阶开发指导文档
  • 彩屏仓982相关
  • 彩屏仓耳机介绍
  • 杰理701_707双屏demo介绍
  • 707电子吧唧开发资料
  • GPIO相关
  • UART串口相关
  • SPI相关
  • nandflash相关
  • norflash相关
  • IIC相关
  • PWM相关
  • SD卡相关
  • 定时器TIMER
  • 文件系统接口设计说明文档
  • 音视频录像开发流程
  • rdec编码器
  • 穿戴功耗数据标准
  • 手表蓝牙开发文档
  • 701蓝牙PAN联网demo
  • BLE开发使用说明
  • 701手表2.0.0版本SDK EQ在线调试和离线调试方法 V1.1
  • JL707 手表喇叭输出声音大小评估方法 V1.0
  • JL707 手表音频EQ调试方法 V1.0
  • AC707N 手表通话写卡 软件配置方法
  • 录音功能
  • 701手表2.X.X系列SDK调试EQ配置方法及音频调试技巧V1.1
  • 701手表104版本SDK EQ在线调试和离线调试方法 V1.1
  • mic2dac示例
  • P11 SensorHub相关
  • 手表升级操作文档
  • AC707NGPU
  • DBI模块介绍
  • GPU模块介绍
  • 701N屏幕驱动配置说明
  • 701N_UI编辑工具用户手册
  • 支付宝资料
  • 支付宝硬件接入资料
  • 支付宝乘车码接入资料
  • CAT1 接入文档
  • 701N_WATCH_CAT1开发说明
  • Findmy功能
  • music模式相关
  • 707电池曲线
  • 707N内置FLASH挂载FAT文件系统251112_v1.2
  • AC707N_本地视频播放demo(AVI-MJPEG-PCM)
  • 光波导屏幕调试
  • 耳机研发和生产流程 指南
  • 707-NandFlash 代码和UI资源独立烧录方案
  • 彩屏仓时间同步补丁
  • 彩屏仓抖音点赞移植
  • 707LVGLv8双屏开发
  • 707N蓝牙互传图传demo
  • AVIPCM数据流接入AIVOICE
  • Flash分区操作demo
  • 手表发射问题
  • 701_707 双备份升级DEMO
  • 707_乘车码刷码失败问题_共性

707 小核IIC1硬件从机

📎 原始文档:https://www.kdocs.cn/l/cqIsYeh9zCs8 707 小核IIC1硬件从机

背景

707 sensorhub的硬件IIC1从机只能放在小核,主机可以在大核使用
小核工程代码对应路径:SensorHub
大核工程代码对应路径:SDK

小核工程编译完后会生成p11_code.bin,不能直接烧录
大核工程编译完,烧录时,会一并将小核代码p11_code.bin烧录到指定位置

实现代码

小核部分

  1. main.h新增IIC事件 image

  2. iic_api.h增加接口声明 image

void hw_iic_slave_module_init();
  1. sdk_config.h使能IIC并配置IO和频率 image
  2. ld文件改动 image
*(.iic.text.cache.L1)
  1. 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
}

大核部分

  1. p11_app_msg.h新增对应事件,id要和小核保持一致 image

  2. 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;
    }
}
  1. 板级打开宏 TCFG_SENSOR_HUB&&TCFG_SENSOR_HUB_P11
    image

注意事项

sensorhub一共只有32kram,如果在大小核中传输大量数据,参考如下形式,在小核中创建全局数组(例如4k的buf)
通过p2m_post_msg进行大小核通信时(最大支持传输32字节),将sensorhub的4k数组起始地址传给大核,sensorhub的ram大核可以直接访问
image

验证

1、读0x34(0x68右移一位)设备,0x02寄存器,长度为5
imageimage

2、写0xab 0xba
imageimage