From b98f31a20349aa179dd6105d01b7f607e991ba86 Mon Sep 17 00:00:00 2001 From: bkleiner Date: Sun, 1 Dec 2024 15:54:51 +0100 Subject: [PATCH] spi: use macro to inline most of transaction --- src/driver/blackbox/m25p16.c | 105 ++++++++-------------- src/driver/blackbox/sdcard.c | 166 +++++++++++++++-------------------- src/driver/gyro/bmi270.c | 78 ++++++---------- src/driver/gyro/bmi323.c | 63 +++++-------- src/driver/gyro/icm42605.c | 26 +++--- src/driver/gyro/mpu6xxx.c | 26 +++--- src/driver/mcu/at32/spi.c | 46 ++++------ src/driver/mcu/stm32/spi.c | 53 +++++------ src/driver/osd/max7456.c | 67 ++++++-------- src/driver/rx/a7105.c | 45 +++++----- src/driver/rx/cc2500.c | 99 ++++++++------------- src/driver/rx/sx128x.c | 107 ++++++++++------------ src/driver/spi.c | 58 ++---------- src/driver/spi.h | 145 ++++++++++++++++++------------ 14 files changed, 435 insertions(+), 649 deletions(-) diff --git a/src/driver/blackbox/m25p16.c b/src/driver/blackbox/m25p16.c index 0c8ddad11..9316ee272 100644 --- a/src/driver/blackbox/m25p16.c +++ b/src/driver/blackbox/m25p16.c @@ -47,13 +47,9 @@ bool m25p16_is_ready() { } static uint8_t buffer[2]; - const spi_txn_segment_t segs[] = { - spi_make_seg_buffer(buffer, buffer, 2), - }; - const bool is_done = spi_seg_submit_check(&bus, segs, { + const bool is_done = spi_seg_submit_check(&bus, { spi_make_seg_buffer(buffer, buffer, 2); }, { buffer[0] = M25P16_READ_STATUS_REGISTER; - buffer[1] = 0xFF; - }); + buffer[1] = 0xFF; }); if (!is_done) { return false; } @@ -69,12 +65,9 @@ uint8_t m25p16_command(const uint8_t cmd) { m25p16_wait_for_ready(); uint8_t ret = 0; - - const spi_txn_segment_t segs[] = { - spi_make_seg_buffer(&ret, &cmd, 1), - }; - spi_seg_submit_wait(&bus, segs); - + spi_seg_submit_wait(&bus, { + spi_make_seg_buffer(&ret, &cmd, 1); + }); return ret; } @@ -82,13 +75,10 @@ uint8_t m25p16_read_command(const uint8_t cmd, uint8_t *data, const uint32_t len m25p16_wait_for_ready(); uint8_t ret = 0; - - const spi_txn_segment_t segs[] = { - spi_make_seg_buffer(&ret, &cmd, 1), - spi_make_seg_buffer(data, NULL, len), - }; - spi_seg_submit_wait(&bus, segs); - + spi_seg_submit_wait(&bus, { + spi_make_seg_buffer(&ret, &cmd, 1); + spi_make_seg_buffer(data, NULL, len); + }); return ret; } @@ -96,14 +86,11 @@ uint8_t m25p16_read_addr(const uint8_t cmd, const uint32_t addr, uint8_t *data, m25p16_wait_for_ready(); uint8_t ret = 0; - - const spi_txn_segment_t segs[] = { - spi_make_seg_buffer(&ret, &cmd, 1), - spi_make_seg_const(m25p16_addr(addr)), - spi_make_seg_buffer(data, NULL, len), - }; - spi_seg_submit_wait(&bus, segs); - + spi_seg_submit_wait(&bus, { + spi_make_seg_buffer(&ret, &cmd, 1); + spi_make_seg_const(m25p16_addr(addr)); + spi_make_seg_buffer(data, NULL, len); + }); return ret; } @@ -112,22 +99,15 @@ bool m25p16_page_program(const uint32_t addr, const uint8_t *buf, const uint32_t return false; } - { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(M25P16_WRITE_ENABLE), - }; - spi_seg_submit(&bus, segs); - } - - { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(M25P16_PAGE_PROGRAM, m25p16_addr(addr)), - spi_make_seg_buffer(NULL, buf, size), - }; - spi_seg_submit(&bus, segs); - } - + spi_seg_submit(&bus, { + spi_make_seg_const(M25P16_WRITE_ENABLE); + }); + spi_seg_submit(&bus, { + spi_make_seg_const(M25P16_PAGE_PROGRAM, m25p16_addr(addr)); + spi_make_seg_buffer(NULL, buf, size); + }); spi_txn_continue(&bus); + return true; } @@ -136,21 +116,15 @@ bool m25p16_write_addr(const uint8_t cmd, const uint32_t addr, uint8_t *data, co return false; } - { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(M25P16_WRITE_ENABLE), - }; - spi_seg_submit(&bus, segs); - } - { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(cmd, m25p16_addr(addr)), - spi_make_seg_buffer(NULL, data, len), - }; - spi_seg_submit(&bus, segs); - } - + spi_seg_submit(&bus, { + spi_make_seg_const(M25P16_WRITE_ENABLE); + }); + spi_seg_submit(&bus, { + spi_make_seg_const(cmd, m25p16_addr(addr)); + spi_make_seg_buffer(NULL, data, len); + }); spi_txn_continue(&bus); + return true; } @@ -159,19 +133,12 @@ bool m25p16_chip_erase() { return false; } - { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(M25P16_WRITE_ENABLE), - }; - spi_seg_submit(&bus, segs); - } - { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(M25P16_BULK_ERASE), - }; - spi_seg_submit(&bus, segs); - } - + spi_seg_submit(&bus, { + spi_make_seg_const(M25P16_WRITE_ENABLE); + }); + spi_seg_submit(&bus, { + spi_make_seg_const(M25P16_BULK_ERASE); + }); spi_txn_continue(&bus); return true; } diff --git a/src/driver/blackbox/sdcard.c b/src/driver/blackbox/sdcard.c index 76d7e6700..df30fd845 100644 --- a/src/driver/blackbox/sdcard.c +++ b/src/driver/blackbox/sdcard.c @@ -91,19 +91,15 @@ static bool sdcard_read_detect() { } static uint8_t sdcard_wait_non_idle() { - uint8_t ret = 0; - - const spi_txn_segment_t segs[] = { - spi_make_seg_buffer(&ret, NULL, 1), - }; - for (uint16_t timeout = 8;; timeout--) { if (timeout == 0) { return 0xFF; } - spi_seg_submit_wait(&bus, segs); - + uint8_t ret = 0; + spi_seg_submit_wait(&bus, { + spi_make_seg_buffer(&ret, NULL, 1); + }); if (ret != 0xFF) { return ret; } @@ -112,19 +108,15 @@ static uint8_t sdcard_wait_non_idle() { } static bool sdcard_wait_for_idle() { - uint8_t ret = 0; - - const spi_txn_segment_t segs[] = { - spi_make_seg_buffer(&ret, NULL, 1), - }; - for (uint16_t timeout = 8;; timeout--) { if (timeout == 0) { return 0; } - spi_seg_submit_wait(&bus, segs); - + uint8_t ret = 0; + spi_seg_submit_wait(&bus, { + spi_make_seg_buffer(&ret, NULL, 1); + }); if (ret == 0xFF) { return true; } @@ -137,34 +129,31 @@ static uint8_t sdcard_command(const uint8_t cmd, const uint32_t args) { return 0xFF; } - uint32_t count = 0; - spi_txn_segment_t segs[3] = {}; - - segs[count++] = spi_make_seg_const( - 0x40 | cmd, - args >> 24, - args >> 16, - args >> 8, - args >> 0); - - // we have to send CRC while we are still in SD Bus mode - switch (cmd) { - case SDCARD_GO_IDLE: - segs[count++] = spi_make_seg_const(0x95); - break; - case SDCARD_IF_COND: - segs[count++] = spi_make_seg_const(0x87); - break; - default: - segs[count++] = spi_make_seg_const(1); - break; - } + spi_seg_submit_wait(&bus, { + spi_make_seg_const( + 0x40 | cmd, + args >> 24, + args >> 16, + args >> 8, + args >> 0); - if (cmd == SDCARD_STOP_TRANSMISSION) { - segs[count++] = spi_make_seg_const(0xFF); - } + // we have to send CRC while we are still in SD Bus mode + switch (cmd) { + case SDCARD_GO_IDLE: + spi_make_seg_const(0x95); + break; + case SDCARD_IF_COND: + spi_make_seg_const(0x87); + break; + default: + spi_make_seg_const(1); + break; + } - spi_seg_submit_wait_ex(&bus, segs, count); + if (cmd == SDCARD_STOP_TRANSMISSION) { + spi_make_seg_const(0xFF); + } + }); return sdcard_wait_non_idle(); } @@ -176,12 +165,9 @@ static uint8_t sdcard_app_command(const uint8_t cmd, const uint32_t args) { uint32_t sdcard_read_response() { uint8_t buf[4]; - - const spi_txn_segment_t segs[] = { - spi_make_seg_buffer(buf, NULL, 4), - }; - spi_seg_submit_wait(&bus, segs); - + spi_seg_submit_wait(&bus, { + spi_make_seg_buffer(buf, NULL, 4); + }); return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3] << 0); } @@ -192,28 +178,23 @@ void sdcard_read_data(uint8_t *buf, const uint32_t size) { return; } - const spi_txn_segment_t segs[] = { - spi_make_seg_buffer(buf, NULL, size), - // two bytes CRC - spi_make_seg_const(0xFF, 0xFF), - }; - spi_seg_submit_wait(&bus, segs); + spi_seg_submit_wait(&bus, { + spi_make_seg_buffer(buf, NULL, size); + // two bytes CRC + spi_make_seg_const(0xFF, 0xFF); + }); } void sdcard_write_data(const uint8_t token, const uint8_t *buf, const uint32_t size) { - const spi_txn_segment_t segs[] = { - // start block - spi_make_seg_const(token), - - spi_make_seg_buffer(NULL, (uint8_t *)buf, size), - - // two bytes CRC - spi_make_seg_const(0xFF, 0xFF), - - // write response - spi_make_seg_const(0xFF), - }; - spi_seg_submit_wait(&bus, segs); + spi_seg_submit_wait(&bus, { + // start block + spi_make_seg_const(token); + spi_make_seg_buffer(NULL, (uint8_t *)buf, size); + // two bytes CRC + spi_make_seg_const(0xFF, 0xFF); + // write response + spi_make_seg_const(0xFF); + }); } static void sdcard_parse_csd(sdcard_csd_t *csd, uint8_t *c) { @@ -300,11 +281,10 @@ sdcard_status_t sdcard_update() { } const uint8_t buf[20] = {[RANGE_INIT(0, 20)] = 0xff}; - const spi_txn_segment_t segs[] = { - spi_make_seg_buffer(NULL, buf, 20), - }; - spi_seg_submit_continue(&bus, segs); - + spi_seg_submit(&bus, { + spi_make_seg_buffer(NULL, buf, 20); + }); + spi_txn_continue(&bus); state = SDCARD_RESET; delay_loops = 100; tries++; @@ -405,14 +385,13 @@ sdcard_status_t sdcard_update() { uint8_t token = sdcard_wait_non_idle(); if (token == 0xFE) { state = SDCARD_READ_MULTIPLE_CONTINUE; + spi_seg_submit(&bus, { + spi_make_seg_buffer(operation.buf + operation.count_done * SDCARD_PAGE_SIZE, NULL, SDCARD_PAGE_SIZE); - const spi_txn_segment_t segs[] = { - spi_make_seg_buffer(operation.buf + operation.count_done * SDCARD_PAGE_SIZE, NULL, SDCARD_PAGE_SIZE), - - // two bytes CRC - spi_make_seg_const(0xFF, 0xFF), - }; - spi_seg_submit_continue(&bus, segs); + // two bytes CRC + spi_make_seg_const(0xFF, 0xFF); + }); + spi_txn_continue(&bus); } break; } @@ -462,19 +441,19 @@ sdcard_status_t sdcard_update() { break; } - const spi_txn_segment_t segs[] = { - // token - spi_make_seg_const(0xFC), + spi_seg_submit(&bus, { + // token + spi_make_seg_const(0xFC); - spi_make_seg_buffer(NULL, operation.buf, SDCARD_PAGE_SIZE), + spi_make_seg_buffer(NULL, operation.buf, SDCARD_PAGE_SIZE); - // two bytes CRC - spi_make_seg_const(0xFF, 0xFF), + // two bytes CRC + spi_make_seg_const(0xFF, 0xFF); - // write response - spi_make_seg_const(0xFF), - }; - spi_seg_submit_continue(&bus, segs); + // write response + spi_make_seg_const(0xFF); + }); + spi_txn_continue(&bus); state = SDCARD_WRITE_MULTIPLE_VERIFY; break; @@ -491,11 +470,10 @@ sdcard_status_t sdcard_update() { } case SDCARD_WRITE_MULTIPLE_FINISH: { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(0xFD), - }; - spi_seg_submit_continue(&bus, segs); - + spi_seg_submit(&bus, { + spi_make_seg_const(0xFD); + }); + spi_txn_continue(&bus); state = SDCARD_WRITE_MULTIPLE_FINISH_WAIT; break; } diff --git a/src/driver/gyro/bmi270.c b/src/driver/gyro/bmi270.c index 0e577dc47..62726d829 100644 --- a/src/driver/gyro/bmi270.c +++ b/src/driver/gyro/bmi270.c @@ -130,10 +130,9 @@ uint8_t bmi270_read(uint8_t reg) { uint8_t buffer[3] = {reg | 0x80, 0x0, 0x0}; - const spi_txn_segment_t segs[] = { - spi_make_seg_buffer(buffer, buffer, 3), - }; - spi_seg_submit_wait(&gyro_bus, segs); + spi_seg_submit_wait(&gyro_bus, { + spi_make_seg_buffer(buffer, buffer, 3); + }); return buffer[2]; } @@ -142,57 +141,43 @@ uint16_t bmi270_read16(uint8_t reg) { spi_bus_device_reconfigure(&gyro_bus, SPI_MODE_TRAILING_EDGE, SPI_SPEED_SLOW); uint8_t buffer[4] = {reg | 0x80, 0x0, 0x0, 0x0}; - - const spi_txn_segment_t segs[] = { - spi_make_seg_buffer(buffer, buffer, 4), - }; - spi_seg_submit_wait(&gyro_bus, segs); - + spi_seg_submit_wait(&gyro_bus, { + spi_make_seg_buffer(buffer, buffer, 4); + }); return ((buffer[3] << 8) | buffer[2]); } void bmi270_write(uint8_t reg, uint8_t data, uint32_t delay) { spi_bus_device_reconfigure(&gyro_bus, SPI_MODE_TRAILING_EDGE, SPI_SPEED_SLOW); - - const spi_txn_segment_t segs[] = { - spi_make_seg_const(reg, data), - }; - spi_seg_submit_wait(&gyro_bus, segs); - + spi_seg_submit_wait(&gyro_bus, { + spi_make_seg_const(reg, data); + }); time_delay_ms(delay); } void bmi270_write16(uint8_t reg, uint16_t data, uint32_t delay) { spi_bus_device_reconfigure(&gyro_bus, SPI_MODE_TRAILING_EDGE, SPI_SPEED_SLOW); - - const spi_txn_segment_t segs[] = { - spi_make_seg_const(reg, data & 0xff, data >> 8), - }; - spi_seg_submit_wait(&gyro_bus, segs); - + spi_seg_submit_wait(&gyro_bus, { + spi_make_seg_const(reg, data & 0xff, data >> 8); + }); time_delay_ms(delay); } void bmi270_write_data(uint8_t reg, uint8_t *data, uint32_t size, uint32_t delay) { spi_bus_device_reconfigure(&gyro_bus, SPI_MODE_TRAILING_EDGE, SPI_SPEED_SLOW); - - const spi_txn_segment_t segs[] = { - spi_make_seg_const(reg), - spi_make_seg_buffer(NULL, data, size), - }; - spi_seg_submit_wait(&gyro_bus, segs); - + spi_seg_submit_wait(&gyro_bus, { + spi_make_seg_const(reg); + spi_make_seg_buffer(NULL, data, size); + }); time_delay_ms(delay); } void bmi270_read_data(uint8_t reg, uint8_t *data, uint32_t size) { spi_bus_device_reconfigure(&gyro_bus, SPI_MODE_TRAILING_EDGE, SPI_SPEED_FAST); - - const spi_txn_segment_t segs[] = { - spi_make_seg_const(reg | 0x80, 0xFF), - spi_make_seg_buffer(data, NULL, size), - }; - spi_seg_submit_wait(&gyro_bus, segs); + spi_seg_submit_wait(&gyro_bus, { + spi_make_seg_const(reg | 0x80, 0xFF); + spi_make_seg_buffer(data, NULL, size); + }); } void bmi270_read_gyro_data(gyro_data_t *data) { @@ -224,21 +209,14 @@ void bmi270_read_gyro_data(gyro_data_t *data) { data->temp = (float)((int16_t)((gyro_buf[13] << 8) | gyro_buf[12])) / 512.0 + 23.0; - { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(BMI270_REG_ACC_DATA_X_LSB | 0x80, 0xFF), - spi_make_seg_buffer(gyro_buf, NULL, 12), - }; - spi_seg_submit(&gyro_bus, segs); - } - { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(BMI270_REG_TEMPERATURE_LSB | 0x80, 0xFF), - spi_make_seg_buffer(gyro_buf + 12, NULL, 2), - }; - spi_seg_submit(&gyro_bus, segs); - } - + spi_seg_submit(&gyro_bus, { + spi_make_seg_const(BMI270_REG_ACC_DATA_X_LSB | 0x80, 0xFF); + spi_make_seg_buffer(gyro_buf, NULL, 12); + }); + spi_seg_submit(&gyro_bus, { + spi_make_seg_const(BMI270_REG_TEMPERATURE_LSB | 0x80, 0xFF); + spi_make_seg_buffer(gyro_buf + 12, NULL, 2); + }); while (!spi_txn_continue(&gyro_bus)) ; } diff --git a/src/driver/gyro/bmi323.c b/src/driver/gyro/bmi323.c index 481cb8fe6..e4a7fdd6f 100644 --- a/src/driver/gyro/bmi323.c +++ b/src/driver/gyro/bmi323.c @@ -111,10 +111,9 @@ uint8_t bmi3_read8(uint8_t reg) { uint8_t buffer[3] = {reg | 0x80, 0x0, 0x0}; - const spi_txn_segment_t segs[] = { - spi_make_seg_buffer(buffer, buffer, 3), - }; - spi_seg_submit_wait(&gyro_bus, segs); + spi_seg_submit_wait(&gyro_bus, { + spi_make_seg_buffer(buffer, buffer, 3); + }); return buffer[2]; } @@ -123,57 +122,44 @@ uint16_t bmi3_read16(uint8_t reg) { spi_bus_device_reconfigure(&gyro_bus, SPI_MODE_TRAILING_EDGE, SPI_SPEED_SLOW); uint8_t buffer[4] = {reg | 0x80, 0x0, 0x0, 0x0}; - - const spi_txn_segment_t segs[] = { - spi_make_seg_buffer(buffer, buffer, 4), - }; - spi_seg_submit_wait(&gyro_bus, segs); - + spi_seg_submit_wait(&gyro_bus, { + spi_make_seg_buffer(buffer, buffer, 4); + }); return ((buffer[3] << 8) | buffer[2]); } void bmi3_write8(uint8_t reg, uint8_t data, uint32_t delay) { spi_bus_device_reconfigure(&gyro_bus, SPI_MODE_TRAILING_EDGE, SPI_SPEED_SLOW); - - const spi_txn_segment_t segs[] = { - spi_make_seg_const(reg, data), - }; - spi_seg_submit_wait(&gyro_bus, segs); - + spi_seg_submit_wait(&gyro_bus, { + spi_make_seg_const(reg, data); + }); time_delay_ms(delay); } void bmi3_write16(uint8_t reg, uint16_t data, uint32_t delay) { spi_bus_device_reconfigure(&gyro_bus, SPI_MODE_TRAILING_EDGE, SPI_SPEED_SLOW); - - const spi_txn_segment_t segs[] = { - spi_make_seg_const(reg, data & 0xff, data >> 8), - }; - spi_seg_submit_wait(&gyro_bus, segs); - + spi_seg_submit_wait(&gyro_bus, { + spi_make_seg_const(reg, data & 0xff, data >> 8); + }); time_delay_ms(delay); } void bmi3_write_data(uint8_t reg, uint8_t *data, uint32_t size, uint32_t delay) { spi_bus_device_reconfigure(&gyro_bus, SPI_MODE_TRAILING_EDGE, SPI_SPEED_SLOW); - - const spi_txn_segment_t segs[] = { - spi_make_seg_const(reg), - spi_make_seg_buffer(NULL, data, size), - }; - spi_seg_submit_wait(&gyro_bus, segs); - + spi_seg_submit_wait(&gyro_bus, { + spi_make_seg_const(reg); + spi_make_seg_buffer(NULL, data, size); + }); time_delay_ms(delay); } void bmi3_read_data(uint8_t reg, uint8_t *data, uint32_t size) { spi_bus_device_reconfigure(&gyro_bus, SPI_MODE_TRAILING_EDGE, SPI_SPEED_FAST); - const spi_txn_segment_t segs[] = { - spi_make_seg_const(reg | 0x80, 0xFF), - spi_make_seg_buffer(data, NULL, size), - }; - spi_seg_submit_wait(&gyro_bus, segs); + spi_seg_submit_wait(&gyro_bus, { + spi_make_seg_const(reg | 0x80, 0xFF); + spi_make_seg_buffer(data, NULL, size); + }); } void bmi323_read_gyro_data(gyro_data_t *data) { @@ -205,11 +191,10 @@ void bmi323_read_gyro_data(gyro_data_t *data) { data->temp = 0; - const spi_txn_segment_t segs[] = { - spi_make_seg_const(BMI323_REG_ACC_DATA_X_LSB | 0x80, 0xFF), - spi_make_seg_buffer(gyro_buf, NULL, 12), - }; - spi_seg_submit(&gyro_bus, segs); + spi_seg_submit(&gyro_bus, { + spi_make_seg_const(BMI323_REG_ACC_DATA_X_LSB | 0x80, 0xFF); + spi_make_seg_buffer(gyro_buf, NULL, 12); + }); while (!spi_txn_continue(&gyro_bus)) ; } diff --git a/src/driver/gyro/icm42605.c b/src/driver/gyro/icm42605.c index 8bdfcc490..0246f84f8 100644 --- a/src/driver/gyro/icm42605.c +++ b/src/driver/gyro/icm42605.c @@ -89,22 +89,17 @@ uint8_t icm42605_read(uint8_t reg) { spi_bus_device_reconfigure(&gyro_bus, SPI_MODE_TRAILING_EDGE, SPI_SPEED_SLOW); uint8_t buffer[2] = {reg | 0x80, 0x00}; - - const spi_txn_segment_t segs[] = { - spi_make_seg_buffer(buffer, buffer, 2), - }; - spi_seg_submit_wait(&gyro_bus, segs); - + spi_seg_submit_wait(&gyro_bus, { + spi_make_seg_buffer(buffer, buffer, 2); + }); return buffer[1]; } void icm42605_write(uint8_t reg, uint8_t data) { spi_bus_device_reconfigure(&gyro_bus, SPI_MODE_TRAILING_EDGE, SPI_SPEED_SLOW); - - const spi_txn_segment_t segs[] = { - spi_make_seg_const(reg, data), - }; - spi_seg_submit_wait(&gyro_bus, segs); + spi_seg_submit_wait(&gyro_bus, { + spi_make_seg_const(reg, data); + }); } void icm42605_read_gyro_data(gyro_data_t *data) { @@ -121,11 +116,10 @@ void icm42605_read_gyro_data(gyro_data_t *data) { data->gyro.roll = (int16_t)((gyro_buf[10] << 8) | gyro_buf[11]); data->gyro.yaw = (int16_t)((gyro_buf[12] << 8) | gyro_buf[13]); - const spi_txn_segment_t segs[] = { - spi_make_seg_const(ICM42605_TEMP_DATA1 | 0x80), - spi_make_seg_buffer(gyro_buf, NULL, 14), - }; - spi_seg_submit(&gyro_bus, segs); + spi_seg_submit(&gyro_bus, { + spi_make_seg_const(ICM42605_TEMP_DATA1 | 0x80); + spi_make_seg_buffer(gyro_buf, NULL, 14); + }); while (!spi_txn_continue(&gyro_bus)) ; } diff --git a/src/driver/gyro/mpu6xxx.c b/src/driver/gyro/mpu6xxx.c index dcaf6bb1a..4dccd4926 100644 --- a/src/driver/gyro/mpu6xxx.c +++ b/src/driver/gyro/mpu6xxx.c @@ -93,23 +93,18 @@ uint8_t mpu6xxx_read(uint8_t reg) { spi_bus_device_reconfigure(&gyro_bus, SPI_MODE_TRAILING_EDGE, SPI_SPEED_INIT); uint8_t buffer[2] = {reg | 0x80, 0x00}; - - const spi_txn_segment_t segs[] = { - spi_make_seg_buffer(buffer, buffer, 2), - }; - spi_seg_submit_wait(&gyro_bus, segs); - + spi_seg_submit_wait(&gyro_bus, { + spi_make_seg_buffer(buffer, buffer, 2); + }); return buffer[1]; } // blocking dma write of a single register void mpu6xxx_write(uint8_t reg, uint8_t data) { spi_bus_device_reconfigure(&gyro_bus, SPI_MODE_TRAILING_EDGE, SPI_SPEED_INIT); - - const spi_txn_segment_t segs[] = { - spi_make_seg_const(reg, data), - }; - spi_seg_submit_wait(&gyro_bus, segs); + spi_seg_submit_wait(&gyro_bus, { + spi_make_seg_const(reg, data); + }); } void mpu6xxx_read_gyro_data(gyro_data_t *data) { @@ -126,11 +121,10 @@ void mpu6xxx_read_gyro_data(gyro_data_t *data) { data->gyro.roll = (int16_t)((gyro_buf[10] << 8) | gyro_buf[11]); data->gyro.yaw = (int16_t)((gyro_buf[12] << 8) | gyro_buf[13]); - const spi_txn_segment_t segs[] = { - spi_make_seg_const(MPU_RA_ACCEL_XOUT_H | 0x80), - spi_make_seg_buffer(gyro_buf, NULL, 14), - }; - spi_seg_submit(&gyro_bus, segs); + spi_seg_submit(&gyro_bus, { + spi_make_seg_const(MPU_RA_ACCEL_XOUT_H | 0x80); + spi_make_seg_buffer(gyro_buf, NULL, 14); + }); while (!spi_txn_continue(&gyro_bus)) ; } diff --git a/src/driver/mcu/at32/spi.c b/src/driver/mcu/at32/spi.c index 6c57fa63f..aa05b98af 100644 --- a/src/driver/mcu/at32/spi.c +++ b/src/driver/mcu/at32/spi.c @@ -237,54 +237,38 @@ void spi_device_init(spi_ports_t port) { interrupt_enable(dma_rx->irq, DMA_PRIORITY); } -void spi_seg_submit_wait_ex(spi_bus_device_t *bus, const spi_txn_segment_t *segs, const uint32_t count) { - spi_txn_wait(bus); +void spi_seg_transfer_start(spi_bus_device_t *bus) { + const spi_ports_t port = bus->port; + spi_txn_wait(bus); while (!spi_txn_can_send(bus, false)) ; - const spi_ports_t port = bus->port; - spi_dev[port].dma_done = false; - spi_reconfigure(bus); - spi_csn_enable(bus); spi_enable(PORT.channel, TRUE); +} - for (uint32_t i = 0; i < count; i++) { - const spi_txn_segment_t *seg = &segs[i]; - const uint32_t size = seg->size; - - const uint8_t *tx_data = NULL; - uint8_t *rx_data = NULL; +const uint8_t spi_seg_transfer_byte(spi_bus_device_t *bus, const uint8_t byte) { + const spi_ports_t port = bus->port; - if (seg->type == TXN_CONST) { - tx_data = seg->bytes; - } else { - tx_data = seg->tx_data; - rx_data = seg->rx_data; - } + while (!spi_i2s_flag_get(PORT.channel, SPI_I2S_TDBE_FLAG)) + ; - for (uint32_t j = 0; j < size; j++) { - while (!spi_i2s_flag_get(PORT.channel, SPI_I2S_TDBE_FLAG)) - ; + spi_i2s_data_transmit(PORT.channel, tx_data ? tx_data[j] : 0xFF); - spi_i2s_data_transmit(PORT.channel, tx_data ? tx_data[j] : 0xFF); + while (!spi_i2s_flag_get(PORT.channel, SPI_I2S_RDBF_FLAG)) + ; - while (!spi_i2s_flag_get(PORT.channel, SPI_I2S_RDBF_FLAG)) - ; + return spi_i2s_data_receive(PORT.channel); +} - const uint8_t ret = spi_i2s_data_receive(PORT.channel); - if (rx_data != NULL) { - rx_data[j] = ret; - } - } - } +void spi_seg_transfer_finish(spi_bus_device_t *bus) { + const spi_ports_t port = bus->port; spi_csn_disable(bus); spi_enable(PORT.channel, FALSE); - spi_dev[port].dma_done = true; } diff --git a/src/driver/mcu/stm32/spi.c b/src/driver/mcu/stm32/spi.c index 4aaf3f63b..5f7e58091 100644 --- a/src/driver/mcu/stm32/spi.c +++ b/src/driver/mcu/stm32/spi.c @@ -265,14 +265,13 @@ void spi_device_init(spi_ports_t port) { LL_DMA_EnableIT_TE(dma_rx->port, dma_rx->stream_index); } -void spi_seg_submit_wait_ex(spi_bus_device_t *bus, const spi_txn_segment_t *segs, const uint32_t count) { - spi_txn_wait(bus); +void spi_seg_transfer_start(spi_bus_device_t *bus) { + const spi_ports_t port = bus->port; + spi_txn_wait(bus); while (!spi_txn_can_send(bus, false)) ; - const spi_ports_t port = bus->port; - spi_dev[port].dma_done = false; spi_reconfigure(bus); @@ -289,43 +288,31 @@ void spi_seg_submit_wait_ex(spi_bus_device_t *bus, const spi_txn_segment_t *segs #else LL_SPI_Enable(PORT.channel); #endif +} - for (uint32_t i = 0; i < count; i++) { - const spi_txn_segment_t *seg = &segs[i]; - const uint32_t size = seg->size; - - const uint8_t *tx_data = NULL; - uint8_t *rx_data = NULL; - - if (seg->type == TXN_CONST) { - tx_data = seg->bytes; - } else { - tx_data = seg->tx_data; - rx_data = seg->rx_data; - } +const uint8_t spi_seg_transfer_byte(spi_bus_device_t *bus, const uint8_t byte) { + const spi_ports_t port = bus->port; - for (uint32_t j = 0; j < size; j++) { #if defined(STM32H7) - while (!LL_SPI_IsActiveFlag_TXP(PORT.channel)) - ; + while (!LL_SPI_IsActiveFlag_TXP(PORT.channel)) + ; #else - while (!LL_SPI_IsActiveFlag_TXE(PORT.channel)) - ; + while (!LL_SPI_IsActiveFlag_TXE(PORT.channel)) + ; #endif - LL_SPI_TransmitData8(PORT.channel, tx_data ? tx_data[j] : 0xFF); + LL_SPI_TransmitData8(PORT.channel, byte); #if defined(STM32H7) - while (!LL_SPI_IsActiveFlag_RXP(PORT.channel)) - ; + while (!LL_SPI_IsActiveFlag_RXP(PORT.channel)) + ; #else - while (!LL_SPI_IsActiveFlag_RXNE(PORT.channel)) - ; + while (!LL_SPI_IsActiveFlag_RXNE(PORT.channel)) + ; #endif - const uint8_t ret = LL_SPI_ReceiveData8(PORT.channel); - if (rx_data != NULL) { - rx_data[j] = ret; - } - } - } + return LL_SPI_ReceiveData8(PORT.channel); +} + +void spi_seg_transfer_finish(spi_bus_device_t *bus) { + const spi_ports_t port = bus->port; #if defined(STM32H7) while (!LL_SPI_IsActiveFlag_EOT(PORT.channel)) diff --git a/src/driver/osd/max7456.c b/src/driver/osd/max7456.c index e4c506563..ac4ee7b5d 100644 --- a/src/driver/osd/max7456.c +++ b/src/driver/osd/max7456.c @@ -41,24 +41,19 @@ static uint8_t max7456_dma_spi_read(uint8_t reg) { spi_bus_device_reconfigure(&bus, SPI_MODE_LEADING_EDGE, MAX7456_BAUD_RATE); uint8_t ret = 0; - - const spi_txn_segment_t segs[] = { - spi_make_seg_const(reg), - spi_make_seg_buffer(&ret, NULL, 1), - }; - spi_seg_submit_wait(&bus, segs); - + spi_seg_submit_wait(&bus, { + spi_make_seg_const(reg); + spi_make_seg_buffer(&ret, NULL, 1); + }); return ret; } // blocking dma write of a single register static void max7456_dma_spi_write(uint8_t reg, uint8_t data) { spi_bus_device_reconfigure(&bus, SPI_MODE_LEADING_EDGE, MAX7456_BAUD_RATE); - - const spi_txn_segment_t segs[] = { - spi_make_seg_const(reg, data), - }; - spi_seg_submit_wait(&bus, segs); + spi_seg_submit_wait(&bus, { + spi_make_seg_const(reg, data); + }); } static bool max7456_init_display() { @@ -131,15 +126,11 @@ static void max7456_set_system(osd_system_t sys) { static osd_system_t max7456_current_system() { static uint8_t stat = 0; - - const spi_txn_segment_t segs[] = { - spi_make_seg_const(STAT), - spi_make_seg_buffer(&stat, NULL, 1), - }; - const bool is_done = spi_seg_submit_check(&bus, segs, { + const bool is_done = spi_seg_submit_check(&bus, { + spi_make_seg_const(STAT); + spi_make_seg_buffer(&stat, NULL, 1); }, { spi_bus_device_reconfigure(&bus, SPI_MODE_LEADING_EDGE, MAX7456_BAUD_RATE); - stat = 0; - }); + stat = 0; }); if (!is_done) { return last_osd_system; } @@ -240,31 +231,23 @@ bool max7456_push_string(uint8_t attr, uint8_t x, uint8_t y, const uint8_t *data spi_bus_device_reconfigure(&bus, SPI_MODE_LEADING_EDGE, MAX7456_BAUD_RATE); - uint32_t offset = 0; - uint8_t buf[8 + size * 2]; - - buf[offset++] = DMM; - buf[offset++] = max7456_map_attr(attr); - - const uint16_t pos = x + y * MAX7456_COLS; - buf[offset++] = DMAH; - buf[offset++] = (pos >> 8) & 0xFF; - buf[offset++] = DMAL; - buf[offset++] = pos & 0xFF; - + uint8_t buf[size * 2]; for (uint8_t i = 0; i < size; i++) { - buf[offset++] = DMDI; - buf[offset++] = data[i]; + buf[i * 2 + 0] = DMDI; + buf[i * 2 + 1] = data[i]; } - // off autoincrement mode - buf[offset++] = DMDI; - buf[offset++] = 0xFF; - - const spi_txn_segment_t segs[] = { - spi_make_seg_buffer(NULL, buf, offset), - }; - spi_seg_submit_continue(&bus, segs); + const uint16_t pos = x + y * MAX7456_COLS; + spi_seg_submit(&bus, { + spi_make_seg_const( + DMM, + max7456_map_attr(attr), + DMAH, (pos >> 8) & 0xFF, + DMAL, pos & 0xFF); + spi_make_seg_buffer(NULL, buf, size * 2); + spi_make_seg_const(DMDI, 0xFF); // off autoincrement mode + }); + spi_txn_continue(&bus); return true; } diff --git a/src/driver/rx/a7105.c b/src/driver/rx/a7105.c index 4407444f4..f96b9d49f 100644 --- a/src/driver/rx/a7105.c +++ b/src/driver/rx/a7105.c @@ -23,38 +23,33 @@ void a7105_handle_exti(bool pin_state) { } void a7105_write_reg(a7105_reg_t reg, uint8_t data) { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(reg, data), - }; - spi_seg_submit_continue(&bus, segs); + spi_seg_submit(&bus, { + spi_make_seg_const(reg, data); + }); + spi_txn_continue(&bus); } static void a7105_write_multi(uint8_t reg, const uint8_t *data, uint8_t len) { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(reg), - spi_make_seg_buffer(NULL, data, len), - }; - spi_seg_submit_wait(&bus, segs); + spi_seg_submit_wait(&bus, { + spi_make_seg_const(reg); + spi_make_seg_buffer(NULL, data, len); + }); } uint8_t a7105_read_reg(a7105_reg_t reg) { uint8_t ret = 0; - - const spi_txn_segment_t segs[] = { - spi_make_seg_const(reg | 0x40), - spi_make_seg_buffer(&ret, NULL, 1), - }; - spi_seg_submit_wait(&bus, segs); - + spi_seg_submit_wait(&bus, { + spi_make_seg_const(reg | 0x40); + spi_make_seg_buffer(&ret, NULL, 1); + }); return ret; } static void a7105_read_multi(uint8_t reg, uint8_t *result, uint8_t len) { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(reg), - spi_make_seg_buffer(result, NULL, len), - }; - spi_seg_submit_wait(&bus, segs); + spi_seg_submit_wait(&bus, { + spi_make_seg_const(reg); + spi_make_seg_buffer(result, NULL, len); + }); } void a7105_strobe(a7105_strobe_t address) { @@ -66,10 +61,10 @@ void a7105_strobe(a7105_strobe_t address) { exti_interrupt_disable(target.rx_spi.exti); } - const spi_txn_segment_t segs[] = { - spi_make_seg_const(address), - }; - spi_seg_submit_continue(&bus, segs); + spi_seg_submit(&bus, { + spi_make_seg_const(address); + }); + spi_txn_continue(&bus); } void a7105_read_fifo(uint8_t *data, uint8_t num) { diff --git a/src/driver/rx/cc2500.c b/src/driver/rx/cc2500.c index 8080b4dc4..2deb3b5b8 100644 --- a/src/driver/rx/cc2500.c +++ b/src/driver/rx/cc2500.c @@ -75,10 +75,10 @@ uint8_t cc2500_read_gdo0() { } void cc2500_strobe(uint8_t address) { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(address), - }; - spi_seg_submit_continue(&bus, segs); + spi_seg_submit(&bus, { + spi_make_seg_const(address); + }); + spi_txn_continue(&bus); } void cc2500_strobe_sync(uint8_t address) { @@ -88,72 +88,54 @@ void cc2500_strobe_sync(uint8_t address) { uint8_t cc2500_get_status() { uint8_t status = 0; - - const spi_txn_segment_t segs[] = { - spi_make_seg_buffer(&status, NULL, 1), - }; - spi_seg_submit_wait(&bus, segs); - + spi_seg_submit_wait(&bus, { + spi_make_seg_buffer(&status, NULL, 1); + }); return status; } void cc2500_write_reg(uint8_t reg, uint8_t data) { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(reg | CC2500_WRITE_SINGLE, data), - }; - spi_seg_submit_continue(&bus, segs); + spi_seg_submit(&bus, { + spi_make_seg_const(reg | CC2500_WRITE_SINGLE, data); + }); + spi_txn_continue(&bus); } uint8_t cc2500_read_reg(uint8_t reg) { uint8_t ret = 0; - - const spi_txn_segment_t segs[] = { - spi_make_seg_const(reg | CC2500_READ_SINGLE), - spi_make_seg_buffer(&ret, NULL, 1), - }; - spi_seg_submit_wait(&bus, segs); - + spi_seg_submit_wait(&bus, { + spi_make_seg_const(reg | CC2500_READ_SINGLE); + spi_make_seg_buffer(&ret, NULL, 1); + }); return ret; } static uint8_t cc2500_read_multi(uint8_t reg, uint8_t *result, uint8_t len) { - const spi_txn_segment_t segs[] = { - spi_make_seg_buffer(®, ®, 1), - spi_make_seg_buffer(result, NULL, len), - }; - spi_seg_submit_wait(&bus, segs); - + spi_seg_submit_wait(&bus, { + spi_make_seg_buffer(®, ®, 1); + spi_make_seg_buffer(result, NULL, len); + }); return reg; } static void cc2500_write_multi(uint8_t reg, uint8_t *data, uint8_t len) { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(reg), - spi_make_seg_buffer(NULL, data, len), - }; - spi_seg_submit_wait(&bus, segs); + spi_seg_submit_wait(&bus, { + spi_make_seg_const(reg); + spi_make_seg_buffer(NULL, data, len); + }); } void cc2500_set_channel(uint8_t channel, uint8_t *cal_data) { - { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(CC2500_SIDLE), - }; - spi_seg_submit(&bus, segs); - } - { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(CC2500_FSCAL3 | CC2500_WRITE_BURST), - spi_make_seg_buffer(NULL, cal_data, 3), - }; - spi_seg_submit(&bus, segs); - } - { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(CC2500_CHANNR | CC2500_WRITE_SINGLE, channel), - }; - spi_seg_submit(&bus, segs); - } + spi_seg_submit(&bus, { + spi_make_seg_const(CC2500_SIDLE); + }); + spi_seg_submit(&bus, { + spi_make_seg_const(CC2500_FSCAL3 | CC2500_WRITE_BURST); + spi_make_seg_buffer(NULL, cal_data, 3); + }); + spi_seg_submit(&bus, { + spi_make_seg_const(CC2500_CHANNR | CC2500_WRITE_SINGLE, channel); + }); spi_txn_continue(&bus); } @@ -171,15 +153,12 @@ uint8_t cc2500_packet_size() { uint8_t len1 = 0; uint8_t len2 = 0; - { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(CC2500_RXBYTES | CC2500_READ_SINGLE), - spi_make_seg_buffer(&len1, NULL, 1), - spi_make_seg_const(CC2500_RXBYTES | CC2500_READ_SINGLE), - spi_make_seg_buffer(&len2, NULL, 1), - }; - spi_seg_submit_wait(&bus, segs); - } + spi_seg_submit_wait(&bus, { + spi_make_seg_const(CC2500_RXBYTES | CC2500_READ_SINGLE); + spi_make_seg_buffer(&len1, NULL, 1); + spi_make_seg_const(CC2500_RXBYTES | CC2500_READ_SINGLE); + spi_make_seg_buffer(&len2, NULL, 1); + }); // valid len found? if (len1 == len2) { diff --git a/src/driver/rx/sx128x.c b/src/driver/rx/sx128x.c index 7efd04661..fd0afdcb9 100644 --- a/src/driver/rx/sx128x.c +++ b/src/driver/rx/sx128x.c @@ -100,8 +100,7 @@ static bool sx128x_poll_for_not_busy() { return true; } -#define read_command_txn(cmd, data, size) \ - spi_make_seg_const(cmd, 0x0), spi_make_seg_buffer(data, NULL, size) +#define read_command_txn(cmd, data, size) static void sx128x_set_dio0_active(void *arg) { packet_time_us = time_micros(); @@ -109,28 +108,21 @@ static void sx128x_set_dio0_active(void *arg) { } static void sx128x_read_buffer(void *arg) { - { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(SX1280_RADIO_READ_BUFFER, buffer_status[1], 0x00), - spi_make_seg_buffer((uint8_t *)rx_spi_packet, NULL, payload_len), - }; - spi_seg_submit(&bus, segs); - } - { - const spi_txn_segment_t segs[] = { - read_command_txn(SX1280_RADIO_GET_PACKETSTATUS, (uint8_t *)packet_status, 2), - }; - spi_seg_submit(&bus, segs, .done_fn = sx128x_set_dio0_active); - } + spi_seg_submit(&bus, { + spi_make_seg_const(SX1280_RADIO_READ_BUFFER, buffer_status[1], 0x00); + spi_make_seg_buffer((uint8_t *)rx_spi_packet, NULL, payload_len); + }); + spi_seg_submit(&bus, { + spi_make_seg_const(SX1280_RADIO_GET_PACKETSTATUS, 0x0); + spi_make_seg_buffer((uint8_t *)packet_status, NULL, 2); }, .done_fn = sx128x_set_dio0_active); } static void sx128x_handle_irq_status(void *arg) { const uint16_t irq = ((irq_status & 0xFF) << 8 | ((irq_status >> 8) & 0xFF)); if ((irq & SX1280_IRQ_RX_DONE)) { - const spi_txn_segment_t segs[] = { - read_command_txn(SX1280_RADIO_GET_RXBUFFERSTATUS, buffer_status, 2), - }; - spi_seg_submit(&bus, segs, .done_fn = sx128x_read_buffer); + spi_seg_submit(&bus, { + spi_make_seg_const(SX1280_RADIO_GET_RXBUFFERSTATUS, 0x0); + spi_make_seg_buffer(buffer_status, NULL, 2); }, .done_fn = sx128x_read_buffer); } else if ((irq & SX1280_IRQ_TX_DONE)) { sx128x_set_mode_async(SX1280_MODE_RX); } @@ -158,21 +150,14 @@ void sx128x_handle_dio0_exti(bool level) { if (!level) return; - { - const spi_txn_segment_t segs[] = { - read_command_txn(SX1280_RADIO_GET_IRQSTATUS, (uint8_t *)&irq_status, 2), - }; - spi_seg_submit(&bus, segs); - } - { - const spi_txn_segment_t segs[] = { - spi_make_seg_const( - SX1280_RADIO_CLR_IRQSTATUS, - (uint8_t)(((uint16_t)SX1280_IRQ_RADIO_ALL >> 8) & 0x00FF), - (uint8_t)((uint16_t)SX1280_IRQ_RADIO_ALL & 0x00FF)), - }; - spi_seg_submit(&bus, segs, .done_fn = sx128x_handle_irq_status); - } + spi_seg_submit(&bus, { + spi_make_seg_const(SX1280_RADIO_GET_IRQSTATUS, 0x0); + spi_make_seg_buffer((uint8_t *)&irq_status, NULL, 2); + }); + spi_seg_submit(&bus, { spi_make_seg_const( + SX1280_RADIO_CLR_IRQSTATUS, + (uint8_t)(((uint16_t)SX1280_IRQ_RADIO_ALL >> 8) & 0x00FF), + (uint8_t)((uint16_t)SX1280_IRQ_RADIO_ALL & 0x00FF)); }, .done_fn = sx128x_handle_irq_status); spi_txn_continue(&bus); } @@ -198,14 +183,13 @@ uint16_t sx128x_read_dio0() { } void sx128x_read_register_burst(const uint16_t reg, uint8_t *data, const uint8_t size) { - const spi_txn_segment_t segs[] = { - spi_make_seg_const((SX1280_RADIO_READ_REGISTER), - ((reg & 0xFF00) >> 8), - (reg & 0x00FF), - 0x00), - spi_make_seg_buffer(data, NULL, size), - }; - spi_seg_submit(&bus, segs); + spi_seg_submit(&bus, { + spi_make_seg_const((SX1280_RADIO_READ_REGISTER), + ((reg & 0xFF00) >> 8), + (reg & 0x00FF), + 0x00); + spi_make_seg_buffer(data, NULL, size); + }); } uint8_t sx128x_read_register(const uint16_t reg) { @@ -216,13 +200,12 @@ uint8_t sx128x_read_register(const uint16_t reg) { } void sx128x_write_register_burst(const uint16_t reg, const uint8_t *data, const uint8_t size) { - const spi_txn_segment_t segs[] = { - spi_make_seg_const((uint8_t)SX1280_RADIO_WRITE_REGISTER, - ((reg & 0xFF00) >> 8), - (reg & 0x00FF)), - spi_make_seg_buffer(NULL, data, size), - }; - spi_seg_submit(&bus, segs); + spi_seg_submit(&bus, { + spi_make_seg_const((uint8_t)SX1280_RADIO_WRITE_REGISTER, + ((reg & 0xFF00) >> 8), + (reg & 0x00FF)); + spi_make_seg_buffer(NULL, data, size); + }); } void sx128x_write_register(const uint16_t reg, const uint8_t val) { @@ -230,18 +213,17 @@ void sx128x_write_register(const uint16_t reg, const uint8_t val) { } void sx128x_read_command_burst(const sx128x_commands_t cmd, uint8_t *data, const uint8_t size) { - const spi_txn_segment_t segs[] = { - read_command_txn(cmd, data, size), - }; - spi_seg_submit(&bus, segs); + spi_seg_submit(&bus, { + spi_make_seg_const(cmd, 0x0); + spi_make_seg_buffer(data, NULL, size); + }); } void sx128x_write_command_burst(const sx128x_commands_t cmd, const uint8_t *data, const uint8_t size) { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(cmd), - spi_make_seg_buffer(NULL, data, size), - }; - spi_seg_submit(&bus, segs); + spi_seg_submit(&bus, { + spi_make_seg_const(cmd); + spi_make_seg_buffer(NULL, data, size); + }); } void sx128x_write_command(const sx128x_commands_t cmd, const uint8_t val) { @@ -249,11 +231,10 @@ void sx128x_write_command(const sx128x_commands_t cmd, const uint8_t val) { } void sx128x_write_tx_buffer(const uint8_t offset, const volatile uint8_t *data, const uint8_t size) { - const spi_txn_segment_t segs[] = { - spi_make_seg_const(SX1280_RADIO_WRITE_BUFFER, offset), - spi_make_seg_buffer(NULL, (uint8_t *)data, size), - }; - spi_seg_submit(&bus, segs); + spi_seg_submit(&bus, { + spi_make_seg_const(SX1280_RADIO_WRITE_BUFFER, offset); + spi_make_seg_buffer(NULL, (uint8_t *)data, size); + }); } void sx128x_set_mode_async(const sx128x_modes_t mode) { diff --git a/src/driver/spi.c b/src/driver/spi.c index 655cae506..ce90761b6 100644 --- a/src/driver/spi.c +++ b/src/driver/spi.c @@ -18,17 +18,21 @@ extern void spi_device_init(spi_ports_t port); extern void spi_reconfigure(spi_bus_device_t *bus); extern void spi_dma_transfer_begin(spi_ports_t port, uint8_t *buffer, uint32_t length); -static inline __attribute__((always_inline)) spi_txn_t *spi_txn_pop(spi_bus_device_t *bus) { +spi_txn_t *spi_txn_pop(spi_bus_device_t *bus) { ATOMIC_BLOCK_ALL { for (uint32_t i = 0; i < SPI_TXN_MAX; i++) { if (txn_pool[i].status == TXN_IDLE) { spi_txn_t *txn = &txn_pool[i]; txn->status = TXN_WAITING; txn->buffer = txn_buffers[i]; + txn->bus = (bus); + txn->size = 0; + txn->flags = 0; return txn; } } } + failloop(FAILLOOP_SPI); return NULL; } @@ -89,58 +93,6 @@ bool spi_txn_continue_port(spi_ports_t port) { return true; } -void spi_seg_submit_ex(spi_bus_device_t *bus, const spi_txn_opts_t opts) { - spi_txn_t *txn = spi_txn_pop(bus); - if (txn == NULL) { - failloop(FAILLOOP_SPI); - } - - txn->bus = bus; - txn->size = 0; - txn->flags = 0; - txn->segment_count = opts.seg_count; - txn->done_fn = opts.done_fn; - txn->done_fn_arg = opts.done_fn_arg; - - for (uint32_t i = 0; i < opts.seg_count; i++) { - const spi_txn_segment_t *seg = &opts.segs[i]; - spi_txn_segment_t *txn_seg = &txn->segments[i]; - - switch (seg->type) { - case TXN_CONST: - txn_seg->rx_data = NULL; - txn_seg->tx_data = NULL; - memcpy(txn->buffer + txn->size, seg->bytes, seg->size); - break; - - case TXN_BUFFER: - txn_seg->tx_data = NULL; - txn_seg->rx_data = seg->rx_data; - if (seg->tx_data) { - memcpy(txn->buffer + txn->size, seg->tx_data, seg->size); - } else { - memset(txn->buffer + txn->size, 0xFF, seg->size); - } - break; - } - - if (txn_seg->rx_data) { - txn->flags |= TXN_DELAYED_RX; - } - - txn_seg->size = seg->size; - txn->size += seg->size; - } - - ATOMIC_BLOCK_ALL { - spi_device_t *dev = &spi_dev[bus->port]; - const uint8_t head = (dev->txn_head + 1) % SPI_TXN_MAX; - txn->status = TXN_READY; - dev->txns[head] = txn; - dev->txn_head = head; - } -} - // only called from dma isr void spi_txn_finish(spi_ports_t port) { spi_device_t *dev = &spi_dev[port]; diff --git a/src/driver/spi.h b/src/driver/spi.h index b35ea6a79..92752b3a3 100644 --- a/src/driver/spi.h +++ b/src/driver/spi.h @@ -2,10 +2,12 @@ #include #include +#include #include "core/project.h" #include "driver/dma.h" #include "driver/gpio.h" +#include "driver/interrupt.h" #include "driver/rcc.h" typedef enum { @@ -25,30 +27,12 @@ typedef struct { #define SPI_TXN_MAX 32 #define SPI_TXN_SEG_MAX 8 -typedef enum { - TXN_CONST, - TXN_BUFFER, -} spi_txn_segment_type_t; - typedef struct { - spi_txn_segment_type_t type; - union { - struct { - uint8_t bytes[8]; - }; - struct { - const uint8_t *tx_data; - uint8_t *rx_data; - }; - }; + uint8_t *rx_data; + uint32_t size; } spi_txn_segment_t; -#define spi_make_seg_const(_bytes...) \ - (spi_txn_segment_t) { .type = TXN_CONST, .bytes = {_bytes}, .size = sizeof((uint8_t[]){_bytes}) } -#define spi_make_seg_buffer(_rx_data, _tx_data, _size) \ - (spi_txn_segment_t) { .type = TXN_BUFFER, .rx_data = (_rx_data), .tx_data = (_tx_data), .size = (_size) } - struct spi_bus_device; typedef enum { @@ -83,9 +67,6 @@ typedef struct { typedef struct { spi_txn_done_fn_t done_fn; void *done_fn_arg; - - const spi_txn_segment_t *segs; - uint32_t seg_count; } spi_txn_opts_t; typedef struct spi_bus_device { @@ -119,10 +100,12 @@ extern const spi_port_def_t spi_port_defs[SPI_PORT_MAX]; void spi_bus_device_init(const spi_bus_device_t *bus); void spi_txn_wait(spi_bus_device_t *bus); +spi_txn_t *spi_txn_pop(spi_bus_device_t *bus); bool spi_txn_continue_port(spi_ports_t port); -void spi_seg_submit_ex(spi_bus_device_t *bus, const spi_txn_opts_t opts); -void spi_seg_submit_wait_ex(spi_bus_device_t *bus, const spi_txn_segment_t *segs, const uint32_t count); +void spi_seg_transfer_start(spi_bus_device_t *bus); +const uint8_t spi_seg_transfer_byte(spi_bus_device_t *bus, const uint8_t byte); +void spi_seg_transfer_finish(spi_bus_device_t *bus); static inline void spi_csn_enable(spi_bus_device_t *bus) { gpio_pin_reset(bus->nss); } static inline void spi_csn_disable(spi_bus_device_t *bus) { gpio_pin_set(bus->nss); } @@ -144,41 +127,87 @@ static inline bool spi_txn_ready(spi_bus_device_t *bus) { return dev->txn_head == dev->txn_tail; } -#define spi_seg_submit_wait(_bus, _segs) \ - { \ - static_assert(__builtin_types_compatible_p(spi_txn_segment_t[], typeof(_segs)), "spi segment not const array"); \ - const uint32_t count = sizeof(_segs) / sizeof(spi_txn_segment_t); \ - static_assert(count < SPI_TXN_SEG_MAX, "spi segment count > max"); \ - spi_seg_submit_wait_ex(_bus, _segs, count); \ +#define spi_make_seg_const(_bytes...) \ + { \ + const uint8_t __bytes__[] = {_bytes}; \ + const uint32_t __size__ = sizeof(__bytes__); \ + if (__is_async__) { \ + spi_txn_segment_t *txn_seg = &txn->segments[txn->segment_count]; \ + txn_seg->rx_data = NULL; \ + for (uint32_t __i__ = 0; __i__ < __size__; __i__++) \ + txn->buffer[txn->size + __i__] = __bytes__[__i__]; \ + txn->size += (txn_seg->size = __size__); \ + txn->segment_count++; \ + } else { \ + for (uint32_t __i__ = 0; __i__ < __size__; __i__++) \ + spi_seg_transfer_byte(__bus__, __bytes__[__i__]); \ + } \ + } +#define spi_make_seg_buffer(_rx_data, _tx_data, _size) \ + if (__is_async__) { \ + spi_txn_segment_t *txn_seg = &txn->segments[txn->segment_count]; \ + txn_seg->rx_data = _rx_data; \ + if (txn_seg->rx_data) \ + txn->flags |= TXN_DELAYED_RX; \ + const uint8_t *__tx_data__ = _tx_data; \ + for (uint32_t __i__ = 0; __i__ < (_size); __i__++) \ + txn->buffer[txn->size + __i__] = __tx_data__ ? __tx_data__[__i__] : 0xFF; \ + txn->size += (txn_seg->size = (_size)); \ + txn->segment_count++; \ + } else { \ + const uint8_t *__tx_data__ = _tx_data; \ + uint8_t *__rx_data__ = _rx_data; \ + for (uint32_t __i__ = 0; __i__ < (_size); __i__++) { \ + const uint8_t res = spi_seg_transfer_byte(__bus__, __tx_data__ ? __tx_data__[__i__] : 0xFF); \ + if (__rx_data__) \ + __rx_data__[__i__] = res; \ + } \ + } +#define spi_seg_submit_wait(_bus, _segs) \ + { \ + const bool __is_async__ = false; \ + spi_txn_t *txn = NULL; \ + spi_bus_device_t *__bus__ = _bus; \ + spi_seg_transfer_start(__bus__); \ + _segs; \ + spi_seg_transfer_finish(__bus__); \ } -#define spi_seg_submit(_bus, _segs, ...) \ - { \ - static_assert(__builtin_types_compatible_p(spi_txn_segment_t[], typeof(_segs)), "spi segment not const array"); \ - const uint32_t count = sizeof(_segs) / sizeof(spi_txn_segment_t); \ - static_assert(count < SPI_TXN_SEG_MAX, "spi segment count > max"); \ - spi_seg_submit_ex(_bus, (spi_txn_opts_t){.segs = _segs, .seg_count = count, __VA_ARGS__}); \ +#define spi_seg_submit(_bus, _segs, _opts...) \ + { \ + const bool __is_async__ = true; \ + const spi_txn_opts_t __opts__ = {_opts}; \ + spi_bus_device_t *__bus__ = _bus; \ + spi_txn_t *txn = spi_txn_pop((_bus)); \ + txn->segment_count = 0; \ + txn->done_fn = __opts__.done_fn; \ + txn->done_fn_arg = __opts__.done_fn_arg; \ + _segs; \ + ATOMIC_BLOCK_ALL { \ + spi_device_t *dev = &spi_dev[(_bus)->port]; \ + const uint8_t head = (dev->txn_head + 1) % SPI_TXN_MAX; \ + txn->status = TXN_READY; \ + dev->txns[head] = txn; \ + dev->txn_head = head; \ + } \ } -#define spi_seg_submit_continue(_bus, _segs, ...) ({ \ - spi_seg_submit(_bus, _segs, __VA_ARGS__); \ - spi_txn_continue(_bus); \ -}) static inline void spi_txn_set_done(void *arg) { *((bool *)arg) = true; } -#define spi_seg_submit_check(_bus, _segs, ...) \ - ({ \ - static volatile bool __did_submit__ = false; \ - static volatile bool __is_done__ = false; \ - if (!__did_submit__) { \ - __VA_ARGS__; \ - spi_seg_submit_continue(_bus, _segs, \ - .done_fn = spi_txn_set_done, \ - .done_fn_arg = (void *)&__is_done__); \ - __did_submit__ = true; \ - } \ - const bool temp = __is_done__; \ - if (__is_done__) { \ - __did_submit__ = false; \ - __is_done__ = false; \ - } \ - temp; \ +#define spi_seg_submit_check(_bus, _segs, ...) \ + ({ \ + static volatile bool __did_submit__ = false; \ + static volatile bool __is_done__ = false; \ + if (!__did_submit__) { \ + __VA_ARGS__; \ + spi_seg_submit(_bus, _segs, \ + .done_fn = spi_txn_set_done, \ + .done_fn_arg = (void *)&__is_done__); \ + spi_txn_continue(_bus); \ + __did_submit__ = true; \ + } \ + const bool temp = __is_done__; \ + if (__is_done__) { \ + __did_submit__ = false; \ + __is_done__ = false; \ + } \ + temp; \ })