mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #11682 from mprse/fpga_tests_CI_targets
Make FPGA tests to pass on CI targets (SPI, analogIn, PWM)pull/11836/head
commit
33e392e9d9
|
@ -190,26 +190,26 @@ Case cases[] = {
|
||||||
Case("PWM - period: 10 ms, fill: 90%, api: period/pulse_width_ms", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<10, 90, PERIOD_PULSEWIDTH_MS> >),
|
Case("PWM - period: 10 ms, fill: 90%, api: period/pulse_width_ms", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<10, 90, PERIOD_PULSEWIDTH_MS> >),
|
||||||
Case("PWM - period: 10 ms, fill: 90%, api: period/pulse_width_us", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<10, 90, PERIOD_PULSEWIDTH_US> >),
|
Case("PWM - period: 10 ms, fill: 90%, api: period/pulse_width_us", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<10, 90, PERIOD_PULSEWIDTH_US> >),
|
||||||
|
|
||||||
Case("PWM - period: 50 ms, fill: 10%, api: period/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 10, PERIOD_WRITE> >),
|
Case("PWM - period: 30 ms, fill: 10%, api: period/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 10, PERIOD_WRITE> >),
|
||||||
Case("PWM - period: 50 ms, fill: 10%, api: period_ms/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 10, PERIOD_MS_WRITE> >),
|
Case("PWM - period: 30 ms, fill: 10%, api: period_ms/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 10, PERIOD_MS_WRITE> >),
|
||||||
Case("PWM - period: 50 ms, fill: 10%, api: period_us/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 10, PERIOD_US_WRITE> >),
|
Case("PWM - period: 30 ms, fill: 10%, api: period_us/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 10, PERIOD_US_WRITE> >),
|
||||||
Case("PWM - period: 50 ms, fill: 10%, api: period/pulse_width", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 10, PERIOD_PULSEWIDTH> >),
|
Case("PWM - period: 30 ms, fill: 10%, api: period/pulse_width", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 10, PERIOD_PULSEWIDTH> >),
|
||||||
Case("PWM - period: 50 ms, fill: 10%, api: period/pulse_width_ms", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 10, PERIOD_PULSEWIDTH_MS> >),
|
Case("PWM - period: 30 ms, fill: 10%, api: period/pulse_width_ms", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 10, PERIOD_PULSEWIDTH_MS> >),
|
||||||
Case("PWM - period: 50 ms, fill: 10%, api: period/pulse_width_us", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 10, PERIOD_PULSEWIDTH_US> >),
|
Case("PWM - period: 30 ms, fill: 10%, api: period/pulse_width_us", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 10, PERIOD_PULSEWIDTH_US> >),
|
||||||
|
|
||||||
Case("PWM - period: 50 ms, fill: 50%, api: period/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 50, PERIOD_WRITE> >),
|
Case("PWM - period: 30 ms, fill: 50%, api: period/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 50, PERIOD_WRITE> >),
|
||||||
Case("PWM - period: 50 ms, fill: 50%, api: period_ms/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 50, PERIOD_MS_WRITE> >),
|
Case("PWM - period: 30 ms, fill: 50%, api: period_ms/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 50, PERIOD_MS_WRITE> >),
|
||||||
Case("PWM - period: 50 ms, fill: 50%, api: period_us/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 50, PERIOD_US_WRITE> >),
|
Case("PWM - period: 30 ms, fill: 50%, api: period_us/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 50, PERIOD_US_WRITE> >),
|
||||||
Case("PWM - period: 50 ms, fill: 50%, api: period/pulse_width", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 50, PERIOD_PULSEWIDTH> >),
|
Case("PWM - period: 30 ms, fill: 50%, api: period/pulse_width", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 50, PERIOD_PULSEWIDTH> >),
|
||||||
Case("PWM - period: 50 ms, fill: 50%, api: period/pulse_width_ms", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 50, PERIOD_PULSEWIDTH_MS> >),
|
Case("PWM - period: 30 ms, fill: 50%, api: period/pulse_width_ms", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 50, PERIOD_PULSEWIDTH_MS> >),
|
||||||
Case("PWM - period: 50 ms, fill: 50%, api: period/pulse_width_us", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 50, PERIOD_PULSEWIDTH_US> >),
|
Case("PWM - period: 30 ms, fill: 50%, api: period/pulse_width_us", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 50, PERIOD_PULSEWIDTH_US> >),
|
||||||
|
|
||||||
Case("PWM - period: 50 ms, fill: 90%, api: period/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 90, PERIOD_WRITE> >),
|
Case("PWM - period: 30 ms, fill: 90%, api: period/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 90, PERIOD_WRITE> >),
|
||||||
Case("PWM - period: 50 ms, fill: 90%, api: period_ms/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 90, PERIOD_MS_WRITE> >),
|
Case("PWM - period: 30 ms, fill: 90%, api: period_ms/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 90, PERIOD_MS_WRITE> >),
|
||||||
Case("PWM - period: 50 ms, fill: 90%, api: period_us/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 90, PERIOD_US_WRITE> >),
|
Case("PWM - period: 30 ms, fill: 90%, api: period_us/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 90, PERIOD_US_WRITE> >),
|
||||||
Case("PWM - period: 50 ms, fill: 90%, api: period/pulse_width", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 90, PERIOD_PULSEWIDTH> >),
|
Case("PWM - period: 30 ms, fill: 90%, api: period/pulse_width", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 90, PERIOD_PULSEWIDTH> >),
|
||||||
Case("PWM - period: 50 ms, fill: 90%, api: period/pulse_width_ms", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 90, PERIOD_PULSEWIDTH_MS> >),
|
Case("PWM - period: 30 ms, fill: 90%, api: period/pulse_width_ms", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 90, PERIOD_PULSEWIDTH_MS> >),
|
||||||
Case("PWM - period: 50 ms, fill: 90%, api: period/pulse_width_us", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 90, PERIOD_PULSEWIDTH_US> >)
|
Case("PWM - period: 30 ms, fill: 90%, api: period/pulse_width_us", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 90, PERIOD_PULSEWIDTH_US> >)
|
||||||
};
|
};
|
||||||
|
|
||||||
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
|
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
|
||||||
|
|
|
@ -44,6 +44,10 @@ typedef enum {
|
||||||
#define FREQ_500_KHZ 500000
|
#define FREQ_500_KHZ 500000
|
||||||
#define FREQ_1_MHZ 1000000
|
#define FREQ_1_MHZ 1000000
|
||||||
#define FREQ_2_MHZ 2000000
|
#define FREQ_2_MHZ 2000000
|
||||||
|
#define FREQ_MIN ((uint32_t)0)
|
||||||
|
#define FREQ_MAX ((uint32_t)-1)
|
||||||
|
|
||||||
|
#define TEST_CAPABILITY_BIT(MASK, CAP) ((1 << CAP) & (MASK))
|
||||||
|
|
||||||
const int TRANSFER_COUNT = 300;
|
const int TRANSFER_COUNT = 300;
|
||||||
SPIMasterTester tester(DefaultFormFactor::pins(), DefaultFormFactor::restricted_pins());
|
SPIMasterTester tester(DefaultFormFactor::pins(), DefaultFormFactor::restricted_pins());
|
||||||
|
@ -62,6 +66,36 @@ void spi_async_handler()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Auxiliary function to check platform capabilities against test case. */
|
||||||
|
static bool check_capabilities(const spi_capabilities_t *capabilities, SPITester::SpiMode spi_mode, uint32_t sym_size, transfer_type_t transfer_type, uint32_t frequency)
|
||||||
|
{
|
||||||
|
// Symbol size
|
||||||
|
if (!TEST_CAPABILITY_BIT(capabilities->word_length, (sym_size - 1))) {
|
||||||
|
utest_printf("\n<Specified symbol size is not supported on this platform> skipped ");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SPI clock mode
|
||||||
|
if (!TEST_CAPABILITY_BIT(capabilities->clk_modes, spi_mode)) {
|
||||||
|
utest_printf("\n<Specified spi clock mode is not supported on this platform> skipped");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Frequency
|
||||||
|
if (frequency != FREQ_MAX && frequency != FREQ_MIN && frequency < capabilities->minimum_frequency && frequency > capabilities->maximum_frequency) {
|
||||||
|
utest_printf("\n<Specified frequency is not supported on this platform> skipped ");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Async mode
|
||||||
|
if (transfer_type == TRANSFER_SPI_MASTER_TRANSFER_ASYNC && capabilities->async_mode == false) {
|
||||||
|
utest_printf("\n<Async mode is not supported on this platform> skipped ");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void fpga_spi_test_init_free(PinName mosi, PinName miso, PinName sclk, PinName ssel)
|
void fpga_spi_test_init_free(PinName mosi, PinName miso, PinName sclk, PinName ssel)
|
||||||
{
|
{
|
||||||
spi_init(&spi, mosi, miso, sclk, ssel);
|
spi_init(&spi, mosi, miso, sclk, ssel);
|
||||||
|
@ -72,6 +106,15 @@ void fpga_spi_test_init_free(PinName mosi, PinName miso, PinName sclk, PinName s
|
||||||
|
|
||||||
void fpga_spi_test_common(PinName mosi, PinName miso, PinName sclk, PinName ssel, SPITester::SpiMode spi_mode, uint32_t sym_size, transfer_type_t transfer_type, uint32_t frequency)
|
void fpga_spi_test_common(PinName mosi, PinName miso, PinName sclk, PinName ssel, SPITester::SpiMode spi_mode, uint32_t sym_size, transfer_type_t transfer_type, uint32_t frequency)
|
||||||
{
|
{
|
||||||
|
spi_capabilities_t capabilities;
|
||||||
|
|
||||||
|
|
||||||
|
spi_get_capabilities(ssel, false, &capabilities);
|
||||||
|
|
||||||
|
if (check_capabilities(&capabilities, spi_mode, sym_size, transfer_type, frequency) == false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t sym_mask = ((1 << sym_size) - 1);
|
uint32_t sym_mask = ((1 << sym_size) - 1);
|
||||||
|
|
||||||
// Remap pins for test
|
// Remap pins for test
|
||||||
|
@ -178,14 +221,10 @@ Case cases[] = {
|
||||||
Case("SPI - mode testing (MODE_1)", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode1, 8, TRANSFER_SPI_MASTER_WRITE_SYNC, FREQ_1_MHZ> >),
|
Case("SPI - mode testing (MODE_1)", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode1, 8, TRANSFER_SPI_MASTER_WRITE_SYNC, FREQ_1_MHZ> >),
|
||||||
Case("SPI - mode testing (MODE_2)", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode2, 8, TRANSFER_SPI_MASTER_WRITE_SYNC, FREQ_1_MHZ> >),
|
Case("SPI - mode testing (MODE_2)", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode2, 8, TRANSFER_SPI_MASTER_WRITE_SYNC, FREQ_1_MHZ> >),
|
||||||
Case("SPI - mode testing (MODE_3)", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode3, 8, TRANSFER_SPI_MASTER_WRITE_SYNC, FREQ_1_MHZ> >),
|
Case("SPI - mode testing (MODE_3)", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode3, 8, TRANSFER_SPI_MASTER_WRITE_SYNC, FREQ_1_MHZ> >),
|
||||||
|
|
||||||
Case("SPI - symbol size testing (16)", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode0, 16, TRANSFER_SPI_MASTER_WRITE_SYNC, FREQ_1_MHZ> >),
|
Case("SPI - symbol size testing (16)", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode0, 16, TRANSFER_SPI_MASTER_WRITE_SYNC, FREQ_1_MHZ> >),
|
||||||
|
|
||||||
Case("SPI - frequency testing (500 kHz)", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode0, 8, TRANSFER_SPI_MASTER_WRITE_SYNC, FREQ_500_KHZ> >),
|
Case("SPI - frequency testing (500 kHz)", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode0, 8, TRANSFER_SPI_MASTER_WRITE_SYNC, FREQ_500_KHZ> >),
|
||||||
Case("SPI - frequency testing (2 MHz)", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode0, 8, TRANSFER_SPI_MASTER_WRITE_SYNC, FREQ_2_MHZ> >),
|
Case("SPI - frequency testing (2 MHz)", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode0, 8, TRANSFER_SPI_MASTER_WRITE_SYNC, FREQ_2_MHZ> >),
|
||||||
|
|
||||||
Case("SPI - block write", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode0, 8, TRANSFER_SPI_MASTER_BLOCK_WRITE_SYNC, FREQ_1_MHZ> >),
|
Case("SPI - block write", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode0, 8, TRANSFER_SPI_MASTER_BLOCK_WRITE_SYNC, FREQ_1_MHZ> >),
|
||||||
|
|
||||||
#if DEVICE_SPI_ASYNCH
|
#if DEVICE_SPI_ASYNCH
|
||||||
Case("SPI - async mode", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode0, 8, TRANSFER_SPI_MASTER_TRANSFER_ASYNC, FREQ_1_MHZ> >)
|
Case("SPI - async mode", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode0, 8, TRANSFER_SPI_MASTER_TRANSFER_ASYNC, FREQ_1_MHZ> >)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include "analogin_api.h"
|
#include "analogin_api.h"
|
||||||
#include "i2c_api.h"
|
#include "i2c_api.h"
|
||||||
|
#include "spi_api.h"
|
||||||
#include "gpio_api.h"
|
#include "gpio_api.h"
|
||||||
#include "mbed_toolchain.h"
|
#include "mbed_toolchain.h"
|
||||||
|
|
||||||
|
@ -41,3 +42,52 @@ MBED_WEAK void analogin_free(analogin_t *obj)
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if DEVICE_SPI
|
||||||
|
// Default SPI capabilities. If specific target has different capabilities this function needs to be re-implemented.
|
||||||
|
MBED_WEAK void spi_get_capabilities(PinName ssel, bool slave, spi_capabilities_t *cap)
|
||||||
|
{
|
||||||
|
if (slave) {
|
||||||
|
cap->minimum_frequency = 200000; // 200 kHz
|
||||||
|
cap->maximum_frequency = 2000000; // 2 MHz
|
||||||
|
cap->word_length = 0x00008080; // 8 and 16 bit symbols
|
||||||
|
cap->support_slave_mode = false; // to be determined later based on ssel
|
||||||
|
cap->hw_cs_handle = false; // irrelevant in slave mode
|
||||||
|
cap->slave_delay_between_symbols_ns = 2500; // 2.5 us
|
||||||
|
cap->clk_modes = 0x0f; // all clock modes
|
||||||
|
#if DEVICE_SPI_ASYNCH
|
||||||
|
cap->async_mode = true;
|
||||||
|
#else
|
||||||
|
cap->async_mode = false;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
cap->minimum_frequency = 200000; // 200 kHz
|
||||||
|
cap->maximum_frequency = 2000000; // 2 MHz
|
||||||
|
cap->word_length = 0x00008080; // 8 and 16 bit symbols
|
||||||
|
cap->support_slave_mode = false; // to be determined later based on ssel
|
||||||
|
cap->hw_cs_handle = false; // to be determined later based on ssel
|
||||||
|
cap->slave_delay_between_symbols_ns = 0; // irrelevant in master mode
|
||||||
|
cap->clk_modes = 0x0f; // all clock modes
|
||||||
|
#if DEVICE_SPI_ASYNCH
|
||||||
|
cap->async_mode = true;
|
||||||
|
#else
|
||||||
|
cap->async_mode = false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if given ssel pin is in the cs pinmap
|
||||||
|
const PinMap *cs_pins = spi_master_cs_pinmap();
|
||||||
|
PinName pin = NC;
|
||||||
|
while (cs_pins->pin != NC) {
|
||||||
|
if (cs_pins->pin == ssel) {
|
||||||
|
#if DEVICE_SPISLAVE
|
||||||
|
cap->support_slave_mode = true;
|
||||||
|
#endif
|
||||||
|
cap->hw_cs_handle = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cs_pins++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -53,6 +53,28 @@ typedef struct spi_s spi_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the capabilities of a SPI peripherals
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/** Minimum frequency supported must be set by target device and it will be assessed during
|
||||||
|
* testing.
|
||||||
|
*/
|
||||||
|
uint32_t minimum_frequency;
|
||||||
|
/** Maximum frequency supported must be set by target device and it will be assessed during
|
||||||
|
* testing.
|
||||||
|
*/
|
||||||
|
uint32_t maximum_frequency;
|
||||||
|
/** Each bit represents the corresponding word length. lsb => 1bit, msb => 32bit. */
|
||||||
|
uint32_t word_length;
|
||||||
|
uint16_t slave_delay_between_symbols_ns; /**< specifies required number of ns between transmission of successive symbols in slave mode. */
|
||||||
|
uint8_t clk_modes; /**< specifies supported modes from spi_mode_t. Each bit represents the corresponding mode. */
|
||||||
|
bool support_slave_mode; /**< If true, the device can handle SPI slave mode using hardware management on the specified ssel pin. */
|
||||||
|
bool hw_cs_handle; /**< If true, in SPI master mode Chip Select can be handled by hardware. */
|
||||||
|
bool async_mode; /**< If true, in async mode is supported. */
|
||||||
|
|
||||||
|
} spi_capabilities_t;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -63,6 +85,11 @@ extern "C" {
|
||||||
* # Defined behavior
|
* # Defined behavior
|
||||||
* * ::spi_init initializes the spi_t control structure
|
* * ::spi_init initializes the spi_t control structure
|
||||||
* * ::spi_init configures the pins used by SPI
|
* * ::spi_init configures the pins used by SPI
|
||||||
|
* * ::spi_get_capabilities() fills the given `spi_capabilities_t` instance
|
||||||
|
* * ::spi_get_capabilities() should consider the `ssel` pin when evaluation the `support_slave_mode` and `hw_cs_handle` capability
|
||||||
|
* * ::spi_get_capabilities(): if the given `ssel` pin cannot be managed by hardware, `support_slave_mode` and `hw_cs_handle` should be false
|
||||||
|
* * At least a symbol width of 8bit must be supported
|
||||||
|
* * The supported frequency range must include the range [0.2..2] MHz
|
||||||
* * ::spi_free returns the pins owned by the SPI object to their reset state
|
* * ::spi_free returns the pins owned by the SPI object to their reset state
|
||||||
* * ::spi_format sets the number of bits per frame
|
* * ::spi_format sets the number of bits per frame
|
||||||
* * ::spi_format configures clock polarity and phase
|
* * ::spi_format configures clock polarity and phase
|
||||||
|
@ -125,6 +152,11 @@ extern "C" {
|
||||||
SPIName spi_get_peripheral_name(PinName mosi, PinName miso, PinName mclk);
|
SPIName spi_get_peripheral_name(PinName mosi, PinName miso, PinName mclk);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fills the given spi_capabilities_t structure with the capabilities of the given peripheral.
|
||||||
|
*/
|
||||||
|
void spi_get_capabilities(PinName ssel, bool slave, spi_capabilities_t *cap);
|
||||||
|
|
||||||
/** Initialize the SPI peripheral
|
/** Initialize the SPI peripheral
|
||||||
*
|
*
|
||||||
* Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
|
* Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
|
||||||
|
|
|
@ -297,7 +297,7 @@ void pwmout_pulsewidth(pwmout_t *obj, float pulse)
|
||||||
DEBUG_PRINTF("pwmout_pulsewidt: %f\r\n", pulse);
|
DEBUG_PRINTF("pwmout_pulsewidt: %f\r\n", pulse);
|
||||||
|
|
||||||
/* Cap pulsewidth to period before setting it. */
|
/* Cap pulsewidth to period before setting it. */
|
||||||
if ((pulse * 1000000) > (float) (obj->pulse & ~SEQ_POLARITY_BIT)) {
|
if ((pulse * 1000000) > (float) obj->period) {
|
||||||
obj->pulse &= SEQ_POLARITY_BIT;
|
obj->pulse &= SEQ_POLARITY_BIT;
|
||||||
obj->pulse |= obj->period;
|
obj->pulse |= obj->period;
|
||||||
pwmout_pulsewidth_us(obj, obj->pulse);
|
pwmout_pulsewidth_us(obj, obj->pulse);
|
||||||
|
@ -354,4 +354,3 @@ const PinMap *pwmout_pinmap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // DEVICE_PWMOUT
|
#endif // DEVICE_PWMOUT
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,51 @@ static void spi_configure_driver_instance(spi_t *obj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void spi_get_capabilities(PinName ssel, bool slave, spi_capabilities_t *cap)
|
||||||
|
{
|
||||||
|
if (slave) {
|
||||||
|
cap->minimum_frequency = 200000; // 200 kHz
|
||||||
|
cap->maximum_frequency = 2000000; // 2 MHz
|
||||||
|
cap->word_length = 0x00000080; // 8 bit symbols
|
||||||
|
cap->support_slave_mode = false; // to be determined later based on ssel
|
||||||
|
cap->hw_cs_handle = false; // irrelevant in slave mode
|
||||||
|
cap->slave_delay_between_symbols_ns = 2500; // 2.5 us
|
||||||
|
cap->clk_modes = 0x0f; // all clock modes
|
||||||
|
#if DEVICE_SPI_ASYNCH
|
||||||
|
cap->async_mode = true;
|
||||||
|
#else
|
||||||
|
cap->async_mode = false;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
cap->minimum_frequency = 200000; // 200 kHz
|
||||||
|
cap->maximum_frequency = 2000000; // 2 MHz
|
||||||
|
cap->word_length = 0x00000080; // 8 bit symbols
|
||||||
|
cap->support_slave_mode = false; // to be determined later based on ssel
|
||||||
|
cap->hw_cs_handle = false; // to be determined later based on ssel
|
||||||
|
cap->slave_delay_between_symbols_ns = 0; // irrelevant in master mode
|
||||||
|
cap->clk_modes = 0x0f; // all clock modes
|
||||||
|
#if DEVICE_SPI_ASYNCH
|
||||||
|
cap->async_mode = true;
|
||||||
|
#else
|
||||||
|
cap->async_mode = false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if given ssel pin is in the cs pinmap
|
||||||
|
const PinMap *cs_pins = spi_master_cs_pinmap();
|
||||||
|
PinName pin = NC;
|
||||||
|
while (cs_pins->pin != NC) {
|
||||||
|
if (cs_pins->pin == ssel) {
|
||||||
|
#if DEVICE_SPISLAVE
|
||||||
|
cap->support_slave_mode = true;
|
||||||
|
#endif
|
||||||
|
cap->hw_cs_handle = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cs_pins++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Initialize the SPI peripheral
|
/** Initialize the SPI peripheral
|
||||||
*
|
*
|
||||||
* Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
|
* Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
|
||||||
|
@ -247,13 +292,13 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
|
||||||
nrf_spi_mode_t new_mode = NRF_SPI_MODE_0;
|
nrf_spi_mode_t new_mode = NRF_SPI_MODE_0;
|
||||||
|
|
||||||
/* Convert Mbed HAL mode to Nordic mode. */
|
/* Convert Mbed HAL mode to Nordic mode. */
|
||||||
if(mode == 0) {
|
if (mode == 0) {
|
||||||
new_mode = NRF_SPI_MODE_0;
|
new_mode = NRF_SPI_MODE_0;
|
||||||
} else if(mode == 1) {
|
} else if (mode == 1) {
|
||||||
new_mode = NRF_SPI_MODE_1;
|
new_mode = NRF_SPI_MODE_1;
|
||||||
} else if(mode == 2) {
|
} else if (mode == 2) {
|
||||||
new_mode = NRF_SPI_MODE_2;
|
new_mode = NRF_SPI_MODE_2;
|
||||||
} else if(mode == 3) {
|
} else if (mode == 3) {
|
||||||
new_mode = NRF_SPI_MODE_3;
|
new_mode = NRF_SPI_MODE_3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,8 +396,9 @@ int spi_master_write(spi_t *obj, int value)
|
||||||
desc.rx_length = 1;
|
desc.rx_length = 1;
|
||||||
ret = nrfx_spi_xfer(&nordic_nrf5_spi_instance[instance], &desc, 0);
|
ret = nrfx_spi_xfer(&nordic_nrf5_spi_instance[instance], &desc, 0);
|
||||||
|
|
||||||
if (ret != NRFX_SUCCESS)
|
if (ret != NRFX_SUCCESS) {
|
||||||
DEBUG_PRINTF("%d error returned from nrf_spi_xfer\n\r");
|
DEBUG_PRINTF("%d error returned from nrf_spi_xfer\n\r");
|
||||||
|
}
|
||||||
|
|
||||||
/* Manually set chip select pin if defined. */
|
/* Manually set chip select pin if defined. */
|
||||||
if (spi_inst->cs != NC) {
|
if (spi_inst->cs != NC) {
|
||||||
|
@ -421,7 +467,7 @@ int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, cha
|
||||||
int tx_actual_length = (tx_length > 255) ? 255 : tx_length;
|
int tx_actual_length = (tx_length > 255) ? 255 : tx_length;
|
||||||
|
|
||||||
/* Set tx buffer pointer. Set to NULL if no data is going to be transmitted. */
|
/* Set tx buffer pointer. Set to NULL if no data is going to be transmitted. */
|
||||||
const uint8_t * tx_actual_buffer = (tx_actual_length > 0) ?
|
const uint8_t *tx_actual_buffer = (tx_actual_length > 0) ?
|
||||||
(const uint8_t *)(tx_buffer + tx_offset) :
|
(const uint8_t *)(tx_buffer + tx_offset) :
|
||||||
NULL;
|
NULL;
|
||||||
|
|
||||||
|
@ -429,7 +475,7 @@ int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, cha
|
||||||
int rx_actual_length = (rx_length > 255) ? 255 : rx_length;
|
int rx_actual_length = (rx_length > 255) ? 255 : rx_length;
|
||||||
|
|
||||||
/* Set rx buffer pointer. Set to NULL if no data is going to be received. */
|
/* Set rx buffer pointer. Set to NULL if no data is going to be received. */
|
||||||
uint8_t * rx_actual_buffer = (rx_actual_length > 0) ?
|
uint8_t *rx_actual_buffer = (rx_actual_length > 0) ?
|
||||||
(uint8_t *)(rx_buffer + rx_offset) :
|
(uint8_t *)(rx_buffer + rx_offset) :
|
||||||
NULL;
|
NULL;
|
||||||
|
|
||||||
|
@ -721,7 +767,7 @@ void spi_master_transfer(spi_t *obj,
|
||||||
struct buffer_s *buffer_pointer;
|
struct buffer_s *buffer_pointer;
|
||||||
|
|
||||||
buffer_pointer = &obj->tx_buff;
|
buffer_pointer = &obj->tx_buff;
|
||||||
buffer_pointer->buffer = (void*) tx;
|
buffer_pointer->buffer = (void *) tx;
|
||||||
buffer_pointer->length = tx_length;
|
buffer_pointer->length = tx_length;
|
||||||
buffer_pointer->pos = 0;
|
buffer_pointer->pos = 0;
|
||||||
buffer_pointer->width = 8;
|
buffer_pointer->width = 8;
|
||||||
|
|
|
@ -58,7 +58,7 @@ MBED_WEAK const PinMap PinMap_ADC[] = {
|
||||||
// {PA_2, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC1_IN3 // Connected to STDIO_UART_TX
|
// {PA_2, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC1_IN3 // Connected to STDIO_UART_TX
|
||||||
// {PA_3, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC1_IN4 // Connected to STDIO_UART_RX
|
// {PA_3, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC1_IN4 // Connected to STDIO_UART_RX
|
||||||
{PA_4, ADC_2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC2_IN1
|
{PA_4, ADC_2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC2_IN1
|
||||||
{PA_5, ADC_2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC2_IN2 // Connected to LD2 [Green Led]
|
// {PA_5, ADC_2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC2_IN2 // Connected to LD2 [Green Led]
|
||||||
{PA_6, ADC_2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC2_IN3
|
{PA_6, ADC_2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC2_IN3
|
||||||
{PA_7, ADC_2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC2_IN4
|
{PA_7, ADC_2, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC2_IN4
|
||||||
{PB_0, ADC_3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC3_IN12
|
{PB_0, ADC_3, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC3_IN12
|
||||||
|
|
|
@ -58,7 +58,7 @@ MBED_WEAK const PinMap PinMap_ADC[] = {
|
||||||
// {PA_2, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC1_IN2 // Connected to STDIO_UART_TX
|
// {PA_2, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC1_IN2 // Connected to STDIO_UART_TX
|
||||||
// {PA_3, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC1_IN3 // Connected to STDIO_UART_RX
|
// {PA_3, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC1_IN3 // Connected to STDIO_UART_RX
|
||||||
{PA_4, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC1_IN4
|
{PA_4, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC1_IN4
|
||||||
{PA_5, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC1_IN5 // Connected to LD2 [Green Led]
|
// {PA_5, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC1_IN5 // Connected to LD2 [Green Led]
|
||||||
{PA_6, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC1_IN6
|
{PA_6, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC1_IN6
|
||||||
{PA_7, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC1_IN7
|
{PA_7, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC1_IN7
|
||||||
{PB_0, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC1_IN8
|
{PB_0, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC1_IN8
|
||||||
|
|
|
@ -58,7 +58,7 @@ MBED_WEAK const PinMap PinMap_ADC[] = {
|
||||||
// {PA_2, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC_IN2 // Connected to STDIO_UART_TX
|
// {PA_2, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC_IN2 // Connected to STDIO_UART_TX
|
||||||
// {PA_3, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC_IN3 // Connected to STDIO_UART_RX
|
// {PA_3, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC_IN3 // Connected to STDIO_UART_RX
|
||||||
{PA_4, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC_IN4
|
{PA_4, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC_IN4
|
||||||
{PA_5, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC_IN5 // Connected to LD2 [Green Led]
|
// {PA_5, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC_IN5 // Connected to LD2 [Green Led]
|
||||||
{PA_6, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC_IN6
|
{PA_6, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC_IN6
|
||||||
{PA_7, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC_IN7
|
{PA_7, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC_IN7
|
||||||
{PB_0, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC_IN8
|
{PB_0, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC_IN8
|
||||||
|
|
Loading…
Reference in New Issue