43 #define SPI_SELECT_SLAVE_IO__(port, reg) IO ## port ## reg
45 #define SPI_SELECT_SLAVE_IO_(port, reg) SPI_SELECT_SLAVE_IO__(port, reg)
47 #define SPI_SELECT_SLAVE0_IODIR SPI_SELECT_SLAVE_IO_(SPI_SELECT_SLAVE0_PORT, DIR)
48 #define SPI_SELECT_SLAVE0_IOCLR SPI_SELECT_SLAVE_IO_(SPI_SELECT_SLAVE0_PORT, CLR)
49 #define SPI_SELECT_SLAVE0_IOSET SPI_SELECT_SLAVE_IO_(SPI_SELECT_SLAVE0_PORT, SET)
51 #define SPI_SELECT_SLAVE1_IODIR SPI_SELECT_SLAVE_IO_(SPI_SELECT_SLAVE1_PORT, DIR)
52 #define SPI_SELECT_SLAVE1_IOCLR SPI_SELECT_SLAVE_IO_(SPI_SELECT_SLAVE1_PORT, CLR)
53 #define SPI_SELECT_SLAVE1_IOSET SPI_SELECT_SLAVE_IO_(SPI_SELECT_SLAVE1_PORT, SET)
201 uint16_t max_idx =
Max(t->output_length, t->input_length);
202 while (p->tx_idx_buf < max_idx && bit_is_set(((
sspRegs_t *)(p->reg_addr))->sr,
TNF)) {
203 if (p->tx_idx_buf < t->output_length) {
205 SpiSend(p, t->output_buf[p->tx_idx_buf]);
207 uint16_t tmp1 = t->output_buf[2 * p->tx_idx_buf];
208 uint16_t tmp2 = t->output_buf[2 * p->tx_idx_buf + 1] << 8;
216 if (p->tx_idx_buf == max_idx) {
223 while (bit_is_set(((
sspRegs_t *)(p->reg_addr))->sr,
RNE)) {
224 if (p->rx_idx_buf < t->input_length) {
228 t->input_buf[p->rx_idx_buf] = (
uint8_t)r;
230 t->input_buf[2 * p->rx_idx_buf] = (
uint8_t)r;
231 t->input_buf[2 * p->rx_idx_buf + 1] = (
uint8_t)(r >> 8);
269 if (t->before_cb != 0) { t->before_cb(t); }
281 if (t->after_cb != 0) { t->after_cb(t); }
293 p->trans_extract_idx++;
295 p->trans_extract_idx = 0;
298 if (p->trans_extract_idx == p->trans_insert_idx || p->suspend) {
301 SpiStart(p, p->trans[p->trans_extract_idx]);
316 if (bit_is_set(((
sspRegs_t *)(p->reg_addr))->sr,
BSY)) {
341 if (t->before_cb != 0) { t->before_cb(t); }
385 #define SSP_PINSEL1_SCK (2 << 2)
386 #define SSP_PINSEL1_MISO (2 << 4)
387 #define SSP_PINSEL1_MOSI (2 << 6)
388 #define SSP_PINSEL1_SSEL (2 << 8)
391 #ifndef SPI1_VIC_SLOT
392 #define SPI1_VIC_SLOT 7
405 #error "SPI0 is currently not implemented in the mcu_periph/spi HAL for the LPC!"
433 #define MASTER_SSP_DSS 0x07 << 0
434 #define MASTER_SSP_FRF 0x00 << 4
435 #define MASTER_SSP_CPOL 0x00 << 6
436 #define MASTER_SSP_CPHA 0x00 << 7
437 #define MASTER_SSP_SCR 0x0F << 8
440 #define MASTER_SSP_LBM 0x00 << 0
441 #define MASTER_SSP_SSE 0x00 << 1
442 #define MASTER_SSP_MS 0x00 << 2
443 #define MASTER_SSP_SOD 0x00 << 3
450 #define SSPCPSR_VAL 0x02
453 void spi1_ISR(
void) __attribute__((naked));
472 spi1.init_struct = (
void *)(&spi1_vic_slot);
549 #error SPI_SLAVE2 is not implemented yet, sorry
567 if (slave < 254 && p->suspend == 0) {
607 #if (PCLK == 15000000)
611 #if (PCLK == 30000000)
615 #if (PCLK == 60000000)
619 #error unknown PCLK frequency
625 #error SPI0 in slave mode is not implemented yet, sorry
631 #define SLAVE_SSP_DSS 0x07 << 0
632 #define SLAVE_SSP_FRF 0x00 << 4
633 #define SLAVE_SSP_CPOL 0x00 << 6
634 #define SLAVE_SSP_CPHA 0x01 << 7
635 #define SLAVE_SSP_SCR 0x0F << 8
638 #define SLAVE_SSP_LBM 0x00 << 0
639 #define SLAVE_SSP_SSE 0x00 << 1
640 #define SLAVE_SSP_MS 0x01 << 2
641 #define SLAVE_SSP_SOD 0x00 << 3
643 void spi1_slave_ISR(
void) __attribute__((naked));
645 void spi1_slave_ISR(
void)
655 void spi1_slave_arch_init(
void)
664 SSPCR0 = SLAVE_SSP_DSS | SLAVE_SSP_FRF | SLAVE_SSP_CPOL | SLAVE_SSP_CPHA | SLAVE_SSP_SCR;
665 SSPCR1 = SLAVE_SSP_LBM | SLAVE_SSP_MS | SLAVE_SSP_SOD;
static void SpiDisable(struct spi_periph *p)
enum SPIClockPolarity cpol
clock polarity control
bool spi_slave_register(struct spi_periph *p, struct spi_transaction *t)
Register one (and only one) transaction to use spi as slave.
static void SpiInitBuf(struct spi_periph *p, struct spi_transaction *t)
#define SPI_SELECT_SLAVE1_PINSEL
static void SpiRead(struct spi_periph *p, uint16_t *c)
uint16_t output_length
number of data words to write
SPIDataSizeSelect
SPI data word size of transfer.
static void SpiDisableRxi(struct spi_periph *p)
slave is selected before transaction but not unselected
static void SpiAutomaton(struct spi_periph *p)
void spi1_arch_init(void)
Architecture dependent SPI1 initialization.
slave is not selected but unselected after transaction
static void SpiClearCPHA(struct spi_periph *p)
#define MASTER_SSP_FRF
frame format : SPI
static void SpiStart(struct spi_periph *p, struct spi_transaction *t)
static void SpiClearRti(struct spi_periph *p)
static void SpiSetCPHA(struct spi_periph *p)
static void SpiSlaveSelect(uint8_t slave)
static void SpiSetDataSize(struct spi_periph *p, enum SPIDataSizeSelect dss)
Set the SPI data size to 8 or 16bit.
SPI transaction structure.
bool spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit SPI transaction.
#define SSPCPSR_VAL
Clock prescaler.
static void SpiReceive(struct spi_periph *p, struct spi_transaction *t)
#define MASTER_SSP_SCR
serial clock rate : divide by 16
static void SpiEnableTxi(struct spi_periph *p)
static void SpiClearCPOL(struct spi_periph *p)
volatile uint8_t suspend
control for stop/resume of the fifo
static void SpiTransmit(struct spi_periph *p, struct spi_transaction *t)
#define SPI_SELECT_SLAVE0_IODIR
static void SpiEnableRti(struct spi_periph *p)
#define MASTER_SSP_CPOL
clock polarity : SCK idles low
#define MASTER_SSP_CPHA
clock phase : data captured on first clock transition
Architecture independent SPI (Serial Peripheral Interface) API.
enum SPIClockPhase cpha
clock phase control
#define SPI_SELECT_SLAVE0_PINSEL_BIT
bool spi_lock(struct spi_periph *p, uint8_t slave)
spi_lock() function
SPI peripheral structure.
#define SPI_SELECT_SLAVE0_PIN
void spi_slave_unselect(uint8_t slave)
spi_slave_unselect() function
#define SPI_SELECT_SLAVE1_IOCLR
static void SpiEnable(struct spi_periph *p)
#define SPI_SELECT_SLAVE1_PINSEL_BIT
SPICallback after_cb
NULL or function called after the transaction.
static void SpiSetCPOL(struct spi_periph *p)
bool spi_slave_wait(struct spi_periph *p)
Initialized and wait for the next transaction.
#define SPI_SELECT_SLAVE1_PIN
#define SPI_SELECT_SLAVE0_IOSET
#define MASTER_SSP_MS
master slave mode : master
static void SpiSlaveUnselect(uint8_t slave)
uint16_t input_length
number of data words to read
enum SPIStatus status
internal state of the peripheral
static void SpiEnableRxi(struct spi_periph *p)
static void SpiEndOfTransaction(struct spi_periph *p, struct spi_transaction *t)
#define MASTER_SSP_LBM
loopback mode : disabled
unsigned disableIRQ(void)
bool spi_resume(struct spi_periph *p, uint8_t slave)
spi_resume() function
slave is selected before transaction and unselected after
#define SPI_SELECT_SLAVE0_PINSEL
#define MASTER_SSP_SOD
slave output disable : don't care when master
#define SPI_SELECT_SLAVE0_IOCLR
uint8_t trans_extract_idx
enum SPIDataSizeSelect dss
data transfer word size
static void SpiSend(struct spi_periph *p, uint16_t c)
#define SPI1_VIC_SLOT
default initial settings
static void SpiSlaveStart(struct spi_periph *p, struct spi_transaction *t)
static void SpiDisableRti(struct spi_periph *p)
#define SPI_SELECT_SLAVE1_IODIR
#define SPI_TRANSACTION_QUEUE_LEN
SPI transaction queue length.
#define SPI_SELECT_SLAVE1_IOSET
void spi_init_slaves(void)
spi_init_slaves() function
#define MASTER_SSP_DSS
data size : 8 bits
void spi_slave_select(uint8_t slave)
spi_slave_select() function
#define SPI_SELECT_SLAVE0_PINSEL_VAL
static void SpiDisableTxi(struct spi_periph *p)
void spi0_arch_init(void)
Architecture dependent SPI0 initialization.
struct spi_transaction * trans[SPI_TRANSACTION_QUEUE_LEN]
circular buffer holding transactions
process_rx_dma_interrupt & spi1
receive transferred over DMA
static void SpiSlaveAutomaton(struct spi_periph *p)
enum SPITransactionStatus status
#define SPI_SELECT_SLAVE1_PINSEL_VAL