8000 stmhal: Refactor to use extmod implementation of software SPI class. · Felipeasg/micropython@1b6d94b · GitHub
[go: up one dir, main page]

Skip to content

Commit 1b6d94b

Browse files
committed
stmhal: Refactor to use extmod implementation of software SPI class.
This is a pure refactoring (and simplification) of code so that stmhal uses the software SPI class provided in extmod, for the machine.SPI implementation.
1 parent 1eb3c66 commit 1b6d94b

File tree

2 files changed

+50
-228
lines changed

2 files changed

+50
-228
lines changed

stmhal/mpconfigport.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@
105105
#define MICROPY_PY_MACHINE_I2C (1)
106106
#define MICROPY_PY_MACHINE_I2C_MAKE_NEW machine_hard_i2c_make_new
107107
#define MICROPY_PY_MACHINE_SPI (1)
108+
#define MICROPY_PY_MACHINE_SPI_MSB (SPI_FIRSTBIT_MSB)
109+
#define MICROPY_PY_MACHINE_SPI_LSB (SPI_FIRSTBIT_LSB)
110+
#define MICROPY_PY_MACHINE_SPI_MAKE_NEW machine_hard_spi_make_new
108111
#define MICROPY_PY_MACHINE_SPI_MIN_DELAY (0)
109112
#define MICROPY_PY_MACHINE_SPI_MAX_BAUDRATE (HAL_RCC_GetSysClockFreq() / 48)
110113
#define MICROPY_PY_FRAMEBUF (1)

stmhal/spi.c

Lines changed: 47 additions & 228 deletions
Original file line numberDiff line numberDiff line change
@@ -829,216 +829,7 @@ const mp_obj_type_t pyb_spi_type = {
829829
};
830830

