Skip to content

Commit 4b1b4f7

Browse files
committed
Add spi_get_capabilities() function to HAL API
Add also default weak version of spi_get_capabilities() which provides default/most common SPI parameters. This function can be replaced if a specific target has different capabilities.
1 parent 766c364 commit 4b1b4f7

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

hal/mbed_compat.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "analogin_api.h"
1919
#include "i2c_api.h"
20+
#include "spi_api.h"
2021
#include "gpio_api.h"
2122
#include "mbed_toolchain.h"
2223

@@ -40,4 +41,53 @@ MBED_WEAK void analogin_free(analogin_t *obj)
4041
{
4142
// Do nothing
4243
}
44+
#endif
45+
46+
#if DEVICE_SPI
47+
// Default SPI capabilities. If specific target has different capabilities this function needs to be re-implemented.
48+
MBED_WEAK void spi_get_capabilities(PinName ssel, bool slave, spi_capabilities_t *cap)
49+
{
50+
if (slave) {
51+
cap->minimum_frequency = 200000; // 200 kHz
52+
cap->maximum_frequency = 2000000; // 2 MHz
53+
cap->word_length = 0x00008080; // 8 and 16 bit symbols
54+
cap->support_slave_mode = false; // to be determined later based on ssel
55+
cap->hw_cs_handle = false; // irrelevant in slave mode
56+
cap->slave_delay_between_symbols_ns = 2500; // 2.5 us
57+
cap->clk_modes = 0x0f; // all clock modes
58+
#if DEVICE_SPI_ASYNCH
59+
cap->async_mode = true;
60+
#else
61+
cap->async_mode = false;
62+
#endif
63+
} else {
64+
cap->minimum_frequency = 200000; // 200 kHz
65+
cap->maximum_frequency = 2000000; // 2 MHz
66+
cap->word_length = 0x00008080; // 8 and 16 bit symbols
67+
cap->support_slave_mode = false; // to be determined later based on ssel
68+
cap->hw_cs_handle = false; // to be determined later based on ssel
69+
cap->slave_delay_between_symbols_ns = 0; // irrelevant in master mode
70+
cap->clk_modes = 0x0f; // all clock modes
71+
#if DEVICE_SPI_ASYNCH
72+
cap->async_mode = true;
73+
#else
74+
cap->async_mode = false;
75+
#endif
76+
}
77+
78+
// check if given ssel pin is in the cs pinmap
79+
const PinMap *cs_pins = spi_master_cs_pinmap();
80+
PinName pin = NC;
81+
while (cs_pins->pin != NC) {
82+
if (cs_pins->pin == ssel) {
83+
#if DEVICE_SPISLAVE
84+
cap->support_slave_mode = true;
85+
#endif
86+
cap->hw_cs_handle = true;
87+
break;
88+
}
89+
cs_pins++;
90+
}
91+
}
92+
4393
#endif

hal/spi_api.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,28 @@ typedef struct spi_s spi_t;
5353

5454
#endif
5555

56+
/**
57+
* Describes the capabilities of a SPI peripherals
58+
*/
59+
typedef struct {
60+
/** Minimum frequency supported must be set by target device and it will be assessed during
61+
* testing.
62+
*/
63+
uint32_t minimum_frequency;
64+
/** Maximum frequency supported must be set by target device and it will be assessed during
65+
* testing.
66+
*/
67+
uint32_t maximum_frequency;
68+
/** Each bit represents the corresponding word length. lsb => 1bit, msb => 32bit. */
69+
uint32_t word_length;
70+
uint16_t slave_delay_between_symbols_ns; /**< specifies required number of ns between transmission of successive symbols in slave mode. */
71+
uint8_t clk_modes; /**< specifies supported modes from spi_mode_t. Each bit represents the corresponding mode. */
72+
bool support_slave_mode; /**< If true, the device can handle SPI slave mode using hardware management on the specified ssel pin. */
73+
bool hw_cs_handle; /**< If true, in SPI master mode Chip Select can be handled by hardware. */
74+
bool async_mode; /**< If true, in async mode is supported. */
75+
76+
} spi_capabilities_t;
77+
5678
#ifdef __cplusplus
5779
extern "C" {
5880
#endif
@@ -63,6 +85,11 @@ extern "C" {
6385
* # Defined behavior
6486
* * ::spi_init initializes the spi_t control structure
6587
* * ::spi_init configures the pins used by SPI
88+
* * ::spi_get_capabilities() fills the given `spi_capabilities_t` instance
89+
* * ::spi_get_capabilities() should consider the `ssel` pin when evaluation the `support_slave_mode` and `hw_cs_handle` capability
90+
* * ::spi_get_capabilities(): if the given `ssel` pin cannot be managed by hardware, `support_slave_mode` and `hw_cs_handle` should be false
91+
* * At least a symbol width of 8bit must be supported
92+
* * The supported frequency range must include the range [0.2..2] MHz
6693
* * ::spi_free returns the pins owned by the SPI object to their reset state
6794
* * ::spi_format sets the number of bits per frame
6895
* * ::spi_format configures clock polarity and phase
@@ -125,6 +152,11 @@ extern "C" {
125152
SPIName spi_get_peripheral_name(PinName mosi, PinName miso, PinName mclk);
126153
#endif
127154

155+
/**
156+
* Fills the given spi_capabilities_t structure with the capabilities of the given peripheral.
157+
*/
158+
void spi_get_capabilities(PinName ssel, bool slave, spi_capabilities_t *cap);
159+
128160
/** Initialize the SPI peripheral
129161
*
130162
* Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral

0 commit comments

Comments
 (0)