Skip to content

Allow (unpadded) SPI transfers < 8bits #5542

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 12 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 39 additions & 11 deletions drivers/bus/softspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2016-2018 Damien P. George
* Copyright (c) 2019 "Eric Poulsen" <eric@zyxod.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand All @@ -25,6 +26,7 @@
*/

#include "drivers/bus/spi.h"
#include "py/runtime.h"

int mp_soft_spi_ioctl(void *self_in, uint32_t cmd) {
mp_soft_spi_obj_t *self = (mp_soft_spi_obj_t*)self_in;
Expand All @@ -44,38 +46,63 @@ int mp_soft_spi_ioctl(void *self_in, uint32_t cmd) {
return 0;
}

void mp_soft_spi_transfer(void *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
void mp_soft_spi_transfer(void *self_in, size_t len, const uint8_t *src, uint8_t *dest, uint8_t bits) {
mp_soft_spi_obj_t *self = (mp_soft_spi_obj_t*)self_in;
uint32_t delay_half = self->delay_half;

bits = bits ? bits : self->bits;
if (bits == 0) {
// Shoudln't be possible with soft SPI, but
// just in case.
mp_raise_ValueError(MP_ERROR_TEXT("bits cannot be 0"));
}

int bytesPerChunk = (bits + 7) / 8;
// round length down as needed (possibly to zero)
len = len / bytesPerChunk * bytesPerChunk;
if(len == 0) {
return;
}

uint8_t remBits = bits;

// only MSB transfer is implemented

// If a port defines MICROPY_HW_SOFTSPI_MIN_DELAY, and the configured
// delay_half is equal to this value, then the software SPI implementation
// will run as fast as possible, limited only by CPU speed and GPIO time.
#ifdef MICROPY_HW_SOFTSPI_MIN_DELAY
if (delay_half == MICROPY_HW_SOFTSPI_MIN_DELAY) {
for (size_t i = 0; i < len; ++i) {
uint8_t data_out = src[i];
if (delay_half == MICROPY_HW_SOFTSPI_MIN_DELAY)
{
while (len--) {
uint8_t bitsThisByte = remBits < 8 ? remBits : 8;
uint8_t data_out = *src++;
uint8_t data_in = 0;
for (int j = 0; j < 8; ++j, data_out <<= 1) {

remBits -= bitsThisByte;
for (; bitsThisByte; --bitsThisByte, data_out <<= 1) {
mp_hal_pin_write(self->mosi, (data_out >> 7) & 1);
mp_hal_pin_write(self->sck, 1 - self->polarity);
data_in = (data_in << 1) | mp_hal_pin_read(self->miso);
mp_hal_pin_write(self->sck, self->polarity);
}
remBits = remBits ? remBits : bits;
if (dest != NULL) {
dest[i] = data_in;
*dest++ = data_in;
}
}
return;
}
#endif
#endif

for (size_t i = 0; i < len; ++i) {
uint8_t data_out = src[i];

while(len--) {
uint8_t bitsThisByte = remBits < 8 ? remBits : 8;
uint8_t data_out = *src++;
uint8_t data_in = 0;
for (int j = 0; j < 8; ++j, data_out <<= 1) {

remBits -= bitsThisByte;
for(;bitsThisByte; --bitsThisByte, data_out <<= 1) {
mp_hal_pin_write(self->mosi, (data_out >> 7) & 1);
if (self->phase == 0) {
mp_hal_delay_us_fast(delay_half);
Expand All @@ -93,8 +120,9 @@ void mp_soft_spi_transfer(void *self_in, size_t len, const uint8_t *src, uint8_t
mp_hal_delay_us_fast(delay_half);
}
}
remBits = remBits ? remBits : bits;
if (dest != NULL) {
dest[i] = data_in;
*dest++ = data_in;
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions drivers/bus/spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,14 @@ enum {

typedef struct _mp_spi_proto_t {
int (*ioctl)(void *self, uint32_t cmd);
void (*transfer)(void *self, size_t len, const uint8_t *src, uint8_t *dest);
void (*transfer)(void *self, size_t len, const uint8_t *src, uint8_t *dest, uint8_t bits);
} mp_spi_proto_t;

typedef struct _mp_soft_spi_obj_t {
uint32_t delay_half; // microsecond delay for half SCK period
uint8_t polarity;
uint8_t phase;
uint8_t bits;
mp_hal_pin_obj_t sck;
mp_hal_pin_obj_t mosi;
mp_hal_pin_obj_t miso;
Expand All @@ -50,6 +51,6 @@ typedef struct _mp_soft_spi_obj_t {
extern const mp_spi_proto_t mp_soft_spi_proto;

int mp_soft_spi_ioctl(void *self, uint32_t cmd);
void mp_soft_spi_transfer(void *self, size_t len, const uint8_t *src, uint8_t *dest);
void mp_soft_spi_transfer(void *self, size_t len, const uint8_t *src, uint8_t *dest, uint8_t bits);

#endif // MICROPY_INCLUDED_DRIVERS_BUS_SPI_H
6 changes: 3 additions & 3 deletions drivers/memory/spiflash.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ STATIC void mp_spiflash_write_cmd_data(mp_spiflash_t *self, uint8_t cmd, size_t
if (c->bus_kind == MP_SPIFLASH_BUS_SPI) {
// Note: len/data are unused for standard SPI
mp_hal_pin_write(c->bus.u_spi.cs, 0);
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 1, &cmd, NULL);
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 1, &cmd, NULL, 8);
mp_hal_pin_write(c->bus.u_spi.cs, 1);
} else {
c->bus.u_qspi.proto->write_cmd_data(c->bus.u_qspi.data, cmd, len, data);
Expand Down Expand Up @@ -110,8 +110,8 @@ STATIC uint32_t mp_spiflash_read_cmd(mp_spiflash_t *self, uint8_t cmd, size_t le
if (c->bus_kind == MP_SPIFLASH_BUS_SPI) {
uint32_t buf;
mp_hal_pin_write(c->bus.u_spi.cs, 0);
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 1, &cmd, NULL);
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, len, (void*)&buf, (void*)&buf);
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 1, &cmd, NULL, 8);
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, len, (void*)&buf, (void*)&buf, 8);
mp_hal_pin_write(c->bus.u_spi.cs, 1);
return buf;
} else {
Expand Down
46 changes: 28 additions & 18 deletions extmod/machine_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,50 +59,59 @@ STATIC mp_obj_t machine_spi_deinit(mp_obj_t self) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_spi_deinit_obj, machine_spi_deinit);

STATIC void mp_machine_spi_transfer(mp_obj_t self, size_t len, const void *src, void *dest) {
STATIC void mp_machine_spi_transfer(mp_obj_t self, size_t len, const void *src, void *dest, int8_t bits) {
mp_obj_base_t *s = (mp_obj_base_t *)MP_OBJ_TO_PTR(self);
mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t *)s->type->protocol;
spi_p->transfer(s, len, src, dest);
spi_p->transfer(s, len, src, dest, bits);
}

STATIC mp_obj_t mp_machine_spi_read(size_t n_args, const mp_obj_t *args) {
vstr_t vstr;
vstr_init_len(&vstr, mp_obj_get_int(args[1]));
memset(vstr.buf, n_args == 3 ? mp_obj_get_int(args[2]) : 0, vstr.len);
mp_machine_spi_transfer(args[0], vstr.len, vstr.buf, vstr.buf);
memset(vstr.buf, n_args >= 3 ? mp_obj_get_int(args[2]) : 0, vstr.len);
uint8_t bits = n_args == 4 ? mp_obj_get_int(args[3]) : 0;
mp_machine_spi_transfer(args[0], vstr.len, vstr.buf, vstr.buf, bits);
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_read_obj, 2, 3, mp_machine_spi_read);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_read_obj, 2, 4, mp_machine_spi_read);

STATIC mp_obj_t mp_machine_spi_readinto(size_t n_args, const mp_obj_t *args) {
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
memset(bufinfo.buf, n_args == 3 ? mp_obj_get_int(args[2]) : 0, bufinfo.len);
mp_machine_spi_transfer(args[0], bufinfo.len, bufinfo.buf, bufinfo.buf);
memset(bufinfo.buf, n_args >= 3 ? mp_obj_get_int(args[2]) : 0, bufinfo.len);
uint8_t bits = n_args == 4 ? mp_obj_get_int(args[3]) : 0;
mp_machine_spi_transfer(args[0], bufinfo.len, bufinfo.buf, bufinfo.buf, bits);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_readinto_obj, 2, 3, mp_machine_spi_readinto);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_readinto_obj, 2, 4, mp_machine_spi_readinto);

STATIC mp_obj_t mp_machine_spi_write(mp_obj_t self, mp_obj_t wr_buf) {
STATIC mp_obj_t mp_machine_spi_write(size_t n_args, const mp_obj_t *args) {
mp_obj_t self = args[0];
mp_obj_t wr_buf = args[1];
uint8_t bits = n_args == 3 ? mp_obj_get_int(args[2]) : 0;
mp_buffer_info_t src;
mp_get_buffer_raise(wr_buf, &src, MP_BUFFER_READ);
mp_machine_spi_transfer(self, src.len, (const uint8_t *)src.buf, NULL);
mp_machine_spi_transfer(self, src.len, (const uint8_t *)src.buf, NULL, bits);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(mp_machine_spi_write_obj, mp_machine_spi_write);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_write_obj, 2, 3, mp_machine_spi_write);

STATIC mp_obj_t mp_machine_spi_write_readinto(mp_obj_t self, mp_obj_t wr_buf, mp_obj_t rd_buf) {
STATIC mp_obj_t mp_machine_spi_write_readinto(size_t n_args, const mp_obj_t *args) {
mp_obj_t self = args[0];
mp_obj_t wr_buf = args[1];
mp_obj_t rd_buf = args[2];
uint8_t bits = n_args == 4 ? mp_obj_get_int(args[3]) : 0;
mp_buffer_info_t src;
mp_get_buffer_raise(wr_buf, &src, MP_BUFFER_READ);
mp_buffer_info_t dest;
mp_get_buffer_raise(rd_buf, &dest, MP_BUFFER_WRITE);
if (src.len != dest.len) {
mp_raise_ValueError(MP_ERROR_TEXT("buffers must be the same length"));
}
mp_machine_spi_transfer(self, src.len, src.buf, dest.buf);
mp_machine_spi_transfer(self, src.len, src.buf, dest.buf, bits);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_3(mp_machine_spi_write_readinto_obj, mp_machine_spi_write_readinto);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_write_readinto_obj, 3, 4, mp_machine_spi_write_readinto);

STATIC const mp_rom_map_elem_t machine_spi_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_spi_init_obj) },
Expand Down Expand Up @@ -179,8 +188,9 @@ STATIC mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n
self->spi.delay_half = baudrate_to_delay_half(args[ARG_baudrate].u_int);
self->spi.polarity = args[ARG_polarity].u_int;
self->spi.phase = args[ARG_phase].u_int;
if (args[ARG_bits].u_int != 8) {
mp_raise_ValueError(MP_ERROR_TEXT("bits must be 8"));
self->spi.bits = args[ARG_bits].u_int;
if (self->spi.bits == 0) {
mp_raise_ValueError(MP_ERROR_TEXT("bits must be > 0"));
}
if (args[ARG_firstbit].u_int != MICROPY_PY_MACHINE_SPI_MSB) {
mp_raise_ValueError(MP_ERROR_TEXT("firstbit must be MSB"));
Expand Down Expand Up @@ -238,9 +248,9 @@ STATIC void mp_machine_soft_spi_init(mp_obj_base_t *self_in, size_t n_args, cons
mp_soft_spi_ioctl(&self->spi, MP_SPI_IOCTL_INIT);
}

STATIC void mp_machine_soft_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
STATIC void mp_machine_soft_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest, int8_t bits) {
mp_machine_soft_spi_obj_t *self = (mp_machine_soft_spi_obj_t *)self_in;
mp_soft_spi_transfer(&self->spi, len, src, dest);
mp_soft_spi_transfer(&self->spi, len, src, dest, bits);
}

const mp_machine_spi_p_t mp_machine_soft_spi_p = {
Expand Down
7 changes: 3 additions & 4 deletions extmod/machine_spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
typedef struct _mp_machine_spi_p_t {
void (*init)(mp_obj_base_t *obj, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
void (*deinit)(mp_obj_base_t *obj); // can be NULL
void (*transfer)(mp_obj_base_t *obj, size_t len, const uint8_t *src, uint8_t *dest);
void (*transfer)(mp_obj_base_t *obj, size_t len, const uint8_t *src, uint8_t *dest, int8_t bits);
} mp_machine_spi_p_t;

typedef struct _mp_machine_soft_spi_obj_t {
Expand All @@ -60,10 +60,9 @@ extern const mp_obj_type_t mp_machine_soft_spi_type;
extern const mp_obj_dict_t mp_machine_spi_locals_dict;

mp_obj_t mp_machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args);

MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_read_obj);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_readinto_obj);
MP_DECLARE_CONST_FUN_OBJ_2(mp_machine_spi_write_obj);
MP_DECLARE_CONST_FUN_OBJ_3(mp_machine_spi_write_readinto_obj);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_write_obj);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_write_readinto_obj);

#endif // MICROPY_INCLUDED_EXTMOD_MACHINE_SPI_H
7 changes: 4 additions & 3 deletions ports/esp32/machine_hw_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,16 +288,17 @@ STATIC mp_uint_t gcd(mp_uint_t x, mp_uint_t y) {
return x;
}

STATIC void machine_hw_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
STATIC void machine_hw_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest, int8_t _bits) {
machine_hw_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
int8_t bits = _bits != -1 ? _bits : self->bits;

if (self->state == MACHINE_HW_SPI_STATE_DEINIT) {
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("transfer on deinitialized SPI"));
return;
}

// Round to nearest whole set of bits
int bits_to_send = len * 8 / self->bits * self->bits;
int bits_to_send = len * 8 / bits * bits;

if (!bits_to_send) {
mp_raise_ValueError(MP_ERROR_TEXT("buffer too short"));
Expand All @@ -320,7 +321,7 @@ STATIC void machine_hw_spi_transfer(mp_obj_base_t *self_in, size_t len, const ui
} else {
int offset = 0;
int bits_remaining = bits_to_send;
int optimum_word_size = 8 * self->bits / gcd(8, self->bits);
int optimum_word_size = 8 * bits / gcd(8, bits);
int max_transaction_bits = MP_HW_SPI_MAX_XFER_BITS / optimum_word_size * optimum_word_size;
spi_transaction_t *transaction, *result, transactions[2];
int i = 0;
Expand Down
2 changes: 1 addition & 1 deletion ports/esp8266/machine_hspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ typedef struct _machine_hspi_obj_t {
uint8_t phase;
} machine_hspi_obj_t;

STATIC void machine_hspi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
STATIC void machine_hspi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest, int8_t bits) {
(void)self_in;

if (dest == NULL) {
Expand Down
2 changes: 1 addition & 1 deletion ports/mimxrt/machine_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ void LPSPI_EDMAMasterCallback(LPSPI_Type *base, lpspi_master_edma_handle_t *hand
self->transfer_busy = false;
}

STATIC void machine_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
STATIC void machine_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest, int8_t bits) {
machine_spi_obj_t *self = (machine_spi_obj_t *)self_in;
// Use DMA for large transfers if channels are available
const size_t dma_min_size_threshold = 16; // That's the FIFO size
Expand Down
24 changes: 13 additions & 11 deletions ports/nrf/modules/machine/spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ STATIC int spi_find(mp_obj_t id) {
}
}

void spi_transfer(const machine_hard_spi_obj_t * self, size_t len, const void * src, void * dest) {
void spi_transfer(const machine_hard_spi_obj_t * self, size_t len, const void * src, void * dest, uint8_t bits) {
nrfx_spi_xfer_desc_t xfer_desc = {
.p_tx_buffer = src,
.tx_length = len,
Expand Down Expand Up @@ -377,17 +377,17 @@ STATIC void machine_hard_spi_deinit(mp_obj_t self_in) {
nrfx_spi_uninit(self->p_spi);
}

STATIC void machine_hard_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
STATIC void machine_hard_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest, uint8_t bits) {
const machine_hard_spi_obj_t *self = (machine_hard_spi_obj_t*)self_in;
spi_transfer(self, len, src, dest);
spi_transfer(self, len, src, dest, bits);
}


STATIC mp_obj_t mp_machine_spi_read(size_t n_args, const mp_obj_t *args) {
vstr_t vstr;
vstr_init_len(&vstr, mp_obj_get_int(args[1]));
memset(vstr.buf, n_args == 3 ? mp_obj_get_int(args[2]) : 0, vstr.len);
spi_transfer(args[0], vstr.len, vstr.buf, vstr.buf);
spi_transfer(args[0], vstr.len, vstr.buf, vstr.buf, -1);
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_read_obj, 2, 3, mp_machine_spi_read);
Expand All @@ -396,31 +396,33 @@ STATIC mp_obj_t mp_machine_spi_readinto(size_t n_args, const mp_obj_t *args) {
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
memset(bufinfo.buf, n_args == 3 ? mp_obj_get_int(args[2]) : 0, bufinfo.len);
spi_transfer(args[0], bufinfo.len, bufinfo.buf, bufinfo.buf);
spi_transfer(args[0], bufinfo.len, bufinfo.buf, bufinfo.buf, -1);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_readinto_obj, 2, 3, mp_machine_spi_readinto);

STATIC mp_obj_t mp_machine_spi_write(mp_obj_t self, mp_obj_t wr_buf) {
STATIC mp_obj_t mp_machine_spi_write(mp_obj_t self, mp_obj_t wr_buf, mp_obj_t _bits) {
mp_buffer_info_t src;
int8_t bits = _bits == mp_const_none ? -1 : mp_obj_get_int(_bits);
mp_get_buffer_raise(wr_buf, &src, MP_BUFFER_READ);
spi_transfer(self, src.len, (const uint8_t*)src.buf, NULL);
spi_transfer(self, src.len, (const uint8_t*)src.buf, NULL, bits);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(mp_machine_spi_write_obj, mp_machine_spi_write);
MP_DEFINE_CONST_FUN_OBJ_3(mp_machine_spi_write_obj, mp_machine_spi_write);

STATIC mp_obj_t mp_machine_spi_write_readinto(mp_obj_t self, mp_obj_t wr_buf, mp_obj_t rd_buf) {
STATIC mp_obj_t mp_machine_spi_write_readinto(mp_obj_t self, mp_obj_t wr_buf, mp_obj_t rd_buf, mp_obj_t _bits) {
mp_buffer_info_t src;
int8_t bits = _bits == mp_const_none ? -1 : mp_obj_get_int(_bits);
mp_get_buffer_raise(wr_buf, &src, MP_BUFFER_READ);
mp_buffer_info_t dest;
mp_get_buffer_raise(rd_buf, &dest, MP_BUFFER_WRITE);
if (src.len != dest.len) {
mp_raise_ValueError(MP_ERROR_TEXT("buffers must be the same length"));
}
spi_transfer(self, src.len, src.buf, dest.buf);
spi_transfer(self, src.len, src.buf, dest.buf, bits);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_3(mp_machine_spi_write_readinto_obj, mp_machine_spi_write_readinto);
MP_DEFINE_CONST_FUN_OBJ_4(mp_machine_spi_write_readinto_obj, mp_machine_spi_write_readinto);


STATIC const mp_machine_spi_p_t machine_hard_spi_p = {
Expand Down
3 changes: 2 additions & 1 deletion ports/nrf/modules/machine/spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ void spi_init0(void);
void spi_transfer(const machine_hard_spi_obj_t * self,
size_t len,
const void * src,
void * dest);
void * dest,
uint8_t bits);
Loading