回复
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
回复
相关推荐