forked from Imagelibrary/rtems
bsp/atsam: Allow to use a decoder for SPI CS.
The SPI controller supports a decoder connected to the chip select lines. This patch allows to use this mode.
This commit is contained in:
@@ -21,12 +21,17 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#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(
|
int spi_bus_register_atsam(
|
||||||
const char *bus_path,
|
const char *bus_path,
|
||||||
uint8_t spi_peripheral_id,
|
const atsam_spi_config *config
|
||||||
Spi *spi_regs,
|
|
||||||
const Pin *pins,
|
|
||||||
size_t pin_count
|
|
||||||
);
|
);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ typedef struct {
|
|||||||
uint32_t dma_rx_channel;
|
uint32_t dma_rx_channel;
|
||||||
int transfer_in_progress;
|
int transfer_in_progress;
|
||||||
bool chip_select_active;
|
bool chip_select_active;
|
||||||
|
bool chip_select_decode;
|
||||||
} atsam_spi_bus;
|
} atsam_spi_bus;
|
||||||
|
|
||||||
static void atsam_spi_wakeup_task(atsam_spi_bus *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;
|
uint8_t delay_cs;
|
||||||
uint32_t csr = 0;
|
uint32_t csr = 0;
|
||||||
|
uint32_t mode = 0;
|
||||||
|
uint32_t cs = bus->base.cs;
|
||||||
|
|
||||||
delay_cs = atsam_calculate_dlybcs(bus->base.delay_usecs);
|
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(
|
SPID_Configure(
|
||||||
&bus->spi,
|
&bus->spi,
|
||||||
bus->spi.pSpiHw,
|
bus->spi.pSpiHw,
|
||||||
bus->spi.spiId,
|
bus->spi.spiId,
|
||||||
(SPI_MR_DLYBCS(delay_cs) |
|
mode,
|
||||||
SPI_MR_MSTR |
|
|
||||||
SPI_MR_MODFDIS |
|
|
||||||
SPI_PCS(bus->base.cs)),
|
|
||||||
&XDMAD_Instance
|
&XDMAD_Instance
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -113,7 +124,7 @@ static void atsam_configure_spi(atsam_spi_bus *bus)
|
|||||||
|
|
||||||
atsam_set_phase_and_polarity(bus->base.mode, &csr);
|
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(
|
static void atsam_spi_start_dma_transfer(
|
||||||
@@ -141,7 +152,11 @@ static void atsam_spi_do_transfer(
|
|||||||
|
|
||||||
bus->chip_select_active = true;
|
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);
|
SPI_Enable(pSpiHw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,10 +404,7 @@ static void atsam_spi_init_xdma(atsam_spi_bus *bus)
|
|||||||
|
|
||||||
int spi_bus_register_atsam(
|
int spi_bus_register_atsam(
|
||||||
const char *bus_path,
|
const char *bus_path,
|
||||||
uint8_t spi_peripheral_id,
|
const atsam_spi_config *config
|
||||||
Spi *spi_regs,
|
|
||||||
const Pin *pins,
|
|
||||||
size_t pin_count
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
atsam_spi_bus *bus;
|
atsam_spi_bus *bus;
|
||||||
@@ -410,11 +422,12 @@ int spi_bus_register_atsam(
|
|||||||
bus->base.speed_hz = bus->base.max_speed_hz;
|
bus->base.speed_hz = bus->base.max_speed_hz;
|
||||||
bus->base.delay_usecs = 1;
|
bus->base.delay_usecs = 1;
|
||||||
bus->base.cs = 1;
|
bus->base.cs = 1;
|
||||||
bus->spi.spiId = spi_peripheral_id;
|
bus->spi.spiId = config->spi_peripheral_id;
|
||||||
bus->spi.pSpiHw = spi_regs;
|
bus->spi.pSpiHw = config->spi_regs;
|
||||||
|
bus->chip_select_decode = config->chip_select_decode;
|
||||||
|
|
||||||
PIO_Configure(pins, pin_count);
|
PIO_Configure(config->pins, config->pin_count);
|
||||||
PMC_EnablePeripheral(spi_peripheral_id);
|
PMC_EnablePeripheral(config->spi_peripheral_id);
|
||||||
atsam_configure_spi(bus);
|
atsam_configure_spi(bus);
|
||||||
atsam_spi_init_xdma(bus);
|
atsam_spi_init_xdma(bus);
|
||||||
|
|
||||||
|
|||||||
@@ -66,12 +66,17 @@ int atsam_register_spi_0(void)
|
|||||||
PIN_SPI0_CLOCK
|
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(
|
return spi_bus_register_atsam(
|
||||||
ATSAM_SPI_0_BUS_PATH,
|
ATSAM_SPI_0_BUS_PATH,
|
||||||
ID_SPI0,
|
&config
|
||||||
SPI0,
|
|
||||||
pins,
|
|
||||||
RTEMS_ARRAY_SIZE(pins)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,11 +95,16 @@ int atsam_register_spi_1(void)
|
|||||||
PIN_SPI1_CLOCK
|
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(
|
return spi_bus_register_atsam(
|
||||||
ATSAM_SPI_1_BUS_PATH,
|
ATSAM_SPI_1_BUS_PATH,
|
||||||
ID_SPI1,
|
&config
|
||||||
SPI1,
|
|
||||||
pins,
|
|
||||||
RTEMS_ARRAY_SIZE(pins)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user