831831
/******************************************************************************/
832-
/* MicroPython bindings for machine API */
833-
834-
// for make_new
835-
enum {
836-
ARG_NEW_id,
837-
ARG_NEW_baudrate,
838-
ARG_NEW_polarity,
839-
ARG_NEW_phase,
840-
ARG_NEW_bits,
841-
ARG_NEW_firstbit,
842-
ARG_NEW_sck,
843-
ARG_NEW_mosi,
844-
ARG_NEW_miso
845-
};
846-
847-
// for init
848-
enum {
849-
ARG_INIT_baudrate,
850-
ARG_INIT_polarity,
851-
ARG_INIT_phase,
852-
ARG_INIT_bits,
853-
ARG_INIT_firstbit
854-
};
855-
856-
STATIC mp_obj_t machine_soft_spi_make_new(mp_arg_val_t *args);
857-
STATIC void machine_soft_spi_init(mp_obj_t self, mp_arg_val_t *args);
858-
STATIC void machine_soft_spi_deinit(mp_obj_t self);
859-
860-
STATIC mp_obj_t machine_hard_spi_make_new(mp_arg_val_t *args);
861-
STATIC void machine_hard_spi_init(mp_obj_t self, mp_arg_val_t *args);
862-
STATIC void machine_hard_spi_deinit(mp_obj_t self);
863-
864-
/* common code for both soft and hard implementations *************************/
865-
866-
STATIC mp_obj_t machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
867-
static const mp_arg_t allowed_args[] = {
868-
{ MP_QSTR_id, MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(-1)} },
869-
{ MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 500000} },
870-
{ MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
871-
{ MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
872-
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
873-
{ MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SPI_FIRSTBIT_MSB} },
874-
{ MP_QSTR_sck, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
875-
{ MP_QSTR_mosi, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
876-
{ MP_QSTR_miso, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
877-
};
878-
879-
// parse args
880-
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
881-
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
882-
883-
if (args[ARG_NEW_id].u_obj == MP_OBJ_NEW_SMALL_INT(-1)) {
884-
// software SPI
885-
return machine_soft_spi_make_new(args);
886-
} else {
887-
// hardware peripheral id given
888-
return machine_hard_spi_make_new(args);
889-
}
890-
}
891-
892-
STATIC mp_obj_t machine_spi_init(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
893-
static const mp_arg_t allowed_args[] = {
894-
{ MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
895-
{ MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
896-
{ MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
897-
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
898-
{ MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
899-
};
900-
901-
// parse args
902-
mp_obj_t self = pos_args[0];
903-
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
904-
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
905-
906-
// dispatch to specific implementation
907-
if (mp_obj_get_type(self) == &machine_soft_spi_type) {
908-
machine_soft_spi_init(self, args);
909-
} else {
910-
machine_hard_spi_init(self, args);
911-
}
912-
913-
return mp_const_none;
914-
}
915-
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_spi_init_obj, 1, machine_spi_init);
916-
917-
STATIC mp_obj_t machine_spi_deinit(mp_obj_t self) {
918-
// dispatch to specific implementation
919-
if (mp_obj_get_type(self) == &machine_soft_spi_type) {
920-
machine_soft_spi_deinit(self);
921-
} else {
922-
machine_hard_spi_deinit(self);
923-
}
924-
return mp_const_none;
925-
}
926-
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_spi_deinit_obj, machine_spi_deinit);
927-
928-
STATIC const mp_rom_map_elem_t machine_spi_locals_dict_table[] = {
929-
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_spi_init_obj) },
930-
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_spi_deinit_obj) },
931-
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_machine_spi_read_obj) },
932-
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_machine_spi_readinto_obj) },
933-
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_machine_spi_write_obj) },
934-
{ MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&mp_machine_spi_write_readinto_obj) },
935-
936-
{ MP_ROM_QSTR(MP_QSTR_MSB), MP_ROM_INT(SPI_FIRSTBIT_MSB) },
937-
{ MP_ROM_QSTR(MP_QSTR_LSB), MP_ROM_INT(SPI_FIRSTBIT_LSB) },
938-
};
939-
940-
STATIC MP_DEFINE_CONST_DICT(machine_spi_locals_dict, machine_spi_locals_dict_table);
941-
942-
/* code for soft implementation ***********************************************/
943-
944-
// for the software SPI implementation, this is roughly the max baudrate
945-
#define MAX_BAUDRATE (HAL_RCC_GetSysClockFreq() / 48)
946-
947-
STATIC uint32_t baudrate_from_delay_half(uint32_t delay_half) {
948-
if (delay_half == MICROPY_PY_MACHINE_SPI_MIN_DELAY) {
949-
return MAX_BAUDRATE;
950-
} else {
951-
return 500000 / delay_half;
952-
}
953-
}
954-
955-
STATIC uint32_t baudrate_to_delay_half(uint32_t baudrate) {
956-
if (baudrate >= MAX_BAUDRATE) {
957-
return MICROPY_PY_MACHINE_SPI_MIN_DELAY;
958-
} else {
959-
uint32_t delay_half = 500000 / baudrate;
960-
// round delay_half up so that: actual_baudrate <= requested_baudrate
961-
if (500000 % baudrate != 0) {
962-
delay_half += 1;
963-
}
964-
return delay_half;
965-
}
966-
}
967-
968-
STATIC void machine_soft_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
969-
mp_machine_soft_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
970-
mp_printf(print, "SPI(-1, baudrate=%u, polarity=%u, phase=%u, sck=%q, mosi=%q, miso=%q)",
971-
baudrate_from_delay_half(self->delay_half), self->polarity, self->phase,
972-
self->sck->name, self->mosi->name, self->miso->name);
973-
}
974-
975-
STATIC mp_obj_t machine_soft_spi_make_new(mp_arg_val_t *args) {
976-
// create new object
977-
mp_machine_soft_spi_obj_t *self = m_new_obj(mp_machine_soft_spi_obj_t);
978-
self->base.type = &machine_soft_spi_type;
979-
980-
// set parameters
981-
self->delay_half = baudrate_to_delay_half(args[ARG_NEW_baudrate].u_int);
982-
self->polarity = args[ARG_NEW_polarity].u_int;
983-
self->phase = args[ARG_NEW_phase].u_int;
984-
if (args[ARG_NEW_bits].u_int != 8) {
985-
mp_raise_ValueError("bits must be 8");
986-
}
987-
if (args[ARG_NEW_firstbit].u_int != SPI_FIRSTBIT_MSB) {
988-
mp_raise_ValueError("firstbit must be MSB");
989-
}
990-
if (args[ARG_NEW_sck].u_obj == MP_OBJ_NULL
991-
|| args[ARG_NEW_mosi].u_obj == MP_OBJ_NULL
992-
|| args[ARG_NEW_miso].u_obj == MP_OBJ_NULL) {
993-
mp_raise_ValueError("must specify all of sck/mosi/miso");
994-
}
995-
self->sck = mp_hal_get_pin_obj(args[ARG_NEW_sck].u_obj);
996-
self->mosi = mp_hal_get_pin_obj(args[ARG_NEW_mosi].u_obj);
997-
self->miso = mp_hal_get_pin_obj(args[ARG_NEW_miso].u_obj);
998-
999-
// configure pins
1000-
mp_hal_pin_write(self->sck, self->polarity);
1001-
mp_hal_pin_output(self->sck);
1002-
mp_hal_pin_output(self->mosi);
1003-
mp_hal_pin_input(self->miso);
1004-
1005-
return MP_OBJ_FROM_PTR(self);
1006-
}
1007-
1008-
STATIC void machine_soft_spi_init(mp_obj_t self_in, mp_arg_val_t *args) {
1009-
mp_machine_soft_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
1010-
1011-
// update parameters
1012-
if (args[ARG_INIT_baudrate].u_int != -1) {
1013-
self->delay_half = baudrate_to_delay_half(args[ARG_INIT_baudrate].u_int);
1014-
}
1015-
if (args[ARG_INIT_polarity].u_int != -1) {
1016-
self->polarity = args[ARG_INIT_polarity].u_int;
1017-
}
1018-
if (args[ARG_INIT_phase].u_int != -1) {
1019-
self->phase = args[ARG_INIT_phase].u_int;
1020-
}
1021-
}
1022-
1023-
STATIC void machine_soft_spi_deinit(mp_obj_t self) {
1024-
// nothing to do
1025-
(void)self;
1026-
}
1027-
1028-
STATIC const mp_machine_spi_p_t machine_soft_spi_p = {
1029-
.transfer = mp_machine_soft_spi_transfer,
1030-
};
1031-
1032-
const mp_obj_type_t machine_soft_spi_type = {
1033-
{ &mp_type_type },
1034-
.name = MP_QSTR_SoftSPI,
1035-
.print = machine_soft_spi_print,
1036-
.make_new = machine_spi_make_new,
1037-
.protocol = &machine_soft_spi_p,
1038-
.locals_dict = (mp_obj_t)&machine_spi_locals_dict,
1039-
};
1040-
1041-
/* code for hard implementation ***********************************************/
832+
// Implementation of hard SPI for machine module
1042833

