OVMS3-idf/components/driver/test/include/test/test_common_spi.h
michael 41e58bc419 spi: add new test for timing and mode
New unit tests added
------------------------

**Local:** Local test uses the GPIO matrix to connect the master and the
slave on the same board. When the master needs the iomux, the master
uses the GPIOs of its own, the slave connect to the pins by GPIO matrix;
When the slave needs the iomux, the slave uses the GPIOs of its own, the
master connects to the pins by GPIO matrix.

- Provide a new unit test which performs freq scanning in mode 0. It
scans frequency of 1M, 8M, 9M and all frequency steps up to the maximum
frequency allowed.

**M & S**: Master & slave tests performs the test with two boards. The
master and slave use iomux or gpio matrix according to the config.

- Provide a new unit test which performs freq scanning in mode 0. It
scans frequency of 1M, 8M, 9M and all frequency steps up to the maximum
frequency allowed.

- Provide a new unit test which performs mode test with significant
frequencies. It tests mode 0,1,2,3 with low frequency, and the maximum
frequency allowed.
2019-01-26 00:10:41 +08:00

187 lines
5.8 KiB
C

#ifndef _TEST_COMMON_SPI_H_
#define _TEST_COMMON_SPI_H_
#include <esp_types.h>
#include "driver/spi_master.h"
#include "freertos/FreeRTOS.h"
#include "freertos/ringbuf.h"
#include "freertos/task.h"
#include "unity.h"
#include "test_utils.h"
#include <string.h>
#include "param_test.h"
// All the tests using the header should use this definition as much as possible,
// so that the working host can be changed easily in the future.
#define TEST_SPI_HOST HSPI_HOST
#define TEST_SLAVE_HOST VSPI_HOST
#define FUNC_SPI 1
#define FUNC_GPIO 2
//Delay information
#define ESP_SPI_SLAVE_TV (12.5*3.5)
#define GPIO_DELAY (12.5*2)
#define WIRE_DELAY 12.5
#define TV_INT_CONNECT_GPIO (ESP_SPI_SLAVE_TV+GPIO_DELAY)
#define TV_INT_CONNECT (ESP_SPI_SLAVE_TV)
//when connecting to another board, the delay is usually increased by 12.5ns
#define TV_WITH_ESP_SLAVE_GPIO (TV_INT_CONNECT_GPIO+WIRE_DELAY)
#define TV_WITH_ESP_SLAVE (TV_INT_CONNECT+WIRE_DELAY)
//currently ESP32 slave only supports up to 20MHz, but 40MHz on the same board
#define ESP_SPI_SLAVE_MAX_FREQ SPI_MASTER_FREQ_20M
#define ESP_SPI_SLAVE_MAX_FREQ_SYNC SPI_MASTER_FREQ_40M
#define MAX_TEST_SIZE 16 ///< in this test we run several transactions, this is the maximum trans that can be run
#define PSET_NAME_LEN 30 ///< length of each param set name
//test low frequency, high frequency until freq limit for worst case (both GPIO)
#define TEST_FREQ_DEFAULT(){\
1*1000*1000, \
SPI_MASTER_FREQ_8M , \
SPI_MASTER_FREQ_9M , \
SPI_MASTER_FREQ_10M, \
SPI_MASTER_FREQ_11M, \
SPI_MASTER_FREQ_13M, \
SPI_MASTER_FREQ_16M, \
SPI_MASTER_FREQ_20M, \
SPI_MASTER_FREQ_26M, \
SPI_MASTER_FREQ_40M, \
SPI_MASTER_FREQ_80M, \
0,\
}
#define PIN_NUM_MISO HSPI_IOMUX_PIN_NUM_MISO
#define PIN_NUM_MOSI HSPI_IOMUX_PIN_NUM_MOSI
#define PIN_NUM_CLK HSPI_IOMUX_PIN_NUM_CLK
#define PIN_NUM_CS HSPI_IOMUX_PIN_NUM_CS
//default bus config for tests
#define SPI_BUS_TEST_DEFAULT_CONFIG() {\
.miso_io_num=PIN_NUM_MISO, \
.mosi_io_num=PIN_NUM_MOSI,\
.sclk_io_num=PIN_NUM_CLK,\
.quadwp_io_num=-1,\
.quadhd_io_num=-1\
}
//default device config for master devices
#define SPI_DEVICE_TEST_DEFAULT_CONFIG() {\
.clock_speed_hz=10*1000*1000,\
.mode=0,\
.spics_io_num=PIN_NUM_CS,\
.queue_size=16,\
.pre_cb=NULL, \
.cs_ena_pretrans = 0,\
.cs_ena_posttrans = 0,\
.input_delay_ns = 62.5,\
}
//default device config for slave devices
#define SPI_SLAVE_TEST_DEFAULT_CONFIG() {\
.mode=0,\
.spics_io_num=PIN_NUM_CS,\
.queue_size=3,\
.flags=0,\
}
typedef enum {
FULL_DUPLEX = 0,
HALF_DUPLEX_MISO = 1,
HALF_DUPLEX_MOSI = 2,
} spi_dup_t;
/*-------- slave task related stuff -----------*/
typedef struct {
uint32_t len;
uint8_t* tx_start;
uint8_t data[1];
} slave_rxdata_t;
typedef struct {
uint32_t len;
const uint8_t *start;
} slave_txdata_t;
typedef struct {
spi_host_device_t spi;
RingbufHandle_t data_received;
QueueHandle_t data_to_send;
} spi_slave_task_context_t;
// test data for master and slave
extern uint8_t spitest_master_send[];
extern uint8_t spitest_slave_send[];
//tags for master and slave app
extern const char MASTER_TAG[];
extern const char SLAVE_TAG[];
//parameter set definition
typedef struct {
const char pset_name[PSET_NAME_LEN];
/*The test work till the frequency below,
*set the frequency to higher and remove checks in the driver to know how fast the system can run.
*/
const int *freq_list; // list of tested frequency, terminated by 0
int freq_limit; //freq larger (not equal) than this will be ignored
spi_dup_t dup;
int mode;
bool length_aligned;
int test_size;
int master_limit; // the master disable dummy bits and discard readings over this freq
bool master_iomux;
int master_dma_chan;
bool slave_iomux;
int slave_dma_chan;
int slave_tv_ns;
bool slave_unaligned_addr;
} spitest_param_set_t;
//context definition for the parameterized test
typedef struct {
uint8_t master_rxbuf[480];
spi_transaction_t master_trans[MAX_TEST_SIZE];
TaskHandle_t handle_slave;
spi_slave_task_context_t slave_context;
slave_txdata_t slave_trans[MAX_TEST_SIZE];
} spitest_context_t;
// fill default value of spitest_param_set_t
void spitest_def_param(void* arg);
// functions for slave task
esp_err_t init_slave_context(spi_slave_task_context_t *context);
void deinit_slave_context(spi_slave_task_context_t *context);
void spitest_slave_task(void* arg);
//called by slave, pull-up all pins used by slave
void slave_pull_up(const spi_bus_config_t* cfg, int spics_io_num);
// to access data of pre-defined transactions.
void spitest_init_transactions(const spitest_param_set_t *cfg, spitest_context_t* context);
// print data from a transaction
void spitest_master_print_data(spi_transaction_t *t, int rxlength);
void spitest_slave_print_data(slave_rxdata_t *t, bool print_rxdata);
// Check whether master and slave data match
esp_err_t spitest_check_data(int len, spi_transaction_t *master_t, slave_rxdata_t *slave_t, bool check_master_data, bool check_slave_len, bool check_slave_data);
static inline int get_trans_len(spi_dup_t dup, spi_transaction_t *master_t)
{
if (dup!=HALF_DUPLEX_MISO) {
return master_t->length;
} else {
return master_t->rxlength;
}
}
//remove device from bus and free the bus
void master_free_device_bus(spi_device_handle_t spi);
//use this function to fix the output source when assign multiple funcitons to a same pin
void spitest_gpio_output_sel(uint32_t gpio_num, int func, uint32_t signal_idx);
#endif //_TEST_COMMON_SPI_H_