Improve SPI bus implementation

Make possible to define chip-select pin for internal SPI.
By defining chip-select pin, it's possible to start specific SPI device only.
This allows to have several same type of sensors on the same bus with different orientation.
This commit is contained in:
Jani Paalijarvi 2021-11-15 13:09:35 +02:00 committed by Beat Küng
parent 35d4986ea7
commit 02336acd61
6 changed files with 21 additions and 11 deletions

View File

@ -137,8 +137,8 @@ class ModuleDocumentation(object):
"\"board-specific bus (default=all) (external SPI: n-th bus (default=1))\"", 'true'])
if self._is_bool_true(args[1]):
self._handle_usage_param_int(['\'c\'', '1', '1', '10',
"\"chip-select index (for external SPI)\"", 'true'])
self._handle_usage_param_int(['\'c\'', '-1', '0', '31',
"\"chip-select pin (for internal SPI) or index (for external SPI)\"", 'true'])
self._handle_usage_param_int(['\'m\'', '-1', '0', '3', "\"SPI mode\"", 'true'])
self._handle_usage_param_int(['\'f\'', '-1', '0', '1000000', "\"bus frequency in kHz\"", 'true'])

View File

@ -187,7 +187,7 @@ int BusCLIArguments::getOpt(int argc, char *argv[], const char *options)
break;
case 'c':
chipselect_index = atoi(_optarg);
chipselect = atoi(_optarg);
break;
#endif // CONFIG_SPI
@ -286,7 +286,7 @@ BusInstanceIterator::BusInstanceIterator(const char *module_name,
#endif // CONFIG_I2C
#if defined(CONFIG_SPI)
_spi_bus_iterator(spiFilter(cli_arguments.bus_option),
cli_arguments.bus_option == I2CSPIBusOption::SPIExternal ? cli_arguments.chipselect_index : devid_driver_index,
devid_driver_index, cli_arguments.chipselect,
cli_arguments.requested_bus),
#endif // CONFIG_SPI
#if defined(CONFIG_I2C)

View File

@ -176,7 +176,7 @@ public:
int requested_bus{-1};
int bus_frequency{0};
#if defined(CONFIG_SPI)
int chipselect_index {1};
int chipselect {-1};
spi_mode_e spi_mode{SPIDEV_MODE3};
#endif // CONFIG_SPI
#if defined(CONFIG_I2C)

View File

@ -141,12 +141,14 @@ public:
* Constructor
* Note: only for devices of type PX4_SPI_DEVICE_ID
* @param filter
* @param devid_driver_index DRV_* or chip-select index starting from 1
* @param devid_driver_index DRV_*
* @param chipselect pin of SPIInternal (-1=all) or chip-select index of SPIExternal starting from 1 (optional)
* @param bus starts with 1 (-1=all, but only for internal). Numbering for internal is arch-specific, for external
* it is the n-th external bus.
*/
SPIBusIterator(FilterType filter, uint16_t devid_driver_index, int bus = -1)
SPIBusIterator(FilterType filter, uint16_t devid_driver_index, int16_t chipselect = -1, int bus = -1)
: _filter(filter), _devid_driver_index(devid_driver_index),
_chipselect(chipselect),
_bus(filter == FilterType::ExternalBus && bus == -1 ? 1 : bus) {}
bool next();
@ -165,6 +167,7 @@ public:
private:
const FilterType _filter;
const uint16_t _devid_driver_index;
const int16_t _chipselect;
const int _bus;
int _index{0};
int _external_bus_counter{1};

View File

@ -120,7 +120,7 @@ void PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(bool i2c_support, bool spi_support
true);
if (spi_support) {
PRINT_MODULE_USAGE_PARAM_INT('c', 1, 1, 10, "chip-select index (for external SPI)", true);
PRINT_MODULE_USAGE_PARAM_INT('c', -1, 0, 31, "chip-select pin (for internal SPI) or index (for external SPI)", true);
PRINT_MODULE_USAGE_PARAM_INT('m', -1, 0, 3, "SPI mode", true);
}

View File

@ -37,6 +37,10 @@
#include <px4_platform_common/spi.h>
#ifndef GPIO_PIN_MASK
#define GPIO_PIN_MASK 0
#endif
#if BOARD_NUM_SPI_CFG_HW_VERSIONS > 1
void px4_set_spi_buses_from_hw_version()
{
@ -124,10 +128,12 @@ bool SPIBusIterator::next()
case FilterType::InternalBus:
if (!bus_data.is_external) {
if (_bus == bus_data.bus || _bus == -1) {
// find device id
// Note: if chipselect < 0, it's not defined and used in filter
// find device
for (int i = _bus_device_index + 1; i < SPI_BUS_MAX_DEVICES; ++i) {
if (PX4_SPI_DEVICE_ID == PX4_SPIDEVID_TYPE(bus_data.devices[i].devid) &&
_devid_driver_index == bus_data.devices[i].devtype_driver) {
_devid_driver_index == bus_data.devices[i].devtype_driver &&
(_chipselect < 0 || _chipselect == (int16_t)(bus_data.devices[i].cs_gpio & GPIO_PIN_MASK))) {
_bus_device_index = i;
return true;
}
@ -139,7 +145,8 @@ bool SPIBusIterator::next()
case FilterType::ExternalBus:
if (bus_data.is_external) {
uint16_t cs_index = _devid_driver_index - 1;
// Note: chip-select index is starting from 1 in CLI, -1 means not defined
uint16_t cs_index = _chipselect < 1 ? 0 : _chipselect - 1;
if (_bus == _external_bus_counter && cs_index < SPI_BUS_MAX_DEVICES &&
bus_data.devices[cs_index].cs_gpio != 0 && cs_index != _bus_device_index) {