1043834
typedef struct _machine_hard_spi_obj_t {
1044835
mp_obj_base_t base;
@@ -1055,19 +846,34 @@ STATIC const machine_hard_spi_obj_t machine_hard_spi_obj[] = {
1055846
};
1056847

1057848
STATIC void machine_hard_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
1058-
machine_hard_spi_obj_t *self = self_in;
849+
machine_hard_spi_obj_t *self = (machine_hard_spi_obj_t*)self_in;
1059850
spi_print(print, self->pyb->spi, false);
1060851
}
1061852

1062-
STATIC mp_obj_t machine_hard_spi_make_new(mp_arg_val_t *args) {
853+
mp_obj_t machine_hard_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
854+
enum { ARG_id, ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit, ARG_sck, ARG_mosi, ARG_miso };
855+
static const mp_arg_t allowed_args[] = {
856+
{ MP_QSTR_id, MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(-1)} },
857+
{ MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 500000} },
858+
{ MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
859+
{ MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
860+
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
861+
{ MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SPI_FIRSTBIT_MSB} },
862+
{ MP_QSTR_sck, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
863+
{ MP_QSTR_mosi, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
864+
{ MP_QSTR_miso, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
865+
};
866+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
867+
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
868+
1063869
// get static peripheral object
1064-
int spi_id = spi_find(args[ARG_NEW_id].u_obj);
870+
int spi_id = spi_find(args[ARG_id].u_obj);
1065871
const machine_hard_spi_obj_t *self = &machine_hard_spi_obj[spi_id - 1];
1066872

1067873
// here we would check the sck/mosi/miso pins and configure them, but it's not implemented
1068-
if (args[ARG_NEW_sck].u_obj != MP_OBJ_NULL
1069-
|| args[ARG_NEW_mosi].u_obj != MP_OBJ_NULL
1070-
|| args[ARG_NEW_miso].u_obj != MP_OBJ_NULL) {
874+
if (args[ARG_sck].u_obj != MP_OBJ_NULL
875+
|| args[ARG_mosi].u_obj != MP_OBJ_NULL
876+
|| args[ARG_miso].u_obj != MP_OBJ_NULL) {
1071877
mp_raise_ValueError("explicit choice of sck/mosi/miso is not implemented");
1072878
}
1073879

@@ -1083,30 +889,41 @@ STATIC mp_obj_t machine_hard_spi_make_new(mp_arg_val_t *args) {
1083889
init->CRCPolynomial = 0;
1084890

1085891
// set configurable paramaters
1086-
spi_set_params(self->pyb->spi, 0xffffffff, args[ARG_NEW_baudrate].u_int,
1087-
args[ARG_NEW_polarity].u_int, args[ARG_NEW_phase].u_int, args[ARG_NEW_bits].u_int,
1088-
args[ARG_NEW_firstbit].u_int);
892+
spi_set_params(self->pyb->spi, 0xffffffff, args[ARG_baudrate].u_int,
893+
args[ARG_polarity].u_int, args[ARG_phase].u_int, args[ARG_bits].u_int,
894+
args[ARG_firstbit].u_int);
1089895

1090896
// init the SPI bus
1091897
spi_init(self->pyb->spi, false);
1092898

1093899
return MP_OBJ_FROM_PTR(self);
1094900
}
1095901

1096-
STATIC void machine_hard_spi_init(mp_obj_t self_in, mp_arg_val_t *args) {
1097-
machine_hard_spi_obj_t *self = self_in;
902+
STATIC void machine_hard_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
903+
machine_hard_spi_obj_t *self = (machine_hard_spi_obj_t*)self_in;
904+
905+
enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit };
906+
static const mp_arg_t allowed_args[] = {
907+
{ MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
908+
{ MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
909+
{ MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
910+
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
911+
{ MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
912+
};
913+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
914+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
1098915

1099916
// set the SPI configuration values
1100-
spi_set_params(self->pyb->spi, 0xffffffff, args[ARG_INIT_baudrate].u_int,
1101-
args[ARG_INIT_polarity].u_int, args[ARG_INIT_phase].u_int, args[ARG_INIT_bits].u_int,
1102-
args[ARG_INIT_firstbit].u_int);
917+
spi_set_params(self->pyb->spi, 0xffffffff, args[ARG_baudrate].u_int,
918+
args[ARG_polarity].u_int, args[ARG_phase].u_int, args[ARG_bits].u_int,
919+
args[ARG_firstbit].u_int);
1103920

1104921
// re-init the SPI bus
1105922
spi_init(self->pyb->spi, false);
1106923
}
1107924

1108-
STATIC void machine_hard_spi_deinit(mp_obj_t self_in) {
1109-
machine_hard_spi_obj_t *self = self_in;
925+
STATIC void machine_hard_spi_deinit(mp_obj_base_t *self_in) {
926+
machine_hard_spi_obj_t *self = (machine_hard_spi_obj_t*)self_in;
1110927
spi_deinit(self->pyb->spi);
1111928
}
1112929

@@ -1116,14 +933,16 @@ STATIC void machine_hard_spi_transfer(mp_obj_base_t *self_in, size_t len, const
1116933
}
1117934

1118935
STATIC const mp_machine_spi_p_t machine_hard_spi_p = {
936+
.init = machine_hard_spi_init,
937+
.deinit = machine_hard_spi_deinit,
1119938
.transfer = machine_hard_spi_transfer,
1120939
};
1121940

1122941
const mp_obj_type_t machine_hard_spi_type = {
1123942
{ &mp_type_type },
1124943
.name = MP_QSTR_SPI,
1125944
.print = machine_hard_spi_print,
1126-
.make_new = machine_spi_make_new,
945+
.make_new = mp_machine_spi_make_new, // delegate to master constructor
1127946
.protocol = &machine_hard_spi_p,
1128-
.locals_dict = (mp_obj_t)&machine_spi_locals_dict,
947+
.locals_dict = (mp_obj_t)&mp_machine_spi_locals_dict,
1129948
};

0 commit comments

Comments
 (0)
0