change half_duplex to be on spi construct

This commit is contained in:
Scott Gauche 2022-02-08 21:37:38 -05:00
parent 4110b44b8a
commit 3b418dbddc
7 changed files with 24 additions and 16 deletions

View File

@ -171,7 +171,7 @@ STATIC int check_pins(busio_spi_obj_t *self,
void common_hal_busio_spi_construct(busio_spi_obj_t *self, void common_hal_busio_spi_construct(busio_spi_obj_t *self,
const mcu_pin_obj_t *sck, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *sck, const mcu_pin_obj_t *mosi,
const mcu_pin_obj_t *miso) { const mcu_pin_obj_t *miso, bool half_duplex) {
int periph_index = check_pins(self, sck, mosi, miso); int periph_index = check_pins(self, sck, mosi, miso);
SPI_TypeDef *SPIx = mcu_spi_banks[periph_index - 1]; SPI_TypeDef *SPIx = mcu_spi_banks[periph_index - 1];
@ -208,12 +208,11 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
self->handle.Instance = SPIx; self->handle.Instance = SPIx;
self->handle.Init.Mode = SPI_MODE_MASTER; self->handle.Init.Mode = SPI_MODE_MASTER;
if (self->mosi == NULL && self->miso != NULL) { // Direction change only required for RX-only, see RefMan RM0090:884
self->handle.Init.Direction = SPI_DIRECTION_2LINES_RXONLY; if (half_duplex == true) {
} else if (self->mosi != NULL && self->miso == NULL) {
self->handle.Init.Direction = SPI_DIRECTION_1LINE; self->handle.Init.Direction = SPI_DIRECTION_1LINE;
} else if (self->mosi != NULL && self->miso != NULL) { } else {
self->handle.Init.Direction = SPI_DIRECTION_2LINES; self->handle.Init.Direction = (self->mosi == NULL) ? SPI_DIRECTION_2LINES_RXONLY : SPI_DIRECTION_2LINES;
} }
self->handle.Init.DataSize = SPI_DATASIZE_8BIT; self->handle.Init.DataSize = SPI_DATASIZE_8BIT;
self->handle.Init.CLKPolarity = SPI_POLARITY_LOW; self->handle.Init.CLKPolarity = SPI_POLARITY_LOW;
@ -229,6 +228,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
} }
self->baudrate = (get_busclock(SPIx) / 16); self->baudrate = (get_busclock(SPIx) / 16);
self->prescaler = 16; self->prescaler = 16;
self->half_duplex = half_duplex;
self->polarity = 0; self->polarity = 0;
self->phase = 0; self->phase = 0;
self->bits = 8; self->bits = 8;
@ -345,11 +345,15 @@ bool common_hal_busio_spi_write(busio_spi_obj_t *self,
bool common_hal_busio_spi_read(busio_spi_obj_t *self, bool common_hal_busio_spi_read(busio_spi_obj_t *self,
uint8_t *data, size_t len, uint8_t write_value) { uint8_t *data, size_t len, uint8_t write_value) {
if (self->miso == NULL && self->half_duplex == false) {
mp_raise_ValueError(translate("No MISO Pin"));
} else if (self->half_duplex == true && self->mosi == NULL) {
mp_raise_ValueError(translate("No MOSI Pin"));
}
HAL_StatusTypeDef result = HAL_OK; HAL_StatusTypeDef result = HAL_OK;
// If in modes SPI_DIRECTION_2LINES_RXONLY or SPI_DIRECTION_1LINE if ((self->half_duplex == false && self->mosi == NULL) || (self->half_duplex == true && self->mosi != NULL && self->miso == NULL)) {
if ((self->mosi == NULL && self->miso != NULL) || (self->mosi != NULL && self->miso == NULL)) {
result = HAL_SPI_Receive(&self->handle, data, (uint16_t)len, HAL_MAX_DELAY); result = HAL_SPI_Receive(&self->handle, data, (uint16_t)len, HAL_MAX_DELAY);
} else { // Else SPI_DIRECTION_2LINES } else {
memset(data, write_value, len); memset(data, write_value, len);
result = HAL_SPI_TransmitReceive(&self->handle, data, data, (uint16_t)len, HAL_MAX_DELAY); result = HAL_SPI_TransmitReceive(&self->handle, data, data, (uint16_t)len, HAL_MAX_DELAY);
} }

View File

@ -44,6 +44,7 @@ typedef struct {
const mcu_periph_obj_t *nss; const mcu_periph_obj_t *nss;
uint32_t baudrate; uint32_t baudrate;
uint16_t prescaler; uint16_t prescaler;
bool half_duplex;
uint8_t polarity; uint8_t polarity;
uint8_t phase; uint8_t phase;
uint8_t bits; uint8_t bits;

View File

@ -74,7 +74,8 @@
//| //|
//| :param ~microcontroller.Pin clock: the pin to use for the clock. //| :param ~microcontroller.Pin clock: the pin to use for the clock.
//| :param ~microcontroller.Pin MOSI: the Main Out Selected In pin. //| :param ~microcontroller.Pin MOSI: the Main Out Selected In pin.
//| :param ~microcontroller.Pin MISO: the Main In Selected Out pin.""" //| :param ~microcontroller.Pin MISO: the Main In Selected Out pin.
//| :param bool half_duplex: True when MOSI is used for bidirectional data. False when SPI is full-duplex or simplex."""
//| ... //| ...
//| //|
@ -84,11 +85,12 @@ STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, siz
#if CIRCUITPY_BUSIO_SPI #if CIRCUITPY_BUSIO_SPI
busio_spi_obj_t *self = m_new_obj(busio_spi_obj_t); busio_spi_obj_t *self = m_new_obj(busio_spi_obj_t);
self->base.type = &busio_spi_type; self->base.type = &busio_spi_type;
enum { ARG_clock, ARG_MOSI, ARG_MISO }; enum { ARG_clock, ARG_MOSI, ARG_MISO, ARG_half_duplex };
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {
{ MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_MOSI, MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_MOSI, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_MISO, MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_MISO, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_half_duplex, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_bool = false} },
}; };
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_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); mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@ -101,7 +103,7 @@ STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, siz
mp_raise_ValueError(translate("Must provide MISO or MOSI pin")); mp_raise_ValueError(translate("Must provide MISO or MOSI pin"));
} }
common_hal_busio_spi_construct(self, clock, mosi, miso); common_hal_busio_spi_construct(self, clock, mosi, miso, args[ARG_half_duplex].u_bool);
return MP_OBJ_FROM_PTR(self); return MP_OBJ_FROM_PTR(self);
#else #else
mp_raise_ValueError(translate("Invalid pins")); mp_raise_ValueError(translate("Invalid pins"));

