The SPI controller supports a decoder connected to the chip select lines. This patch allows to use this mode. --- bsps/arm/atsam/include/bsp/atsam-spi.h | 13 +++++--- c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c | 41 ++++++++++++++++--------- c/src/lib/libbsp/arm/atsam/spi/atsam_spi_init.c | 26 +++++++++++----- 3 files changed, 54 insertions(+), 26 deletions(-)
diff --git a/bsps/arm/atsam/include/bsp/atsam-spi.h b/bsps/arm/atsam/include/bsp/atsam-spi.h index 548dd544f4..4bfa6c3a1e 100644 --- a/bsps/arm/atsam/include/bsp/atsam-spi.h +++ b/bsps/arm/atsam/include/bsp/atsam-spi.h @@ -21,12 +21,17 @@ extern "C" { #endif /* __cplusplus */ +typedef struct { + uint8_t spi_peripheral_id; + const Pin *pins; + Spi *spi_regs; + size_t pin_count; + bool chip_select_decode; +} atsam_spi_config; + int spi_bus_register_atsam( const char *bus_path, - uint8_t spi_peripheral_id, - Spi *spi_regs, - const Pin *pins, - size_t pin_count + const atsam_spi_config *config ); #ifdef __cplusplus diff --git a/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c b/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c index 5c6cdc2af7..24850c8327 100644 --- a/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c +++ b/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c @@ -49,6 +49,7 @@ typedef struct { uint32_t dma_rx_channel; int transfer_in_progress; bool chip_select_active; + bool chip_select_decode; } atsam_spi_bus; static void atsam_spi_wakeup_task(atsam_spi_bus *bus) @@ -91,17 +92,27 @@ static void atsam_configure_spi(atsam_spi_bus *bus) { uint8_t delay_cs; uint32_t csr = 0; + uint32_t mode = 0; + uint32_t cs = bus->base.cs; delay_cs = atsam_calculate_dlybcs(bus->base.delay_usecs); + mode |= SPI_MR_DLYBCS(delay_cs); + mode |= SPI_MR_MSTR; + mode |= SPI_MR_MODFDIS; + if (bus->chip_select_decode) { + mode |= SPI_MR_PCS(bus->base.cs); + mode |= SPI_MR_PCSDEC; + cs /= 4; + } else { + mode |= SPI_PCS(bus->base.cs); + } + SPID_Configure( &bus->spi, bus->spi.pSpiHw, bus->spi.spiId, - (SPI_MR_DLYBCS(delay_cs) | - SPI_MR_MSTR | - SPI_MR_MODFDIS | - SPI_PCS(bus->base.cs)), + mode, &XDMAD_Instance ); @@ -113,7 +124,7 @@ static void atsam_configure_spi(atsam_spi_bus *bus) atsam_set_phase_and_polarity(bus->base.mode, &csr); - SPI_ConfigureNPCS(bus->spi.pSpiHw, bus->base.cs, csr); + SPI_ConfigureNPCS(bus->spi.pSpiHw, cs, csr); } static void atsam_spi_start_dma_transfer( @@ -141,7 +152,11 @@ static void atsam_spi_do_transfer( bus->chip_select_active = true; - SPI_ChipSelect(pSpiHw, 1 << msg->cs); + if (bus->chip_select_decode) { + pSpiHw->SPI_MR = (pSpiHw->SPI_MR & ~SPI_MR_PCS_Msk) | SPI_MR_PCS(msg->cs); + } else { + SPI_ChipSelect(pSpiHw, 1 << msg->cs); + } SPI_Enable(pSpiHw); } @@ -389,10 +404,7 @@ static void atsam_spi_init_xdma(atsam_spi_bus *bus) int spi_bus_register_atsam( const char *bus_path, - uint8_t spi_peripheral_id, - Spi *spi_regs, - const Pin *pins, - size_t pin_count + const atsam_spi_config *config ) { atsam_spi_bus *bus; @@ -410,11 +422,12 @@ int spi_bus_register_atsam( bus->base.speed_hz = bus->base.max_speed_hz; bus->base.delay_usecs = 1; bus->base.cs = 1; - bus->spi.spiId = spi_peripheral_id; - bus->spi.pSpiHw = spi_regs; + bus->spi.spiId = config->spi_peripheral_id; + bus->spi.pSpiHw = config->spi_regs; + bus->chip_select_decode = config->chip_select_decode; - PIO_Configure(pins, pin_count); - PMC_EnablePeripheral(spi_peripheral_id); + PIO_Configure(config->pins, config->pin_count); + PMC_EnablePeripheral(config->spi_peripheral_id); atsam_configure_spi(bus); atsam_spi_init_xdma(bus); diff --git a/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_init.c b/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_init.c index 09440f263f..ca18f8ec35 100644 --- a/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_init.c +++ b/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_init.c @@ -66,12 +66,17 @@ int atsam_register_spi_0(void) PIN_SPI0_CLOCK }; + static const atsam_spi_config config = { + .spi_peripheral_id = ID_SPI0, + .spi_regs = SPI0, + .pins = pins, + .pin_count = RTEMS_ARRAY_SIZE(pins), + .chip_select_decode = false + }; + return spi_bus_register_atsam( ATSAM_SPI_0_BUS_PATH, - ID_SPI0, - SPI0, - pins, - RTEMS_ARRAY_SIZE(pins) + &config ); } @@ -90,11 +95,16 @@ int atsam_register_spi_1(void) PIN_SPI1_CLOCK }; + static const atsam_spi_config config = { + .spi_peripheral_id = ID_SPI1, + .spi_regs = SPI1, + .pins = pins, + .pin_count = RTEMS_ARRAY_SIZE(pins), + .chip_select_decode = false + }; + return spi_bus_register_atsam( ATSAM_SPI_1_BUS_PATH, - ID_SPI1, - SPI1, - pins, - RTEMS_ARRAY_SIZE(pins) + &config ); } -- 2.13.6 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel