Skip to content

Commit 6e1dfb0

Browse files
committed
stmhal: Reorganise code for parsing keyword args in I2C methods.
To make it the same as SPI and UART.
1 parent de8b585 commit 6e1dfb0

1 file changed

Lines changed: 66 additions & 74 deletions

File tree

stmhal/i2c.c

Lines changed: 66 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -286,34 +286,33 @@ STATIC void pyb_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ki
286286
/// - `addr` is the 7-bit address (only sensible for a slave)
287287
/// - `baudrate` is the SCL clock rate (only sensible for a master)
288288
/// - `gencall` is whether to support general call mode
289-
STATIC const mp_arg_t pyb_i2c_init_args[] = {
290-
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
291-
{ MP_QSTR_addr, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0x12} },
292-
{ MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} },
293-
{ MP_QSTR_gencall, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
294-
};
295-
#define PYB_I2C_INIT_NUM_ARGS MP_ARRAY_SIZE(pyb_i2c_init_args)
289+
STATIC mp_obj_t pyb_i2c_init_helper(const pyb_i2c_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
290+
static const mp_arg_t allowed_args[] = {
291+
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
292+
{ MP_QSTR_addr, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0x12} },
293+
{ MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} },
294+
{ MP_QSTR_gencall, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
295+
};
296296

