Hi3861的micropython移植之硬件I2C 原创 精华

再见南丫岛
发布于 2022-4-5 17:17
浏览
1收藏

这篇文章,先说一下硬件I2C的方案。后续文档会说明软件I2C的python移植。

0、底层框架函数

STATIC const mp_rom_map_elem_t machine_i2c_locals_dict_table[] = {
    { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&machine_i2c_scan_obj) },

    // standard bus operations
    { MP_ROM_QSTR(MP_QSTR_readfrom), MP_ROM_PTR(&machine_i2c_readfrom_obj) },
    { MP_ROM_QSTR(MP_QSTR_readfrom_into), MP_ROM_PTR(&machine_i2c_readfrom_into_obj) },
    { MP_ROM_QSTR(MP_QSTR_writeto), MP_ROM_PTR(&machine_i2c_writeto_obj) },
    { MP_ROM_QSTR(MP_QSTR_writevto), MP_ROM_PTR(&machine_i2c_writevto_obj) },

    // memory operations
    { MP_ROM_QSTR(MP_QSTR_readfrom_mem), MP_ROM_PTR(&machine_i2c_readfrom_mem_obj) },
    //{ MP_ROM_QSTR(MP_QSTR_readfrom_mem_into), MP_ROM_PTR(&machine_i2c_readfrom_mem_into_obj) },
    { MP_ROM_QSTR(MP_QSTR_writeto_mem), MP_ROM_PTR(&machine_i2c_writeto_mem_obj) },
};

主要实现以上的这几个函数即可。

1、I2C的初始化

在machine_hard_i2c_make_new函数中,需要对Hi3861的I2C接口进行初始化。

mp_obj_t machine_hard_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
    enum { ARG_id, ARG_freq,};
    static const mp_arg_t allowed_args[] = {
        { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_OBJ },
        { MP_QSTR_freq, MP_ARG_INT, {.u_int = 100000} },
    };

    // Parse args.
    mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
    mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);

    // Get I2C bus.
    int i2c_id = mp_obj_get_int(args[ARG_id].u_obj);
    machine_i2c_obj_t *self =NULL;
    for(int i=0;i< MP_ARRAY_SIZE(machine_i2c_obj);i++)
    {
        if(i2c_id == machine_i2c_obj[i].i2c_id)
        {
            self = (machine_i2c_obj_t *)&machine_i2c_obj[i];
        }
    }
    if (self == NULL || self->base.type == NULL) {
        mp_raise_ValueError(MP_ERROR_TEXT("invalid i2c channel"));
    }
    self->baudrate = args[ARG_freq].u_int;

    if(self->ble_ex == 0)
    {
        //if(self->i2c_id == 11)
        {
            IoTGpioInit(13);
            IoTGpioSetDir(13, 1);
            hi_io_set_func(13,HI_IO_FUNC_GPIO_13_I2C0_SDA);
            IoTGpioInit(14);
            IoTGpioSetDir(14, 1);
            hi_io_set_func(14,HI_IO_FUNC_GPIO_14_I2C0_SCL);
            hi_i2c_init(0, self->baudrate); 
        }
    }
    else
    {
        set_i2c_attribute(self->i2c_id, self->baudrate);
    }
    return MP_OBJ_FROM_PTR(self);
}

3、读函数

STATIC int mp_machine_i2c_readfrom(mp_obj_base_t *self_in, uint16_t addr, uint8_t *dest, size_t len, bool stop) {
    machine_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
    if(self->ble_ex == 0)
    {
        hi_i2c_data i2c_data = {0};
        uint8_t  buffer[1] = {0x00};
        i2c_data.send_buf = buffer;
        i2c_data.send_len = 1;
        i2c_data.receive_buf = dest;
        i2c_data.receive_len = len;
        return hi_i2c_writeread(0, (addr<<1), &i2c_data);
    }
    else
    {
        return ble_i2c_read(self->i2c_id,(addr<<1),0x00,dest,len);
    }
}

2、写函数

STATIC int mp_machine_i2c_writeto(mp_obj_base_t *self_in, uint16_t addr, const uint8_t *src, size_t len, bool stop) {
    uint8_t buf[1] = {0};
    hi_i2c_data i2c_data = { 0 };
    machine_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
    if(self->ble_ex == 0)
    {
        if (len == 0){
            len = 1;
            if (src == NULL){
                src = buf;
            }
            i2c_data.send_buf = src;
            i2c_data.send_len = len;
            return hi_i2c_write(0,addr<<1,&i2c_data);
        } else if (src == NULL){
            nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "buf must not NULL"));
        }
        i2c_data.send_buf = src;
        i2c_data.send_len = len;
        return hi_i2c_write(0,addr<<1,&i2c_data);
    }
    else
    {
        if (len == 0){
            len = 1;
            if (src == NULL){
                src = buf;
            }
            i2c_data.send_buf = src;
            i2c_data.send_len = len;
            return ble_i2c_write(self->i2c_id,addr<<1,0x00,src,len);
        } else if (src == NULL){
            nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "buf must not NULL"));
        }
        i2c_data.send_buf = src;
        i2c_data.send_len = len;
        return ble_i2c_write(self->i2c_id,addr<<1,0x00,src,len);
    }
}

4、实例

from machine import Pin, I2C

i2c = I2C(0,100000)      
i2c.scan()                          
i2c.writeto(0x50, "abcd")                 
i2c.writeto_mem(0x50,0x00, "HQX") 

i2c.writeto_mem(0x50,0x01, "haoqixing8888") 

i2c.readfrom(0x50,4)                    
i2c.readfrom_mem(0x50, 0x02, 4)# read 1 bytes from memory of slave 0x51(7-bit)
i2c.writeto_mem(0x51, 2, b'\x10')# write 1 byte to memory of slave 42

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
2
收藏 1
回复
举报
回复
    相关推荐