Skip to content

Commit 3b418db

Browse files
committed
change half_duplex to be on spi construct
1 parent 4110b44 commit 3b418db

File tree

7 files changed

+24
-16
lines changed

7 files changed

+24
-16
lines changed

ports/stm/common-hal/busio/SPI.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ STATIC int check_pins(busio_spi_obj_t *self,
171171

172172
void common_hal_busio_spi_construct(busio_spi_obj_t *self,
173173
const mcu_pin_obj_t *sck, const mcu_pin_obj_t *mosi,
174-
const mcu_pin_obj_t *miso) {
174+
const mcu_pin_obj_t *miso, bool half_duplex) {
175175

176176
int periph_index = check_pins(self, sck, mosi, miso);
177177
SPI_TypeDef *SPIx = mcu_spi_banks[periph_index - 1];
@@ -208,12 +208,11 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
208208

209209
self->handle.Instance = SPIx;
210210
self->handle.Init.Mode = SPI_MODE_MASTER;
211-
if (self->mosi == NULL && self->miso != NULL) {
212-
self->handle.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
213-
} else if (self->mosi != NULL && self->miso == NULL) {
211+
// Direction change only required for RX-only, see RefMan RM0090:884
212+
if (half_duplex == true) {
214213
self->handle.Init.Direction = SPI_DIRECTION_1LINE;
215-
} else if (self->mosi != NULL && self->miso != NULL) {
216-
self->handle.Init.Direction = SPI_DIRECTION_2LINES;
214+
} else {
215+
self->handle.Init.Direction = (self->mosi == NULL) ? SPI_DIRECTION_2LINES_RXONLY : SPI_DIRECTION_2LINES;
217216
}
218217
self->handle.Init.DataSize = SPI_DATASIZE_8BIT;
219218
self->handle.Init.CLKPolarity = SPI_POLARITY_LOW;
@@ -229,6 +228,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
229228
}
230229
self->baudrate = (get_busclock(SPIx) / 16);
231230
self->prescaler = 16;
231+
self->half_duplex = half_duplex;
232232
self->polarity = 0;
233233
self->phase = 0;
234234
self->bits = 8;
@@ -345,11 +345,15 @@ bool common_hal_busio_spi_write(busio_spi_obj_t *self,
345345

346346
bool common_hal_busio_spi_read(busio_spi_obj_t *self,
347347
uint8_t *data, size_t len, uint8_t write_value) {
348+
if (self->miso == NULL && self->half_duplex == false) {
349+
mp_raise_ValueError(translate("No MISO Pin"));
350+
} else if (self->half_duplex == true && self->mosi == NULL) {
351+
mp_raise_ValueError(translate("No MOSI Pin"));
352+
}
348353
HAL_StatusTypeDef result = HAL_OK;
349-
// If in modes SPI_DIRECTION_2LINES_RXONLY or SPI_DIRECTION_1LINE
350-
if ((self->mosi == NULL && self->miso != NULL) || (self->mosi != NULL && self->miso == NULL)) {
354+
if ((self->half_duplex == false && self->mosi == NULL) || (self->half_duplex == true && self->mosi != NULL && self->miso == NULL)) {
351355
result = HAL_SPI_Receive(&self->handle, data, (uint16_t)len, HAL_MAX_DELAY);
352-
} else { // Else SPI_DIRECTION_2LINES
356+
} else {
353357
memset(data, write_value, len);
354358
result = HAL_SPI_TransmitReceive(&self->handle, data, data, (uint16_t)len, HAL_MAX_DELAY);
355359
}

ports/stm/common-hal/busio/SPI.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ typedef struct {
4444
const mcu_periph_obj_t *nss;
4545
uint32_t baudrate;
4646
uint16_t prescaler;
47+
bool half_duplex;
4748
uint8_t polarity;
4849
uint8_t phase;
4950
uint8_t bits;

shared-bindings/busio/SPI.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@
7474
//|
7575
//| :param ~microcontroller.Pin clock: the pin to use for the clock.
7676
//| :param ~microcontroller.Pin MOSI: the Main Out Selected In pin.
77-
//| :param ~microcontroller.Pin MISO: the Main In Selected Out pin."""
77+
//| :param ~microcontroller.Pin MISO: the Main In Selected Out pin.
78+
//| :param bool half_duplex: True when MOSI is used for bidirectional data. False when SPI is full-duplex or simplex."""
7879
//| ...
7980
//|
8081

@@ -84,11 +85,12 @@ STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, siz
8485
#if CIRCUITPY_BUSIO_SPI
8586
busio_spi_obj_t *self = m_new_obj(busio_spi_obj_t);
8687
self->base.type = &busio_spi_type;
87-
enum { ARG_clock, ARG_MOSI, ARG_MISO };
88+
enum { ARG_clock, ARG_MOSI, ARG_MISO, ARG_half_duplex };
8889
static const mp_arg_t allowed_args[] = {
8990
{ MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ },
9091
{ MP_QSTR_MOSI, MP_ARG_OBJ, {.u_obj = mp_const_none} },
9192
{ MP_QSTR_MISO, MP_ARG_OBJ, {.u_obj = mp_const_none} },
93+
{ MP_QSTR_half_duplex, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_bool = false} },
9294
};
9395
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
9496
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
101103
mp_raise_ValueError(translate("Must provide MISO or MOSI pin"));
102104
}
103105

104-
common_hal_busio_spi_construct(self, clock, mosi, miso);
106+
common_hal_busio_spi_construct(self, clock, mosi, miso, args[ARG_half_duplex].u_bool);
105107
return MP_OBJ_FROM_PTR(self);
106108
#else
107109
mp_raise_ValueError(translate("Invalid pins"));

shared-bindings/busio/SPI.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ extern const mp_obj_type_t busio_spi_type;
3838
// Construct an underlying SPI object.
3939
extern void common_hal_busio_spi_construct(busio_spi_obj_t *self,
4040
const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi,
41-
const mcu_pin_obj_t *miso);
41+
const mcu_pin_obj_t *miso, bool half_duplex);
4242

4343
extern void common_hal_busio_spi_deinit(busio_spi_obj_t *self);
4444
extern bool common_hal_busio_spi_deinited(busio_spi_obj_t *self);

shared-module/board/__init__.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ mp_obj_t common_hal_board_create_spi(const mp_int_t instance) {
131131
assert_pin_free(spi_pin[instance].mosi);
132132
assert_pin_free(spi_pin[instance].miso);
133133

134-
common_hal_busio_spi_construct(self, spi_pin[instance].clock, spi_pin[instance].mosi, spi_pin[instance].miso);
134+
common_hal_busio_spi_construct(self, spi_pin[instance].clock, spi_pin[instance].mosi, spi_pin[instance].miso, false);
135135

136136
spi_obj_created[instance] = true;
137137
return &spi_obj[instance];

supervisor/shared/external_flash/spi_flash.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ void spi_flash_init(void) {
149149
common_hal_digitalio_digitalinout_never_reset(&cs_pin);
150150

151151
supervisor_flash_spi_bus.base.type = &busio_spi_type;
152-
common_hal_busio_spi_construct(&supervisor_flash_spi_bus, SPI_FLASH_SCK_PIN, SPI_FLASH_MOSI_PIN, SPI_FLASH_MISO_PIN);
152+
common_hal_busio_spi_construct(&supervisor_flash_spi_bus, SPI_FLASH_SCK_PIN, SPI_FLASH_MOSI_PIN, SPI_FLASH_MISO_PIN, false);
153153
common_hal_busio_spi_never_reset(&supervisor_flash_spi_bus);
154154

155155
return;

supervisor/shared/status_leds.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ void status_led_init() {
163163
common_hal_busio_spi_construct(&status_apa102,
164164
MICROPY_HW_APA102_SCK,
165165
MICROPY_HW_APA102_MOSI,
166-
NULL);
166+
NULL,
167+
false);
167168
#endif
168169
#if CIRCUITPY_BITBANG_APA102
169170
shared_module_bitbangio_spi_try_lock(&status_apa102);

0 commit comments

Comments
 (0)