View File

@ -38,7 +38,7 @@ extern const mp_obj_type_t busio_spi_type;
// Construct an underlying SPI object. // Construct an underlying SPI object.
extern void common_hal_busio_spi_construct(busio_spi_obj_t *self, extern void common_hal_busio_spi_construct(busio_spi_obj_t *self,
const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi,
const mcu_pin_obj_t *miso); const mcu_pin_obj_t *miso, bool half_duplex);
extern void common_hal_busio_spi_deinit(busio_spi_obj_t *self); extern void common_hal_busio_spi_deinit(busio_spi_obj_t *self);
extern bool common_hal_busio_spi_deinited(busio_spi_obj_t *self); extern bool common_hal_busio_spi_deinited(busio_spi_obj_t *self);

View File

@ -131,7 +131,7 @@ mp_obj_t common_hal_board_create_spi(const mp_int_t instance) {
assert_pin_free(spi_pin[instance].mosi); assert_pin_free(spi_pin[instance].mosi);
assert_pin_free(spi_pin[instance].miso); assert_pin_free(spi_pin[instance].miso);
common_hal_busio_spi_construct(self, spi_pin[instance].clock, spi_pin[instance].mosi, spi_pin[instance].miso); common_hal_busio_spi_construct(self, spi_pin[instance].clock, spi_pin[instance].mosi, spi_pin[instance].miso, false);
spi_obj_created[instance] = true; spi_obj_created[instance] = true;
return &spi_obj[instance]; return &spi_obj[instance];

View File

@ -149,7 +149,7 @@ void spi_flash_init(void) {
common_hal_digitalio_digitalinout_never_reset(&cs_pin); common_hal_digitalio_digitalinout_never_reset(&cs_pin);
supervisor_flash_spi_bus.base.type = &busio_spi_type; supervisor_flash_spi_bus.base.type = &busio_spi_type;
common_hal_busio_spi_construct(&supervisor_flash_spi_bus, SPI_FLASH_SCK_PIN, SPI_FLASH_MOSI_PIN, SPI_FLASH_MISO_PIN); common_hal_busio_spi_construct(&supervisor_flash_spi_bus, SPI_FLASH_SCK_PIN, SPI_FLASH_MOSI_PIN, SPI_FLASH_MISO_PIN, false);
common_hal_busio_spi_never_reset(&supervisor_flash_spi_bus); common_hal_busio_spi_never_reset(&supervisor_flash_spi_bus);
return; return;

View File

@ -163,7 +163,8 @@ void status_led_init() {
common_hal_busio_spi_construct(&status_apa102, common_hal_busio_spi_construct(&status_apa102,
MICROPY_HW_APA102_SCK, MICROPY_HW_APA102_SCK,
MICROPY_HW_APA102_MOSI, MICROPY_HW_APA102_MOSI,
NULL); NULL,
false);
#endif #endif
#if CIRCUITPY_BITBANG_APA102 #if CIRCUITPY_BITBANG_APA102
shared_module_bitbangio_spi_try_lock(&status_apa102); shared_module_bitbangio_spi_try_lock(&status_apa102);