297-
STATIC mp_obj_t pyb_i2c_init_helper(const pyb_i2c_obj_t *self, mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
298297
// parse args
299-
mp_arg_val_t vals[PYB_I2C_INIT_NUM_ARGS];
300-
mp_arg_parse_all(n_args, args, kw_args, PYB_I2C_INIT_NUM_ARGS, pyb_i2c_init_args, vals);
298+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
299+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
301300

302301
// set the I2C configuration values
303302
I2C_InitTypeDef *init = &self->i2c->Init;
304303

305-
if (vals[0].u_int == PYB_I2C_MASTER) {
304+
if (args[0].u_int == PYB_I2C_MASTER) {
306305
// use a special address to indicate we are a master
307306
init->OwnAddress1 = PYB_I2C_MASTER_ADDRESS;
308307
} else {
309-
init->OwnAddress1 = (vals[1].u_int << 1) & 0xfe;
308+
init->OwnAddress1 = (args[1].u_int << 1) & 0xfe;
310309
}
311310

312311
init->AddressingMode = I2C_ADDRESSINGMODE_7BIT;
313-
init->ClockSpeed = MIN(vals[2].u_int, 400000);
312+
init->ClockSpeed = MIN(args[2].u_int, 400000);
314313
init->DualAddressMode = I2C_DUALADDRESS_DISABLED;
315314
init->DutyCycle = I2C_DUTYCYCLE_16_9;
316-
init->GeneralCallMode = vals[3].u_bool ? I2C_GENERALCALL_ENABLED : I2C_GENERALCALL_DISABLED;
315+
init->GeneralCallMode = args[3].u_bool ? I2C_GENERALCALL_ENABLED : I2C_GENERALCALL_DISABLED;
317316
init->NoStretchMode = I2C_NOSTRETCH_DISABLED;
318317
init->OwnAddress2 = 0xfe; // unused
319318

@@ -452,24 +451,22 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_i2c_scan_obj, pyb_i2c_scan);
452451
/// - `timeout` is the timeout in milliseconds to wait for the send
453452
///
454453
/// Return value: `None`.
455-
STATIC const mp_arg_t pyb_i2c_send_args[] = {
456-
{ MP_QSTR_send, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
457-
{ MP_QSTR_addr, MP_ARG_INT, {.u_int = PYB_I2C_MASTER_ADDRESS} },
458-
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
459-
};
460-
#define PYB_I2C_SEND_NUM_ARGS MP_ARRAY_SIZE(pyb_i2c_send_args)
461-
462-
STATIC mp_obj_t pyb_i2c_send(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
463-
pyb_i2c_obj_t *self = args[0];
454+
STATIC mp_obj_t pyb_i2c_send(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
455+
static const mp_arg_t allowed_args[] = {
456+
{ MP_QSTR_send, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
457+
{ MP_QSTR_addr, MP_ARG_INT, {.u_int = PYB_I2C_MASTER_ADDRESS} },
458+
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
459+
};
464460

465461
// parse args
466-
mp_arg_val_t vals[PYB_I2C_SEND_NUM_ARGS];
467-
mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_I2C_SEND_NUM_ARGS, pyb_i2c_send_args, vals);
462+
pyb_i2c_obj_t *self = pos_args[0];
463+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
464+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
468465

469466
// get the buffer to send from
470467
mp_buffer_info_t bufinfo;
471468
uint8_t data[1];
472-
pyb_buf_get_for_send(vals[0].u_obj, &bufinfo, data);
469+
pyb_buf_get_for_send(args[0].u_obj, &bufinfo, data);
473470

474471
// if IRQs are enabled then we can use DMA
475472
DMA_HandleTypeDef tx_dma;
@@ -482,21 +479,21 @@ STATIC mp_obj_t pyb_i2c_send(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *k
482479
// send the data
483480
HAL_StatusTypeDef status;
484481
if (in_master_mode(self)) {
485-
if (vals[1].u_int == PYB_I2C_MASTER_ADDRESS) {
482+
if (args[1].u_int == PYB_I2C_MASTER_ADDRESS) {
486483
if (query_irq() == IRQ_STATE_ENABLED) {
487484
dma_deinit(&tx_dma);
488485
}
489486
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "addr argument required"));
490487
}
491-
mp_uint_t i2c_addr = vals[1].u_int << 1;
488+
mp_uint_t i2c_addr = args[1].u_int << 1;
492489
if (query_irq() == IRQ_STATE_DISABLED) {
493-
status = HAL_I2C_Master_Transmit(self->i2c, i2c_addr, bufinfo.buf, bufinfo.len, vals[2].u_int);
490+
status = HAL_I2C_Master_Transmit(self->i2c, i2c_addr, bufinfo.buf, bufinfo.len, args[2].u_int);
494491
} else {
495492
status = HAL_I2C_Master_Transmit_DMA(self->i2c, i2c_addr, bufinfo.buf, bufinfo.len);
496493
}
497494
} else {
498495
if (query_irq() == IRQ_STATE_DISABLED) {
499-
status = HAL_I2C_Slave_Transmit(self->i2c, bufinfo.buf, bufinfo.len, vals[2].u_int);
496+
status = HAL_I2C_Slave_Transmit(self->i2c, bufinfo.buf, bufinfo.len, args[2].u_int);
500497
} else {
501498
status = HAL_I2C_Slave_Transmit_DMA(self->i2c, bufinfo.buf, bufinfo.len);
502499
}
@@ -505,7 +502,7 @@ STATIC mp_obj_t pyb_i2c_send(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *k
505502
// if we used DMA, wait for it to finish
506503
if (query_irq() == IRQ_STATE_ENABLED) {
507504
if (status == HAL_OK) {
508-
status = i2c_wait_dma_finished(self->i2c, vals[2].u_int);
505+
status = i2c_wait_dma_finished(self->i2c, args[2].u_int);
509506
}
510507
dma_deinit(&tx_dma);
511508
}
@@ -529,23 +526,21 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_send_obj, 1, pyb_i2c_send);
529526
///
530527
/// Return value: if `recv` is an integer then a new buffer of the bytes received,
531528
/// otherwise the same buffer that was passed in to `recv`.
532-
STATIC const mp_arg_t pyb_i2c_recv_args[] = {
533-
{ MP_QSTR_recv, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
534-
{ MP_QSTR_addr, MP_ARG_INT, {.u_int = PYB_I2C_MASTER_ADDRESS} },
535-
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
536-
};
537-
#define PYB_I2C_RECV_NUM_ARGS MP_ARRAY_SIZE(pyb_i2c_recv_args)
538-
539-
STATIC mp_obj_t pyb_i2c_recv(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
540-
pyb_i2c_obj_t *self = args[0];
529+
STATIC mp_obj_t pyb_i2c_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
530+
static const mp_arg_t allowed_args[] = {
531+
{ MP_QSTR_recv, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
532+
{ MP_QSTR_addr, MP_ARG_INT, {.u_int = PYB_I2C_MASTER_ADDRESS} },
533+
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
534+
};
541535

542536
// parse args
543-
mp_arg_val_t vals[PYB_I2C_RECV_NUM_ARGS];
544-
mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_I2C_RECV_NUM_ARGS, pyb_i2c_recv_args, vals);
537+
pyb_i2c_obj_t *self = pos_args[0];
538+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
539+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
545540

546541
// get the buffer to receive into
547542
vstr_t vstr;
548-
mp_obj_t o_ret = pyb_buf_get_for_recv(vals[0].u_obj, &vstr);
543+
mp_obj_t o_ret = pyb_buf_get_for_recv(args[0].u_obj, &vstr);
549544

550545
// if IRQs are enabled then we can use DMA
551546
DMA_HandleTypeDef rx_dma;
@@ -558,18 +553,18 @@ STATIC mp_obj_t pyb_i2c_recv(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *k
558553
// receive the data
559554
HAL_StatusTypeDef status;
560555
if (in_master_mode(self)) {
561-
if (vals[1].u_int == PYB_I2C_MASTER_ADDRESS) {
556+
if (args[1].u_int == PYB_I2C_MASTER_ADDRESS) {
562557
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "addr argument required"));
563558
}
564-
mp_uint_t i2c_addr = vals[1].u_int << 1;
559+
mp_uint_t i2c_addr = args[1].u_int << 1;
565560
if (query_irq() == IRQ_STATE_DISABLED) {
566-
status = HAL_I2C_Master_Receive(self->i2c, i2c_addr, (uint8_t*)vstr.buf, vstr.len, vals[2].u_int);
561+
status = HAL_I2C_Master_Receive(self->i2c, i2c_addr, (uint8_t*)vstr.buf, vstr.len, args[2].u_int);
567562
} else {
568563
status = HAL_I2C_Master_Receive_DMA(self->i2c, i2c_addr, (uint8_t*)vstr.buf, vstr.len);
569564
}
570565
} else {
571566
if (query_irq() == IRQ_STATE_DISABLED) {
572-
status = HAL_I2C_Slave_Receive(self->i2c, (uint8_t*)vstr.buf, vstr.len, vals[2].u_int);
567+
status = HAL_I2C_Slave_Receive(self->i2c, (uint8_t*)vstr.buf, vstr.len, args[2].u_int);
573568
} else {
574569
status = HAL_I2C_Slave_Receive_DMA(self->i2c, (uint8_t*)vstr.buf, vstr.len);
575570
}
@@ -578,7 +573,7 @@ STATIC mp_obj_t pyb_i2c_recv(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *k
578573
// if we used DMA, wait for it to finish
579574
if (query_irq() == IRQ_STATE_ENABLED) {
580575
if (status == HAL_OK) {
581-
status = i2c_wait_dma_finished(self->i2c, vals[2].u_int);
576+
status = i2c_wait_dma_finished(self->i2c, args[2].u_int);
582577
}
583578
dma_deinit(&rx_dma);
584579
}
@@ -608,50 +603,48 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_recv_obj, 1, pyb_i2c_recv);
608603
///
609604
/// Returns the read data.
610605
/// This is only valid in master mode.
611-
STATIC const mp_arg_t pyb_i2c_mem_read_args[] = {
606+
STATIC const mp_arg_t pyb_i2c_mem_read_allowed_args[] = {
612607
{ MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
613608
{ MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
614609
{ MP_QSTR_memaddr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
615610
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
616611
{ MP_QSTR_addr_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
617612
};
618-
#define PYB_I2C_MEM_READ_NUM_ARGS MP_ARRAY_SIZE(pyb_i2c_mem_read_args)
619613

620-
STATIC mp_obj_t pyb_i2c_mem_read(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
621-
pyb_i2c_obj_t *self = args[0];
614+
STATIC mp_obj_t pyb_i2c_mem_read(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
615+
// parse args
616+
pyb_i2c_obj_t *self = pos_args[0];
617+
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_i2c_mem_read_allowed_args)];
618+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(pyb_i2c_mem_read_allowed_args), pyb_i2c_mem_read_allowed_args, args);
622619

623620
if (!in_master_mode(self)) {
624621
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "I2C must be a master"));
625622
}
626623

627-
// parse args
628-
mp_arg_val_t vals[PYB_I2C_MEM_READ_NUM_ARGS];
629-
mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_I2C_MEM_READ_NUM_ARGS, pyb_i2c_mem_read_args, vals);
630-
631624
// get the buffer to read into
632625
vstr_t vstr;
633-
mp_obj_t o_ret = pyb_buf_get_for_recv(vals[0].u_obj, &vstr);
626+
mp_obj_t o_ret = pyb_buf_get_for_recv(args[0].u_obj, &vstr);
634627

635628
// get the addresses
636-
mp_uint_t i2c_addr = vals[1].u_int << 1;
637-
mp_uint_t mem_addr = vals[2].u_int;
629+
mp_uint_t i2c_addr = args[1].u_int << 1;
630+
mp_uint_t mem_addr = args[2].u_int;
638631
// determine width of mem_addr; default is 8 bits, entering any other value gives 16 bit width
639632
mp_uint_t mem_addr_size = I2C_MEMADD_SIZE_8BIT;
640-
if (vals[4].u_int != 8) {
633+
if (args[4].u_int != 8) {
641634
mem_addr_size = I2C_MEMADD_SIZE_16BIT;
642635
}
643636

644637
HAL_StatusTypeDef status;
645638
if (query_irq() == IRQ_STATE_DISABLED) {
646-
status = HAL_I2C_Mem_Read(self->i2c, i2c_addr, mem_addr, mem_addr_size, (uint8_t*)vstr.buf, vstr.len, vals[3].u_int);
639+
status = HAL_I2C_Mem_Read(self->i2c, i2c_addr, mem_addr, mem_addr_size, (uint8_t*)vstr.buf, vstr.len, args[3].u_int);
647640
} else {
648641
DMA_HandleTypeDef rx_dma;
649642
dma_init(&rx_dma, self->rx_dma_stream, self->rx_dma_channel, DMA_PERIPH_TO_MEMORY, self->i2c);
650643
self->i2c->hdmatx = NULL;
651644
self->i2c->hdmarx = &rx_dma;
652645
status = HAL_I2C_Mem_Read_DMA(self->i2c, i2c_addr, mem_addr, mem_addr_size, (uint8_t*)vstr.buf, vstr.len);
653646
if (status == HAL_OK) {
654-
status = i2c_wait_dma_finished(self->i2c, vals[3].u_int);
647+
status = i2c_wait_dma_finished(self->i2c, args[3].u_int);
655648
}
656649
dma_deinit(&rx_dma);
657650
}
@@ -681,42 +674,41 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_mem_read_obj, 1, pyb_i2c_mem_read);
681674
///
682675
/// Returns `None`.
683676
/// This is only valid in master mode.
684-
STATIC mp_obj_t pyb_i2c_mem_write(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
685-
pyb_i2c_obj_t *self = args[0];
677+
STATIC mp_obj_t pyb_i2c_mem_write(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
678+
// parse args (same as mem_read)
679+
pyb_i2c_obj_t *self = pos_args[0];
680+
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_i2c_mem_read_allowed_args)];
681+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(pyb_i2c_mem_read_allowed_args), pyb_i2c_mem_read_allowed_args, args);
686682

687683
if (!in_master_mode(self)) {
688684
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "I2C must be a master"));
689685
}
690686

691-
// parse args (same as mem_read)
692-
mp_arg_val_t vals[PYB_I2C_MEM_READ_NUM_ARGS];
693-
mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_I2C_MEM_READ_NUM_ARGS, pyb_i2c_mem_read_args, vals);
694-
695687
// get the buffer to write from
696688
mp_buffer_info_t bufinfo;
697689
uint8_t data[1];
698-
pyb_buf_get_for_send(vals[0].u_obj, &bufinfo, data);
690+
pyb_buf_get_for_send(args[0].u_obj, &bufinfo, data);
699691

700692
// get the addresses
701-
mp_uint_t i2c_addr = vals[1].u_int << 1;
702-
mp_uint_t mem_addr = vals[2].u_int;
693+
mp_uint_t i2c_addr = args[1].u_int << 1;
694+
mp_uint_t mem_addr = args[2].u_int;
703695
// determine width of mem_addr; default is 8 bits, entering any other value gives 16 bit width
704696
mp_uint_t mem_addr_size = I2C_MEMADD_SIZE_8BIT;
705-
if (vals[4].u_int != 8) {
697+
if (args[4].u_int != 8) {
706698
mem_addr_size = I2C_MEMADD_SIZE_16BIT;
707699
}
708700

709701
HAL_StatusTypeDef status;
710702
if (query_irq() == IRQ_STATE_DISABLED) {
711-
status = HAL_I2C_Mem_Write(self->i2c, i2c_addr, mem_addr, mem_addr_size, bufinfo.buf, bufinfo.len, vals[3].u_int);
703+
status = HAL_I2C_Mem_Write(self->i2c, i2c_addr, mem_addr, mem_addr_size, bufinfo.buf, bufinfo.len, args[3].u_int);
712704
} else {
713705
DMA_HandleTypeDef tx_dma;
714706
dma_init(&tx_dma, self->tx_dma_stream, self->tx_dma_channel, DMA_MEMORY_TO_PERIPH, self->i2c);
715707
self->i2c->hdmatx = &tx_dma;
716708
self->i2c->hdmarx = NULL;
717709
status = HAL_I2C_Mem_Write_DMA(self->i2c, i2c_addr, mem_addr, mem_addr_size, bufinfo.buf, bufinfo.len);
718710
if (status == HAL_OK) {
719-
status = i2c_wait_dma_finished(self->i2c, vals[3].u_int);
711+
status = i2c_wait_dma_finished(self->i2c, args[3].u_int);
720712
}
721713
dma_deinit(&tx_dma);
722714
}

0 commit comments

Comments
 (0)