Skip to content

Commit 33e392e

Browse files
authored
Merge pull request #11682 from mprse/fpga_tests_CI_targets
Make FPGA tests to pass on CI targets (SPI, analogIn, PWM)
2 parents 383cf19 + b24afed commit 33e392e

File tree

9 files changed

+215
-49
lines changed

9 files changed

+215
-49
lines changed

TESTS/mbed_hal_fpga_ci_test_shield/pwm/main.cpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -190,26 +190,26 @@ Case cases[] = {
190190
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> >),
191191
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> >),
192192

193-
Case("PWM - period: 50 ms, fill: 10%, api: period/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 10, PERIOD_WRITE> >),
194-
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> >),
195-
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> >),
196-
Case("PWM - period: 50 ms, fill: 10%, api: period/pulse_width", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 10, PERIOD_PULSEWIDTH> >),
197-
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> >),
198-
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> >),
199-
200-
Case("PWM - period: 50 ms, fill: 50%, api: period/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 50, PERIOD_WRITE> >),
201-
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> >),
202-
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> >),
203-
Case("PWM - period: 50 ms, fill: 50%, api: period/pulse_width", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 50, PERIOD_PULSEWIDTH> >),
204-
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> >),
205-
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> >),
206-
207-
Case("PWM - period: 50 ms, fill: 90%, api: period/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 90, PERIOD_WRITE> >),
208-
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> >),
209-
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> >),
210-
Case("PWM - period: 50 ms, fill: 90%, api: period/pulse_width", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<50, 90, PERIOD_PULSEWIDTH> >),
211-
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> >),
212-
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> >)
193+
Case("PWM - period: 30 ms, fill: 10%, api: period/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 10, PERIOD_WRITE> >),
194+
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> >),
195+
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> >),
196+
Case("PWM - period: 30 ms, fill: 10%, api: period/pulse_width", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 10, PERIOD_PULSEWIDTH> >),
197+
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> >),
198+
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> >),
199+
200+
Case("PWM - period: 30 ms, fill: 50%, api: period/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 50, PERIOD_WRITE> >),
201+
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> >),
202+
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> >),
203+
Case("PWM - period: 30 ms, fill: 50%, api: period/pulse_width", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 50, PERIOD_PULSEWIDTH> >),
204+
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> >),
205+
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> >),
206+
207+
Case("PWM - period: 30 ms, fill: 90%, api: period/write", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 90, PERIOD_WRITE> >),
208+
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> >),
209+
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> >),
210+
Case("PWM - period: 30 ms, fill: 90%, api: period/pulse_width", one_peripheral<PWMPort, DefaultFormFactor, fpga_pwm_period_fill_test<30, 90, PERIOD_PULSEWIDTH> >),
211+
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> >),
212+
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> >)
213213
};
214214

215215
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)

TESTS/mbed_hal_fpga_ci_test_shield/spi/main.cpp

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,13 @@ typedef enum {
4141
TRANSFER_SPI_MASTER_TRANSFER_ASYNC
4242
} transfer_type_t;
4343

44-
#define FREQ_500_KHZ 500000
45-
#define FREQ_1_MHZ 1000000
46-
#define FREQ_2_MHZ 2000000
44+
#define FREQ_500_KHZ 500000
45+
#define FREQ_1_MHZ 1000000
46+
#define FREQ_2_MHZ 2000000
47+
#define FREQ_MIN ((uint32_t)0)
48+
#define FREQ_MAX ((uint32_t)-1)
49+
50+
#define TEST_CAPABILITY_BIT(MASK, CAP) ((1 << CAP) & (MASK))
4751

4852
const int TRANSFER_COUNT = 300;
4953
SPIMasterTester tester(DefaultFormFactor::pins(), DefaultFormFactor::restricted_pins());
@@ -62,6 +66,36 @@ void spi_async_handler()
6266
}
6367
#endif
6468

69+
/* Auxiliary function to check platform capabilities against test case. */
70+
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)
71+
{
72+
// Symbol size
73+
if (!TEST_CAPABILITY_BIT(capabilities->word_length, (sym_size - 1))) {
74+
utest_printf("\n<Specified symbol size is not supported on this platform> skipped ");
75+
return false;
76+
}
77+
78+
// SPI clock mode
79+
if (!TEST_CAPABILITY_BIT(capabilities->clk_modes, spi_mode)) {
80+
utest_printf("\n<Specified spi clock mode is not supported on this platform> skipped");
81+
return false;
82+
}
83+
84+
// Frequency
85+
if (frequency != FREQ_MAX && frequency != FREQ_MIN && frequency < capabilities->minimum_frequency && frequency > capabilities->maximum_frequency) {
86+
utest_printf("\n<Specified frequency is not supported on this platform> skipped ");
87+
return false;
88+
}
89+
90+
// Async mode
91+
if (transfer_type == TRANSFER_SPI_MASTER_TRANSFER_ASYNC && capabilities->async_mode == false) {
92+
utest_printf("\n<Async mode is not supported on this platform> skipped ");
93+
return false;
94+
}
95+
96+
return true;
97+
}
98+
6599
void fpga_spi_test_init_free(PinName mosi, PinName miso, PinName sclk, PinName ssel)
66100
{
67101
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
72106

73107
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)
74108
{
109+
spi_capabilities_t capabilities;
110+
111+
112+
spi_get_capabilities(ssel, false, &capabilities);
113+
114+
if (check_capabilities(&capabilities, spi_mode, sym_size, transfer_type, frequency) == false) {
115+
return;
116+
}
117+
75118
uint32_t sym_mask = ((1 << sym_size) - 1);
76119

77120
// Remap pins for test
@@ -178,14 +221,10 @@ Case cases[] = {
178221
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> >),
179222
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> >),
180223
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> >),
181-
182224
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> >),
183-
184225
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> >),
185226
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> >),
186-
187227
Case("SPI - block write", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode0, 8, TRANSFER_SPI_MASTER_BLOCK_WRITE_SYNC, FREQ_1_MHZ> >),
188-
189228
#if DEVICE_SPI_ASYNCH
190229
Case("SPI - async mode", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode0, 8, TRANSFER_SPI_MASTER_TRANSFER_ASYNC, FREQ_1_MHZ> >)
191230
#endif

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

targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/pwmout_api.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ void pwmout_pulsewidth(pwmout_t *obj, float pulse)
297297
DEBUG_PRINTF("pwmout_pulsewidt: %f\r\n", pulse);
298298

299299
/* Cap pulsewidth to period before setting it. */
300-
if ((pulse * 1000000) > (float) (obj->pulse & ~SEQ_POLARITY_BIT)) {
300+
if ((pulse * 1000000) > (float) obj->period) {
301301
obj->pulse &= SEQ_POLARITY_BIT;
302302
obj->pulse |= obj->period;
303303
pwmout_pulsewidth_us(obj, obj->pulse);
@@ -354,4 +354,3 @@ const PinMap *pwmout_pinmap()
354354
}
355355

356356
#endif // DEVICE_PWMOUT
357-

0 commit comments

Comments
 (0)