diff options
Diffstat (limited to 'stmhal/spi.c')
| -rw-r--r-- | stmhal/spi.c | 87 |
1 files changed, 69 insertions, 18 deletions
diff --git a/stmhal/spi.c b/stmhal/spi.c index bad71e87b..ba550f979 100644 --- a/stmhal/spi.c +++ b/stmhal/spi.c @@ -14,24 +14,28 @@ #include "bufhelper.h" #include "spi.h" -// Usage model: -// -// See usage model of I2C in i2c.c. SPI is very similar. Main difference is -// parameters to init the SPI bus: -// -// from pyb import SPI -// spi = SPI(1, SPI.MASTER, baudrate=600000, polarity=1, phase=1, crc=0x7) -// -// Only required parameter is mode, SPI.MASTER or SPI.SLAVE. Polarity can be -// 0 or 1, and is the level the idle clock line sits at. Phase can be 1 or 2 -// for number of edges. Crc can be None for no CRC, or a polynomial specifier. -// -// Additional method for SPI: -// -// data = spi.send_recv(b'1234') # send 4 bytes and receive 4 bytes -// buf = bytearray(4) -// spi.send_recv(b'1234', buf) # send 4 bytes and receive 4 into buf -// spi.send_recv(buf, buf) # send/recv 4 bytes from/to buf +/// \moduleref pyb +/// \class SPI - a master-driven serial protocol +/// +/// SPI is a serial protocol that is driven by a master. At the physical level +/// there are 3 lines: SCK, MOSI, MISO. +/// +/// See usage model of I2C; SPI is very similar. Main difference is +/// parameters to init the SPI bus: +/// +/// from pyb import SPI +/// spi = SPI(1, SPI.MASTER, baudrate=600000, polarity=1, phase=1, crc=0x7) +/// +/// Only required parameter is mode, SPI.MASTER or SPI.SLAVE. Polarity can be +/// 0 or 1, and is the level the idle clock line sits at. Phase can be 1 or 2 +/// for number of edges. Crc can be None for no CRC, or a polynomial specifier. +/// +/// Additional method for SPI: +/// +/// data = spi.send_recv(b'1234') # send 4 bytes and receive 4 bytes +/// buf = bytearray(4) +/// spi.send_recv(b'1234', buf) # send 4 bytes and receive 4 into buf +/// spi.send_recv(buf, buf) # send/recv 4 bytes from/to buf #if MICROPY_HW_ENABLE_SPI1 SPI_HandleTypeDef SPIHandle1 = {.Instance = NULL}; @@ -194,6 +198,12 @@ STATIC void pyb_spi_print(void (*print)(void *env, const char *fmt, ...), void * } } +/// \method init(mode, baudrate=328125, *, polarity=1, phase=1, bits=8, firstbit=SPI.MSB, ti=false, crc=None) +/// +/// Initialise the SPI bus with the given parameters: +/// +/// - `mode` must be either `SPI.MASTER` or `SPI.SLAVE`. +/// - `baudrate` is the SCK clock rate (only sensible for a master). STATIC const mp_arg_t pyb_spi_init_args[] = { { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 328125} }, @@ -258,6 +268,13 @@ STATIC mp_obj_t pyb_spi_init_helper(const pyb_spi_obj_t *self, uint n_args, cons return mp_const_none; } +/// \classmethod \constructor(bus, ...) +/// +/// Construct an SPI object on the given bus. `bus` can be 1 or 2. +/// With no additional parameters, the SPI object is created but not +/// initialised (it has the settings from the last initialisation of +/// the bus, if any). If extra arguments are given, the bus is initialised. +/// See `init` for parameters of initialisation. STATIC mp_obj_t pyb_spi_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { // check arguments mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); @@ -288,6 +305,8 @@ STATIC mp_obj_t pyb_spi_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_arg } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_init_obj, 1, pyb_spi_init); +/// \method deinit() +/// Turn off the SPI bus. STATIC mp_obj_t pyb_spi_deinit(mp_obj_t self_in) { pyb_spi_obj_t *self = self_in; spi_deinit(self->spi); @@ -295,6 +314,13 @@ STATIC mp_obj_t pyb_spi_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_spi_deinit_obj, pyb_spi_deinit); +/// \method send(send, *, timeout=5000) +/// Send data on the bus: +/// +/// - `send` is the data to send (an integer to send, or a buffer object). +/// - `timeout` is the timeout in milliseconds to wait for the send. +/// +/// Return value: `None`. STATIC const mp_arg_t pyb_spi_send_args[] = { { MP_QSTR_send, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} }, @@ -327,6 +353,16 @@ STATIC mp_obj_t pyb_spi_send(uint n_args, const mp_obj_t *args, mp_map_t *kw_arg } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_send_obj, 1, pyb_spi_send); +/// \method recv(recv, *, timeout=5000) +/// +/// Receive data on the bus: +/// +/// - `recv` can be an integer, which is the number of bytes to receive, +/// or a mutable buffer, which will be filled with received bytes. +/// - `timeout` is the timeout in milliseconds to wait for the receive. +/// +/// Return value: if `recv` is an integer then a new buffer of the bytes received, +/// otherwise the same buffer that was passed in to `recv`. STATIC const mp_arg_t pyb_spi_recv_args[] = { { MP_QSTR_recv, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} }, @@ -363,6 +399,17 @@ STATIC mp_obj_t pyb_spi_recv(uint n_args, const mp_obj_t *args, mp_map_t *kw_arg } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_recv_obj, 1, pyb_spi_recv); +/// \method send_recv(send, recv=None, *, timeout=5000) +/// +/// Send and receive data on the bus at the same time: +/// +/// - `send` is the data to send (an integer to send, or a buffer object). +/// - `recv` is a mutable buffer which will be filled with received bytes. +/// It can be the same as `send`, or omitted. If omitted, a new buffer will +/// be created. +/// - `timeout` is the timeout in milliseconds to wait for the receive. +/// +/// Return value: the buffer with the received bytes. STATIC const mp_arg_t pyb_spi_send_recv_args[] = { { MP_QSTR_send, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_recv, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, @@ -436,6 +483,10 @@ STATIC const mp_map_elem_t pyb_spi_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_send_recv), (mp_obj_t)&pyb_spi_send_recv_obj }, // class constants + /// \constant MASTER - for initialising the bus to master mode + /// \constant SLAVE - for initialising the bus to slave mode + /// \constant MSB - set the first bit to MSB + /// \constant LSB - set the first bit to LSB { MP_OBJ_NEW_QSTR(MP_QSTR_MASTER), MP_OBJ_NEW_SMALL_INT(SPI_MODE_MASTER) }, { MP_OBJ_NEW_QSTR(MP_QSTR_SLAVE), MP_OBJ_NEW_SMALL_INT(SPI_MODE_SLAVE) }, { MP_OBJ_NEW_QSTR(MP_QSTR_MSB), MP_OBJ_NEW_SMALL_INT(SPI_FIRSTBIT_MSB) }, |
