stm32/spi: Provide better separation between SPI driver and uPy objs.
There is an underlying hardware SPI driver (built on top of the STM HAL) and then on top of this sits the legacy pyb.SPI class as well as the machine.SPI class. This patch improves the separation between these layers, in particular decoupling machine.SPI from pyb.SPI.
This commit is contained in:
parent
253f2bd7be
commit
4ad3ede21a
@ -34,7 +34,6 @@
|
||||
#include "pin.h"
|
||||
#include "genhdr/pins.h"
|
||||
#include "bufhelper.h"
|
||||
#include "dma.h"
|
||||
#include "spi.h"
|
||||
|
||||
/// \moduleref pyb
|
||||
@ -75,13 +74,6 @@
|
||||
// SPI6_TX: DMA2_Stream5.CHANNEL_1
|
||||
// SPI6_RX: DMA2_Stream6.CHANNEL_1
|
||||
|
||||
typedef struct _pyb_spi_obj_t {
|
||||
mp_obj_base_t base;
|
||||
SPI_HandleTypeDef *spi;
|
||||
const dma_descr_t *tx_dma_descr;
|
||||
const dma_descr_t *rx_dma_descr;
|
||||
} pyb_spi_obj_t;
|
||||
|
||||
#if defined(MICROPY_HW_SPI1_SCK)
|
||||
SPI_HandleTypeDef SPIHandle1 = {.Instance = NULL};
|
||||
#endif
|
||||
@ -101,36 +93,36 @@ SPI_HandleTypeDef SPIHandle5 = {.Instance = NULL};
|
||||
SPI_HandleTypeDef SPIHandle6 = {.Instance = NULL};
|
||||
#endif
|
||||
|
||||
STATIC const pyb_spi_obj_t pyb_spi_obj[] = {
|
||||
const spi_t spi_obj[6] = {
|
||||
#if defined(MICROPY_HW_SPI1_SCK)
|
||||
{{&pyb_spi_type}, &SPIHandle1, &dma_SPI_1_TX, &dma_SPI_1_RX},
|
||||
{&SPIHandle1, &dma_SPI_1_TX, &dma_SPI_1_RX},
|
||||
#else
|
||||
{{&pyb_spi_type}, NULL, NULL, NULL},
|
||||
{NULL, NULL, NULL},
|
||||
#endif
|
||||
#if defined(MICROPY_HW_SPI2_SCK)
|
||||
{{&pyb_spi_type}, &SPIHandle2, &dma_SPI_2_TX, &dma_SPI_2_RX},
|
||||
{&SPIHandle2, &dma_SPI_2_TX, &dma_SPI_2_RX},
|
||||
#else
|
||||
{{&pyb_spi_type}, NULL, NULL, NULL},
|
||||
{NULL, NULL, NULL},
|
||||
#endif
|
||||
#if defined(MICROPY_HW_SPI3_SCK)
|
||||
{{&pyb_spi_type}, &SPIHandle3, &dma_SPI_3_TX, &dma_SPI_3_RX},
|
||||
{&SPIHandle3, &dma_SPI_3_TX, &dma_SPI_3_RX},
|
||||
#else
|
||||
{{&pyb_spi_type}, NULL, NULL, NULL},
|
||||
{NULL, NULL, NULL},
|
||||
#endif
|
||||
#if defined(MICROPY_HW_SPI4_SCK)
|
||||
{{&pyb_spi_type}, &SPIHandle4, &dma_SPI_4_TX, &dma_SPI_4_RX},
|
||||
{&SPIHandle4, &dma_SPI_4_TX, &dma_SPI_4_RX},
|
||||
#else
|
||||
{{&pyb_spi_type}, NULL, NULL, NULL},
|
||||
{NULL, NULL, NULL},
|
||||
#endif
|
||||
#if defined(MICROPY_HW_SPI5_SCK)
|
||||
{{&pyb_spi_type}, &SPIHandle5, &dma_SPI_5_TX, &dma_SPI_5_RX},
|
||||
{&SPIHandle5, &dma_SPI_5_TX, &dma_SPI_5_RX},
|
||||
#else
|
||||
{{&pyb_spi_type}, NULL, NULL, NULL},
|
||||
{NULL, NULL, NULL},
|
||||
#endif
|
||||
#if defined(MICROPY_HW_SPI6_SCK)
|
||||
{{&pyb_spi_type}, &SPIHandle6, &dma_SPI_6_TX, &dma_SPI_6_RX},
|
||||
{&SPIHandle6, &dma_SPI_6_TX, &dma_SPI_6_RX},
|
||||
#else
|
||||
{{&pyb_spi_type}, NULL, NULL, NULL},
|
||||
{NULL, NULL, NULL},
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -192,8 +184,8 @@ STATIC int spi_find(mp_obj_t id) {
|
||||
} else {
|
||||
// given an integer id
|
||||
int spi_id = mp_obj_get_int(id);
|
||||
if (spi_id >= 1 && spi_id <= MP_ARRAY_SIZE(pyb_spi_obj)
|
||||
&& pyb_spi_obj[spi_id - 1].spi != NULL) {
|
||||
if (spi_id >= 1 && spi_id <= MP_ARRAY_SIZE(spi_obj)
|
||||
&& spi_obj[spi_id - 1].spi != NULL) {
|
||||
return spi_id;
|
||||
}
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
|
||||
@ -203,8 +195,9 @@ STATIC int spi_find(mp_obj_t id) {
|
||||
|
||||
// sets the parameters in the SPI_InitTypeDef struct
|
||||
// if an argument is -1 then the corresponding parameter is not changed
|
||||
STATIC void spi_set_params(SPI_HandleTypeDef *spi, uint32_t prescale, int32_t baudrate,
|
||||
STATIC void spi_set_params(const spi_t *spi_obj, uint32_t prescale, int32_t baudrate,
|
||||
int32_t polarity, int32_t phase, int32_t bits, int32_t firstbit) {
|
||||
SPI_HandleTypeDef *spi = spi_obj->spi;
|
||||
SPI_InitTypeDef *init = &spi->Init;
|
||||
|
||||
if (prescale != 0xffffffff || baudrate != -1) {
|
||||
@ -248,14 +241,13 @@ STATIC void spi_set_params(SPI_HandleTypeDef *spi, uint32_t prescale, int32_t ba
|
||||
}
|
||||
|
||||
// TODO allow to take a list of pins to use
|
||||
void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
|
||||
const pyb_spi_obj_t *self;
|
||||
void spi_init(const spi_t *self, bool enable_nss_pin) {
|
||||
SPI_HandleTypeDef *spi = self->spi;
|
||||
const pin_obj_t *pins[4] = { NULL, NULL, NULL, NULL };
|
||||
|
||||
if (0) {
|
||||
#if defined(MICROPY_HW_SPI1_SCK)
|
||||
} else if (spi->Instance == SPI1) {
|
||||
self = &pyb_spi_obj[0];
|
||||
#if defined(MICROPY_HW_SPI1_NSS)
|
||||
pins[0] = &MICROPY_HW_SPI1_NSS;
|
||||
#endif
|
||||
@ -269,7 +261,6 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
|
||||
#endif
|
||||
#if defined(MICROPY_HW_SPI2_SCK)
|
||||
} else if (spi->Instance == SPI2) {
|
||||
self = &pyb_spi_obj[1];
|
||||
#if defined(MICROPY_HW_SPI2_NSS)
|
||||
pins[0] = &MICROPY_HW_SPI2_NSS;
|
||||
#endif
|
||||
@ -283,7 +274,6 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
|
||||
#endif
|
||||
#if defined(MICROPY_HW_SPI3_SCK)
|
||||
} else if (spi->Instance == SPI3) {
|
||||
self = &pyb_spi_obj[2];
|
||||
#if defined(MICROPY_HW_SPI3_NSS)
|
||||
pins[0] = &MICROPY_HW_SPI3_NSS;
|
||||
#endif
|
||||
@ -297,7 +287,6 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
|
||||
#endif
|
||||
#if defined(MICROPY_HW_SPI4_SCK)
|
||||
} else if (spi->Instance == SPI4) {
|
||||
self = &pyb_spi_obj[3];
|
||||
#if defined(MICROPY_HW_SPI4_NSS)
|
||||
pins[0] = &MICROPY_HW_SPI4_NSS;
|
||||
#endif
|
||||
@ -311,7 +300,6 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
|
||||
#endif
|
||||
#if defined(MICROPY_HW_SPI5_SCK)
|
||||
} else if (spi->Instance == SPI5) {
|
||||
self = &pyb_spi_obj[4];
|
||||
#if defined(MICROPY_HW_SPI5_NSS)
|
||||
pins[0] = &MICROPY_HW_SPI5_NSS;
|
||||
#endif
|
||||
@ -325,7 +313,6 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
|
||||
#endif
|
||||
#if defined(MICROPY_HW_SPI6_SCK)
|
||||
} else if (spi->Instance == SPI6) {
|
||||
self = &pyb_spi_obj[5];
|
||||
#if defined(MICROPY_HW_SPI6_NSS)
|
||||
pins[0] = &MICROPY_HW_SPI6_NSS;
|
||||
#endif
|
||||
@ -349,7 +336,7 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
|
||||
if (pins[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
mp_hal_pin_config_alt(pins[i], mode, pull, AF_FN_SPI, (self - &pyb_spi_obj[0]) + 1);
|
||||
mp_hal_pin_config_alt(pins[i], mode, pull, AF_FN_SPI, (self - &spi_obj[0]) + 1);
|
||||
}
|
||||
|
||||
// init the SPI device
|
||||
@ -368,7 +355,8 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
|
||||
dma_invalidate_channel(self->rx_dma_descr);
|
||||
}
|
||||
|
||||
void spi_deinit(SPI_HandleTypeDef *spi) {
|
||||
void spi_deinit(const spi_t *spi_obj) {
|
||||
SPI_HandleTypeDef *spi = spi_obj->spi;
|
||||
HAL_SPI_DeInit(spi);
|
||||
if (0) {
|
||||
#if defined(MICROPY_HW_SPI1_SCK)
|
||||
@ -410,12 +398,13 @@ void spi_deinit(SPI_HandleTypeDef *spi) {
|
||||
}
|
||||
}
|
||||
|
||||
STATIC HAL_StatusTypeDef spi_wait_dma_finished(SPI_HandleTypeDef *spi, uint32_t timeout) {
|
||||
STATIC HAL_StatusTypeDef spi_wait_dma_finished(const spi_t *spi, uint32_t timeout) {
|
||||
uint32_t start = HAL_GetTick();
|
||||
volatile HAL_SPI_StateTypeDef *state = &spi->spi->State;
|
||||
for (;;) {
|
||||
// Do an atomic check of the state; WFI will exit even if IRQs are disabled
|
||||
uint32_t irq_state = disable_irq();
|
||||
if (spi->State == HAL_SPI_STATE_READY) {
|
||||
if (*state == HAL_SPI_STATE_READY) {
|
||||
enable_irq(irq_state);
|
||||
return HAL_OK;
|
||||
}
|
||||
@ -433,7 +422,7 @@ STATIC HAL_StatusTypeDef spi_wait_dma_finished(SPI_HandleTypeDef *spi, uint32_t
|
||||
// and use that value for the baudrate in the formula, plus a small constant.
|
||||
#define SPI_TRANSFER_TIMEOUT(len) ((len) + 100)
|
||||
|
||||
STATIC void spi_transfer(const pyb_spi_obj_t *self, size_t len, const uint8_t *src, uint8_t *dest, uint32_t timeout) {
|
||||
STATIC void spi_transfer(const spi_t *self, size_t len, const uint8_t *src, uint8_t *dest, uint32_t timeout) {
|
||||
// Note: there seems to be a problem sending 1 byte using DMA the first
|
||||
// time directly after the SPI/DMA is initialised. The cause of this is
|
||||
// unknown but we sidestep the issue by using polling for 1 byte transfer.
|
||||
@ -452,7 +441,7 @@ STATIC void spi_transfer(const pyb_spi_obj_t *self, size_t len, const uint8_t *s
|
||||
MP_HAL_CLEAN_DCACHE(src, len);
|
||||
status = HAL_SPI_Transmit_DMA(self->spi, (uint8_t*)src, len);
|
||||
if (status == HAL_OK) {
|
||||
status = spi_wait_dma_finished(self->spi, timeout);
|
||||
status = spi_wait_dma_finished(self, timeout);
|
||||
}
|
||||
dma_deinit(self->tx_dma_descr);
|
||||
}
|
||||
@ -474,7 +463,7 @@ STATIC void spi_transfer(const pyb_spi_obj_t *self, size_t len, const uint8_t *s
|
||||
MP_HAL_CLEANINVALIDATE_DCACHE(dest, len);
|
||||
status = HAL_SPI_Receive_DMA(self->spi, dest, len);
|
||||
if (status == HAL_OK) {
|
||||
status = spi_wait_dma_finished(self->spi, timeout);
|
||||
status = spi_wait_dma_finished(self, timeout);
|
||||
}
|
||||
if (self->spi->hdmatx != NULL) {
|
||||
dma_deinit(self->tx_dma_descr);
|
||||
@ -495,7 +484,7 @@ STATIC void spi_transfer(const pyb_spi_obj_t *self, size_t len, const uint8_t *s
|
||||
MP_HAL_CLEANINVALIDATE_DCACHE(dest, len);
|
||||
status = HAL_SPI_TransmitReceive_DMA(self->spi, (uint8_t*)src, dest, len);
|
||||
if (status == HAL_OK) {
|
||||
status = spi_wait_dma_finished(self->spi, timeout);
|
||||
status = spi_wait_dma_finished(self, timeout);
|
||||
}
|
||||
dma_deinit(self->tx_dma_descr);
|
||||
dma_deinit(self->rx_dma_descr);
|
||||
@ -507,7 +496,9 @@ STATIC void spi_transfer(const pyb_spi_obj_t *self, size_t len, const uint8_t *s
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void spi_print(const mp_print_t *print, SPI_HandleTypeDef *spi, bool legacy) {
|
||||
STATIC void spi_print(const mp_print_t *print, const spi_t *spi_obj, bool legacy) {
|
||||
SPI_HandleTypeDef *spi = spi_obj->spi;
|
||||
|
||||
uint spi_num = 1; // default to SPI1
|
||||
if (spi->Instance == SPI2) { spi_num = 2; }
|
||||
else if (spi->Instance == SPI3) { spi_num = 3; }
|
||||
@ -556,7 +547,21 @@ STATIC void spi_print(const mp_print_t *print, SPI_HandleTypeDef *spi, bool lega
|
||||
/******************************************************************************/
|
||||
/* MicroPython bindings for legacy pyb API */
|
||||
|
||||
SPI_HandleTypeDef *spi_get_handle(mp_obj_t o) {
|
||||
typedef struct _pyb_spi_obj_t {
|
||||
mp_obj_base_t base;
|
||||
const spi_t *spi;
|
||||
} pyb_spi_obj_t;
|
||||
|
||||
STATIC const pyb_spi_obj_t pyb_spi_obj[] = {
|
||||
{{&pyb_spi_type}, &spi_obj[0]},
|
||||
{{&pyb_spi_type}, &spi_obj[1]},
|
||||
{{&pyb_spi_type}, &spi_obj[2]},
|
||||
{{&pyb_spi_type}, &spi_obj[3]},
|
||||
{{&pyb_spi_type}, &spi_obj[4]},
|
||||
{{&pyb_spi_type}, &spi_obj[5]},
|
||||
};
|
||||
|
||||
const spi_t *spi_from_mp_obj(mp_obj_t o) {
|
||||
if (!MP_OBJ_IS_TYPE(o, &pyb_spi_type)) {
|
||||
mp_raise_ValueError("expecting an SPI object");
|
||||
}
|
||||
@ -595,7 +600,7 @@ STATIC mp_obj_t pyb_spi_init_helper(const pyb_spi_obj_t *self, size_t n_args, co
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
// set the SPI configuration values
|
||||
SPI_InitTypeDef *init = &self->spi->Init;
|
||||
SPI_InitTypeDef *init = &self->spi->spi->Init;
|
||||
init->Mode = args[0].u_int;
|
||||
|
||||
spi_set_params(self->spi, args[2].u_int, args[1].u_int, args[3].u_int, args[4].u_int,
|
||||
@ -693,7 +698,7 @@ STATIC mp_obj_t pyb_spi_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
|
||||
pyb_buf_get_for_send(args[0].u_obj, &bufinfo, data);
|
||||
|
||||
// send the data
|
||||
spi_transfer(self, bufinfo.len, bufinfo.buf, NULL, args[1].u_int);
|
||||
spi_transfer(self->spi, bufinfo.len, bufinfo.buf, NULL, args[1].u_int);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
@ -727,7 +732,7 @@ STATIC mp_obj_t pyb_spi_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
|
||||
mp_obj_t o_ret = pyb_buf_get_for_recv(args[0].u_obj, &vstr);
|
||||
|
||||
// receive the data
|
||||
spi_transfer(self, vstr.len, NULL, (uint8_t*)vstr.buf, args[1].u_int);
|
||||
spi_transfer(self->spi, vstr.len, NULL, (uint8_t*)vstr.buf, args[1].u_int);
|
||||
|
||||
// return the received data
|
||||
if (o_ret != MP_OBJ_NULL) {
|
||||
@ -797,7 +802,7 @@ STATIC mp_obj_t pyb_spi_send_recv(size_t n_args, const mp_obj_t *pos_args, mp_ma
|
||||
}
|
||||
|
||||
// do the transfer
|
||||
spi_transfer(self, bufinfo_send.len, bufinfo_send.buf, bufinfo_recv.buf, args[2].u_int);
|
||||
spi_transfer(self->spi, bufinfo_send.len, bufinfo_send.buf, bufinfo_recv.buf, args[2].u_int);
|
||||
|
||||
// return the received data
|
||||
if (o_ret != MP_OBJ_NULL) {
|
||||
@ -845,7 +850,8 @@ STATIC const mp_rom_map_elem_t pyb_spi_locals_dict_table[] = {
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_spi_locals_dict, pyb_spi_locals_dict_table);
|
||||
|
||||
STATIC void spi_transfer_machine(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
|
||||
spi_transfer((pyb_spi_obj_t*)self_in, len, src, dest, SPI_TRANSFER_TIMEOUT(len));
|
||||
pyb_spi_obj_t *self = (pyb_spi_obj_t*)self_in;
|
||||
spi_transfer(self->spi, len, src, dest, SPI_TRANSFER_TIMEOUT(len));
|
||||
}
|
||||
|
||||
STATIC const mp_machine_spi_p_t pyb_spi_p = {
|
||||
@ -866,21 +872,21 @@ const mp_obj_type_t pyb_spi_type = {
|
||||
|
||||
typedef struct _machine_hard_spi_obj_t {
|
||||
mp_obj_base_t base;
|
||||
const pyb_spi_obj_t *pyb;
|
||||
const spi_t *spi;
|
||||
} machine_hard_spi_obj_t;
|
||||
|
||||
STATIC const machine_hard_spi_obj_t machine_hard_spi_obj[] = {
|
||||
{{&machine_hard_spi_type}, &pyb_spi_obj[0]},
|
||||
{{&machine_hard_spi_type}, &pyb_spi_obj[1]},
|
||||
{{&machine_hard_spi_type}, &pyb_spi_obj[2]},
|
||||
{{&machine_hard_spi_type}, &pyb_spi_obj[3]},
|
||||
{{&machine_hard_spi_type}, &pyb_spi_obj[4]},
|
||||
{{&machine_hard_spi_type}, &pyb_spi_obj[5]},
|
||||
{{&machine_hard_spi_type}, &spi_obj[0]},
|
||||
{{&machine_hard_spi_type}, &spi_obj[1]},
|
||||
{{&machine_hard_spi_type}, &spi_obj[2]},
|
||||
{{&machine_hard_spi_type}, &spi_obj[3]},
|
||||
{{&machine_hard_spi_type}, &spi_obj[4]},
|
||||
{{&machine_hard_spi_type}, &spi_obj[5]},
|
||||
};
|
||||
|
||||
STATIC void machine_hard_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
machine_hard_spi_obj_t *self = (machine_hard_spi_obj_t*)self_in;
|
||||
spi_print(print, self->pyb->spi, false);
|
||||
spi_print(print, self->spi, false);
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -911,7 +917,7 @@ mp_obj_t machine_hard_spi_make_new(const mp_obj_type_t *type, size_t n_args, siz
|
||||
}
|
||||
|
||||
// set the SPI configuration values
|
||||
SPI_InitTypeDef *init = &self->pyb->spi->Init;
|
||||
SPI_InitTypeDef *init = &self->spi->spi->Init;
|
||||
init->Mode = SPI_MODE_MASTER;
|
||||
|
||||
// these parameters are not currently configurable
|
||||
@ -922,12 +928,12 @@ mp_obj_t machine_hard_spi_make_new(const mp_obj_type_t *type, size_t n_args, siz
|
||||
init->CRCPolynomial = 0;
|
||||
|
||||
// set configurable paramaters
|
||||
spi_set_params(self->pyb->spi, 0xffffffff, args[ARG_baudrate].u_int,
|
||||
spi_set_params(self->spi, 0xffffffff, args[ARG_baudrate].u_int,
|
||||
args[ARG_polarity].u_int, args[ARG_phase].u_int, args[ARG_bits].u_int,
|
||||
args[ARG_firstbit].u_int);
|
||||
|
||||
// init the SPI bus
|
||||
spi_init(self->pyb->spi, false);
|
||||
spi_init(self->spi, false);
|
||||
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
@ -947,22 +953,22 @@ STATIC void machine_hard_spi_init(mp_obj_base_t *self_in, size_t n_args, const m
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
// set the SPI configuration values
|
||||
spi_set_params(self->pyb->spi, 0xffffffff, args[ARG_baudrate].u_int,
|
||||
spi_set_params(self->spi, 0xffffffff, args[ARG_baudrate].u_int,
|
||||
args[ARG_polarity].u_int, args[ARG_phase].u_int, args[ARG_bits].u_int,
|
||||
args[ARG_firstbit].u_int);
|
||||
|
||||
// re-init the SPI bus
|
||||
spi_init(self->pyb->spi, false);
|
||||
spi_init(self->spi, false);
|
||||
}
|
||||
|
||||
STATIC void machine_hard_spi_deinit(mp_obj_base_t *self_in) {
|
||||
machine_hard_spi_obj_t *self = (machine_hard_spi_obj_t*)self_in;
|
||||
spi_deinit(self->pyb->spi);
|
||||
spi_deinit(self->spi);
|
||||
}
|
||||
|
||||
STATIC void machine_hard_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
|
||||
machine_hard_spi_obj_t *self = (machine_hard_spi_obj_t*)self_in;
|
||||
spi_transfer(self->pyb, len, src, dest, SPI_TRANSFER_TIMEOUT(len));
|
||||
spi_transfer(self->spi, len, src, dest, SPI_TRANSFER_TIMEOUT(len));
|
||||
}
|
||||
|
||||
STATIC const mp_machine_spi_p_t machine_hard_spi_p = {
|
||||
|
@ -26,18 +26,29 @@
|
||||
#ifndef MICROPY_INCLUDED_STMHAL_SPI_H
|
||||
#define MICROPY_INCLUDED_STMHAL_SPI_H
|
||||
|
||||
#include "dma.h"
|
||||
|
||||
typedef struct _spi_t {
|
||||
SPI_HandleTypeDef *spi;
|
||||
const dma_descr_t *tx_dma_descr;
|
||||
const dma_descr_t *rx_dma_descr;
|
||||
} spi_t;
|
||||
|
||||
extern SPI_HandleTypeDef SPIHandle1;
|
||||
extern SPI_HandleTypeDef SPIHandle2;
|
||||
extern SPI_HandleTypeDef SPIHandle3;
|
||||
extern SPI_HandleTypeDef SPIHandle4;
|
||||
extern SPI_HandleTypeDef SPIHandle5;
|
||||
extern SPI_HandleTypeDef SPIHandle6;
|
||||
|
||||
extern const spi_t spi_obj[6];
|
||||
|
||||
extern const mp_obj_type_t pyb_spi_type;
|
||||
extern const mp_obj_type_t machine_soft_spi_type;
|
||||
extern const mp_obj_type_t machine_hard_spi_type;
|
||||
|
||||
void spi_init0(void);
|
||||
void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin);
|
||||
SPI_HandleTypeDef *spi_get_handle(mp_obj_t o);
|
||||
void spi_init(const spi_t *spi, bool enable_nss_pin);
|
||||
const spi_t *spi_from_mp_obj(mp_obj_t o);
|
||||
|
||||
#endif // MICROPY_INCLUDED_STMHAL_SPI_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user