mirror of
https://github.com/openmv/openmv.git
synced 2025-09-26 23:09:13 +08:00
Merge pull request #2714 from openmv/fix_alif_spi
Some checks are pending
🔥 Firmware Build / build-firmware (ARDUINO_GIGA) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_NANO_33_BLE_SENSE) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_NANO_RP2040_CONNECT) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_NICLA_VISION) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_PORTENTA_H7) (push) Waiting to run
🔥 Firmware Build / build-firmware (DOCKER) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV2) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV3) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV4) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV4P) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMVPT) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV_AE3) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV_RT1060) (push) Waiting to run
🔥 Firmware Build / code-size-report (push) Blocked by required conditions
🔥 Firmware Build / stable-release (push) Blocked by required conditions
🔥 Firmware Build / development-release (push) Blocked by required conditions
Some checks are pending
🔥 Firmware Build / build-firmware (ARDUINO_GIGA) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_NANO_33_BLE_SENSE) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_NANO_RP2040_CONNECT) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_NICLA_VISION) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_PORTENTA_H7) (push) Waiting to run
🔥 Firmware Build / build-firmware (DOCKER) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV2) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV3) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV4) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV4P) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMVPT) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV_AE3) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV_RT1060) (push) Waiting to run
🔥 Firmware Build / code-size-report (push) Blocked by required conditions
🔥 Firmware Build / stable-release (push) Blocked by required conditions
🔥 Firmware Build / development-release (push) Blocked by required conditions
ports/alif: Implement spi_transfer with poll and timeout.
This commit is contained in:
commit
a95ce57e16
@ -84,7 +84,11 @@ static void spi_switch_mode(py_display_obj_t *self, int bits, bool dma) {
|
|||||||
spi_config.datasize = bits;
|
spi_config.datasize = bits;
|
||||||
spi_config.bus_mode = OMV_SPI_BUS_TX;
|
spi_config.bus_mode = OMV_SPI_BUS_TX;
|
||||||
spi_config.nss_enable = false;
|
spi_config.nss_enable = false;
|
||||||
|
#if OMV_SPI_NO_DMA
|
||||||
|
spi_config.dma_flags = 0;
|
||||||
|
#else
|
||||||
spi_config.dma_flags = dma ? OMV_SPI_DMA_NORMAL : 0;
|
spi_config.dma_flags = dma ? OMV_SPI_DMA_NORMAL : 0;
|
||||||
|
#endif
|
||||||
omv_spi_init(&self->spi_bus, &spi_config);
|
omv_spi_init(&self->spi_bus, &spi_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,10 +125,14 @@ struct { \
|
|||||||
#define OMV_SPI_MAX_8BIT_XFER (32768U - 32U)
|
#define OMV_SPI_MAX_8BIT_XFER (32768U - 32U)
|
||||||
#define OMV_SPI_MAX_16BIT_XFER (32768U - 16U)
|
#define OMV_SPI_MAX_16BIT_XFER (32768U - 16U)
|
||||||
#define OMV_SPI_MAX_TIMEOUT (0xFFFFFFFF)
|
#define OMV_SPI_MAX_TIMEOUT (0xFFFFFFFF)
|
||||||
|
#define OMV_SPI_NO_DMA (1)
|
||||||
|
|
||||||
#define OMV_SPI_PORT_BITS \
|
#define OMV_SPI_PORT_BITS \
|
||||||
struct { \
|
struct { \
|
||||||
SPI_Type *inst; \
|
SPI_Type *inst; \
|
||||||
bool is_lp; \
|
bool is_lp; \
|
||||||
|
uint32_t spi_mode; \
|
||||||
|
uint32_t bus_mode; \
|
||||||
|
uint8_t datasize; \
|
||||||
};
|
};
|
||||||
#endif // __OMV_PORTCONFIG_H__
|
#endif // __OMV_PORTCONFIG_H__
|
||||||
|
@ -34,7 +34,9 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "omv_boardconfig.h"
|
#include "omv_boardconfig.h"
|
||||||
|
|
||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
|
||||||
#include "spi.h"
|
#include "spi.h"
|
||||||
#include "alif_hal.h"
|
#include "alif_hal.h"
|
||||||
@ -76,31 +78,84 @@ static const omv_spi_descr_t omv_spi_descr_all[] = {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
int omv_spi_transfer_start(omv_spi_t *spi, omv_spi_transfer_t *xfer) {
|
static int omv_spi_poll_flag(SPI_Type *spi, uint32_t flag, uint32_t timeout) {
|
||||||
|
mp_uint_t tick_start = mp_hal_ticks_ms();
|
||||||
const omv_spi_descr_t *spi_descr = &omv_spi_descr_all[spi->id];
|
while (!(spi->SPI_SR & flag)) {
|
||||||
|
if (mp_hal_ticks_ms() - tick_start >= timeout) {
|
||||||
if (xfer->flags & OMV_SPI_XFER_BLOCKING) {
|
return -1;
|
||||||
spi_transfer_t spi_xfer = { 0 };
|
|
||||||
|
|
||||||
spi_xfer.tx_buff = xfer->txbuf;
|
|
||||||
spi_xfer.tx_total_cnt = xfer->size;
|
|
||||||
|
|
||||||
spi_xfer.rx_buff = xfer->rxbuf;
|
|
||||||
spi_xfer.rx_total_cnt = xfer->size;
|
|
||||||
|
|
||||||
spi_xfer.tx_default_val = 0xFF;
|
|
||||||
spi_xfer.tx_default_enable = true;
|
|
||||||
|
|
||||||
spi_xfer.mode = SPI_TMOD_TX_AND_RX;
|
|
||||||
if (!spi_descr->is_lp) {
|
|
||||||
spi_transfer_blocking(spi->inst, &spi_xfer);
|
|
||||||
} else {
|
|
||||||
lpspi_transfer_blocking(spi->inst, &spi_xfer);
|
|
||||||
}
|
}
|
||||||
|
mp_event_handle_nowait();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int omv_spi_transfer_start(omv_spi_t *spi, omv_spi_transfer_t *xfer) {
|
||||||
|
if (xfer->flags & OMV_SPI_XFER_BLOCKING) {
|
||||||
|
volatile uint32_t *dr = spi->inst->SPI_DR;
|
||||||
|
spi_set_tmod(spi->inst, SPI_TMOD_TX_AND_RX);
|
||||||
|
|
||||||
|
size_t tx_sent = 0;
|
||||||
|
size_t rx_received = 0;
|
||||||
|
|
||||||
|
// FIFO depth is 16 words
|
||||||
|
const size_t rx_threshold = (SPI_RX_FIFO_DEPTH - 1);
|
||||||
|
|
||||||
|
while (rx_received < xfer->size) {
|
||||||
|
// Fill TX FIFO as much as possible without causing RX overflow
|
||||||
|
while (tx_sent < xfer->size &&
|
||||||
|
(tx_sent - rx_received) < rx_threshold &&
|
||||||
|
(spi->inst->SPI_SR & SPI_SR_TFNF)) {
|
||||||
|
|
||||||
|
// Send data
|
||||||
|
if (xfer->txbuf == NULL) {
|
||||||
|
*dr = 0xFFFFFFFFU;
|
||||||
|
} else if (spi->datasize > 16) {
|
||||||
|
*dr = ((uint32_t *) xfer->txbuf)[tx_sent];
|
||||||
|
} else if (spi->datasize > 8) {
|
||||||
|
*dr = ((uint16_t *) xfer->txbuf)[tx_sent];
|
||||||
|
} else {
|
||||||
|
*dr = ((uint8_t *) xfer->txbuf)[tx_sent];
|
||||||
|
}
|
||||||
|
tx_sent++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Receive available data
|
||||||
|
while (rx_received < tx_sent &&
|
||||||
|
(spi->inst->SPI_SR & SPI_SR_RFNE)) {
|
||||||
|
|
||||||
|
if (xfer->rxbuf == NULL) {
|
||||||
|
(void) *dr;
|
||||||
|
} else if (spi->datasize > 16) {
|
||||||
|
((uint32_t *) xfer->rxbuf)[rx_received] = *dr;
|
||||||
|
} else if (spi->datasize > 8) {
|
||||||
|
((uint16_t *) xfer->rxbuf)[rx_received] = *dr;
|
||||||
|
} else {
|
||||||
|
((uint8_t *) xfer->rxbuf)[rx_received] = *dr;
|
||||||
|
}
|
||||||
|
rx_received++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're not making progress, use blocking wait
|
||||||
|
if (tx_sent < xfer->size && (tx_sent - rx_received) >= rx_threshold) {
|
||||||
|
// Wait for RX data to free up space
|
||||||
|
if (omv_spi_poll_flag(spi->inst, SPI_SR_RFNE, xfer->timeout) == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (tx_sent == xfer->size && rx_received < tx_sent) {
|
||||||
|
// All data sent, wait for remaining RX data
|
||||||
|
if (omv_spi_poll_flag(spi->inst, SPI_SR_RFNE, xfer->timeout) == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (tx_sent < xfer->size) {
|
||||||
|
// Wait for space in the TX FIFO
|
||||||
|
if (omv_spi_poll_flag(spi->inst, SPI_SR_TFNF, xfer->timeout) == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,6 +171,9 @@ int omv_spi_init(omv_spi_t *spi, omv_spi_config_t *config) {
|
|||||||
spi->inst = spi_descr->inst;
|
spi->inst = spi_descr->inst;
|
||||||
spi->cs = spi_descr->cs;
|
spi->cs = spi_descr->cs;
|
||||||
spi->is_lp = spi_descr->is_lp;
|
spi->is_lp = spi_descr->is_lp;
|
||||||
|
spi->spi_mode = config->spi_mode;
|
||||||
|
spi->bus_mode = config->bus_mode;
|
||||||
|
spi->datasize = config->datasize;
|
||||||
|
|
||||||
if (spi->inst == NULL) {
|
if (spi->inst == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user