/* Master SPI transmit in interrupt mode */ static void WriteSpiMssg(uint16_t *xferPtr, uint32_t xferSize) { SPI_PARAM_T paramRec; /* Init variable used as semaphore */ intErrCode = -1; /* Setup transfer record */ paramRec.tx_buffer = xferPtr; /* SPI TX buffer */ paramRec.size = xferSize; /* total number of SPI transfers */ paramRec.rx_buffer = rx_buff; /* SPI RX buffer */ paramRec.fsize_sel = 0x0F0E0000;/* Set Tx Control for 16 bit transfer, SSEL0 asserted */ paramRec.eof_flag = 1; /* End of Frame enabled */ paramRec.tx_rx_flag = 2; /* transmit and receive */ paramRec.driver_mode = 1; /* interrupt mode */ paramRec.dma_cfg = NULL; /* DMA configuration */ paramRec.cb = (SPI_CALLBK_T) cbSpiComplete; /* SPI completion callback */ paramRec.dma_cb = NULL; /* DMA completion callback */ /* Transfer message as SPI master via interrupt */ if (LPC_SPID_API->spi_master_transfer(spiHandleMaster, ¶mRec) != LPC_OK) { /* Signal SPI error */ errorSPI(); } /* Sleep until transfer is complete, but allow IRQ to wake system to handle SPI IRQ */ while (intErrCode == -1) { __WFI(); } }
/* Master SPI transmit in interrupt mode */ static void WriteSpiMssg(uint16_t *xferPtr, uint32_t xferSize) { /* Init variable used as semaphore */ intErrCode = -1; /* Setup Transfer structure, this data should be retained for the entire transmission */ XferSetup.pTx = xferArray; /* Transmit Buffer */ XferSetup.pRx = rx_buff;/* Receive Buffer */ XferSetup.DataSize = sizeof(xferArray[0]) * 8; /* Data size in bits */ XferSetup.Length = sizeof(xferArray) / sizeof(xferArray[0]); /* Total frame length */ /* Assert only SSEL0 */ XferSetup.ssel = SPI_TXCTL_ASSERT_SSEL0 | SPI_TXCTL_DEASSERT_SSEL1 | SPI_TXCTL_DEASSERT_SSEL2 | SPI_TXCTL_DEASSERT_SSEL3; XferSetup.TxCnt = 0; XferSetup.RxCnt = 0; if (Chip_SPI_Int_RWFrames(LPC_SPI0, &XferSetup) == ERROR) { errorSPI(); } /* Enable interrupts after initiating transmission */ Chip_SPI_Int_Cmd(LPC_SPI0, SPI_INTENSET_RXRDYEN | SPI_INTENSET_TXRDYEN | SPI_INTENSET_RXOVEN | SPI_INTENSET_TXUREN, ENABLE); /* Sleep until transfer is complete, but allow IRQ to wake system to handle SPI IRQ */ while (intErrCode == -1) { __WFI(); } }
/* SPI interrupt callback, called on completion of SPI operation when in interrupt mode. Called in interrupt context. */ static void cbSpiComplete(uint32_t err_code, uint32_t n) { uint32_t i; if ((err_code == LPC_OK) && (n == (sizeof(xferArray) / sizeof(xferArray[0])))) { /* Verify if received data is same as transmit */ for (i = 0; i < n; i++) { if (rx_buff[i] != xferArray[i]) { errorSPI(); } } intErrCode = (int) err_code; } else { /* Signal Error */ errorSPI(); } }
/* Setup SPI handle and parameters */ static void setupSpiMaster() { SPI_CONFIG_T spiConfigRec; /* Enable SPI clock and reset SPI peripheral - the boot ROM does not do this */ #if 0 Chip_SPI_IF_Init(LPC_SPI0); // FIXME - API need to be standardized to other platforms #else // FIXME - temp workaround Chip_Clock_EnableAsyncPeriphClock(ASYNC_SYSCTL_CLOCK_SPI0); Chip_SYSCTL_AsyncPeriphReset(ASYNC_RESET_SPI0); #endif /* Perform a sanity check on the storage allocation */ if (LPC_SPID_API->spi_get_mem_size() > sizeof(spiMasterHandleMEM)) { /* Example only: this should never happen and probably isn't needed for most SPI code. */ errorSPI(); } /* Setup the SPI0 handle */ spiHandleMaster = LPC_SPID_API->spi_setup(LPC_SPI0_BASE, (uint8_t *) &spiMasterHandleMEM); if (spiHandleMaster == NULL) { errorSPI(); } /* Setup SPI0 configuration record */ spiConfigRec.delay = 0x2222; /* SysClock divided is set to maximum */ spiConfigRec.divider = 0xFFFF; /* Loopback mode, master mode and SPI block enabled */ spiConfigRec.config = 0x85; spiConfigRec.error_en = 0; /* Init SPI0 */ LPC_SPID_API->spi_init(spiHandleMaster, &spiConfigRec); }
/** * @brief Handle SPI0 interrupt by calling SPI ROM handler * @return Nothing */ void SPI0_IRQHandler(void) { uint32_t i; if (XferSetup.RxCnt < XferSetup.Length) { /* Call driver function until transmission is complete */ if (Chip_SPI_Int_RWFrames(LPC_SPI0, &XferSetup) == ERROR) { errorSPI(); } } else { /* Disable interrupts after transmission is complete */ Chip_SPI_Int_Cmd(LPC_SPI0, SPI_INTENSET_RXRDYEN | SPI_INTENSET_TXRDYEN | SPI_INTENSET_RXOVEN | SPI_INTENSET_TXUREN, DISABLE); /* Verify if received data is same as transmit */ for (i = 0; i < sizeof(xferArray) / sizeof(xferArray[0]); i++) { if (rx_buff[i] != xferArray[i]) { errorSPI(); } } intErrCode = (int) LPC_OK; } }