Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
9 changes: 6 additions & 3 deletions drivers/include/drivers/SPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,12 @@ const use_gpio_ssel_t use_gpio_ssel;
* applies to receiving data, so be sure to check examples in the datasheet to determine what frame
* size to use and whether byte swapping is needed when working with an external chip.</p>
*
* <p>Note: Some Mbed targets support frame sizes that are not standard integer sizes, e.g. 4 bits, 7 bits, or
* 24 bits. However, the behavior of these frame sizes is not well defined and may differ across targets
* or across API calls (e.g. single-byte vs transaction vs async). More work is needed to make these consistent.</p>
* \note Some Mbed targets support frame sizes that are not standard integer sizes, e.g. 4 bits, 7 bits, or
* 24 bits. However, the behavior of these frame sizes is currently not tested, and you may need to test what works or
* inspect your target's SPI driver code. More work is needed to make these consistent. When available, using these frame sizes
* requires writing each word to be transmitted into the next-largest C integer type. For example, to send 24-bit frames, you
* would create an array of uint32_ts and write each 24-bit integer into its own uint32_t.
* Then you would pass in the byte length of the array (number of frames * 4, NOT number of frames * 3) to the SPI driver.
*
* <h1>Asynchronous API</h1>
* <p>On many processors, Mbed OS also supports asynchronous %SPI. This feature allows you to run %SPI
Expand Down
2 changes: 1 addition & 1 deletion drivers/source/SPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ void SPI::abort_all_transfers()

int SPI::set_dma_usage(DMAUsage usage)
{
if (spi_active(&_peripheral->spi)) {
if (_peripheral->initialized && spi_active(&_peripheral->spi)) {
return -1;
}
_usage = usage;
Expand Down
2 changes: 1 addition & 1 deletion hal/include/hal/dma_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
* @brief Enumeration of possible DMA usage hints
*/
typedef enum {
DMA_USAGE_NEVER, ///< Never use DMA
DMA_USAGE_NEVER = 0, ///< Never use DMA
DMA_USAGE_OPPORTUNISTIC, ///< Use DMA if possible but deallocate DMA resources when not being used.
DMA_USAGE_ALWAYS, ///< Always use DMA when possible
DMA_USAGE_TEMPORARY_ALLOCATED, // Seems to be used as an internal state indicator for "we need to deallocate these channels."
Expand Down
10 changes: 9 additions & 1 deletion hal/include/hal/spi_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ SPIName spi_get_peripheral_name(PinName mosi, PinName miso, PinName mclk);

/**
* Fills the given spi_capabilities_t structure with the capabilities of the given peripheral.
*
* @param ssel The CS pin being used, for checking the \c hw_cs_handle flag
* @param slave True to get capabilities for slave mode, false to get capabilities for master mode
* @param[out] cap Capabilities are returned here
*/
void spi_get_capabilities(PinName ssel, bool slave, spi_capabilities_t *cap);

Expand Down Expand Up @@ -419,7 +423,7 @@ const PinMap *spi_slave_cs_pinmap(void);
* @param[in] rx_length The number of bytes to receive
* @param[in] bit_width The bit width of buffer words
* @param[in] event The logical OR of events to be registered
* @param[in] handler SPI interrupt handler
* @param[in] handler SPI interrupt handler. This will point, through a bit of indirection, to \c SPI::irq_handler_asynch() for the correct SPI instance
* @param[in] hint A suggestion for how to use DMA with this transfer
*
* @return True if DMA was actually used for the transfer, false otherwise (if interrupts or another CPU-based
Expand All @@ -429,6 +433,10 @@ const PinMap *spi_slave_cs_pinmap(void);
* after the transfer is complete. If this function returns true, the driver layer will cache invalidate the Rx buffer under
* the assumption that the data needs to be re-read from main memory. Be careful, because if the read was not actually
* done by DMA, and the rx data is in the CPU cache, this invalidation will corrupt it.
*
* @note The application layer will always acquire the SPI peripheral first before calling this, including setting the frequency and the bit width. So,
* the \c bit_width argument will never be different from the SPI's currently set bit width, and can actually be ignored.
* TODO remove this argument entirely.
*/
bool spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint8_t bit_width, uint32_t handler, uint32_t event, DMAUsage hint);

Expand Down
2 changes: 2 additions & 0 deletions targets/TARGET_NUVOTON/TARGET_M480/PeripheralNames.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ typedef enum {
SPI_5 = (int) NU_MODNAME(QSPI1_BASE, 5, 0),
} SPIName;

#define DEVICE_SPI_COUNT 6

typedef enum {
I2C_0 = (int) NU_MODNAME(I2C0_BASE, 0, 0),
I2C_1 = (int) NU_MODNAME(I2C1_BASE, 1, 0),
Expand Down
13 changes: 13 additions & 0 deletions targets/TARGET_NUVOTON/TARGET_M480/dma_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,19 @@ int dma_channel_allocate(uint32_t capabilities)

int dma_channel_free(int channelid)
{
PDMA_T * pdma = dma_modbase();

// Make sure channel is disabled
pdma->CHCTL &= ~(1 << channelid); // Enable this DMA channel

// Also clear the request source for a channel in case still enabled.
// This allows this request source to be assigned to a different channel later.
PDMA_SetTransferMode(pdma,
channelid,
PDMA_MEM, // No peripheral
0, // Scatter-gather disabled
0); // Scatter-gather descriptor address

if (channelid != DMA_ERROR_OUT_OF_CHANNELS) {
dma_chn_mask &= ~(1 << channelid);
}
Expand Down
5 changes: 4 additions & 1 deletion targets/TARGET_NUVOTON/TARGET_M480/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,14 @@ struct spi_s {
PinName pin_sclk;
PinName pin_ssel;

// Current word size of the SPI
uint8_t word_size_bits;

// Async transfer related fields
DMAUsage dma_usage;
int dma_chn_id_tx;
int dma_chn_id_rx;
uint32_t event;
uint32_t event_mask;
uint32_t txrx_rmn; // Track tx/rx frames remaining in interrupt way
};

Expand Down
Loading
Loading