static void sspdrv_read_irq_handler(int port_num) { uint32_t data; mdev_t *dev = &mdev_ssp[port_num]; sspdev_data_t *ssp_data_p; ssp_data_p = (sspdev_data_t *) dev->private_data; while (SSP_GetStatus(dev->port_id, SSP_STATUS_RFNE) == SET) { /* Discard data from rx fifo only when HW-FIFO is full*/ if (SSP_GetStatus(dev->port_id, SSP_STATUS_RFOR)) { SSP_LOG("FIFO overrrun\r\n"); SSP_IntClr(dev->port_id , SSP_INT_RFORI); /* Empty entire FIFO when FIFO overrun is detected */ while (SSP_GetStatus(dev->port_id, SSP_STATUS_RFNE) == SET) data = SSP_RecvData(dev->port_id); break; } /* Read data from HW-FIFO to user allocated buffer * if buffer is not full */ if (!is_rx_buf_full(ssp_data_p)) { data = SSP_RecvData(dev->port_id); write_rx_buf(ssp_data_p, (uint8_t)data); } else { break; } } }
/******************************************************************************* * Function Name : WR_CMD * Description : 向 ADS7843写数据 * Input : - cmd: 传输的数据 * Output : None * Return : None * Attention : None *******************************************************************************/ static uint8_t WR_CMD (uint8_t cmd) { /* wait for current SSP activity complete */ while (SSP_GetStatus(LPC_SSP0, SSP_STAT_BUSY) == SET); SSP_SendData(LPC_SSP0, (uint16_t) cmd); while (SSP_GetStatus(LPC_SSP0, SSP_STAT_RXFIFO_NOTEMPTY) == RESET); return (SSP_ReceiveData(LPC_SSP0)); }
/******************************************************************************* * Function Name : LPC17xx_SPI_SendRecvByte * Description : Send one byte then recv one byte of response * Input : - byte_s: byte_s * Output : None * Return : None * Attention : None *******************************************************************************/ uint8_t LPC17xx_SPI_SendRecvByte (uint8_t byte_s) { /* wait for current SSP activity complete */ while (SSP_GetStatus(LPC_SSP0, SSP_STAT_TXFIFO_NOTFULL) == RESET); SSP_SendData(LPC_SSP0, (uint16_t) byte_s); while (SSP_GetStatus(LPC_SSP0, SSP_STAT_RXFIFO_NOTEMPTY) == RESET); return (SSP_ReceiveData(LPC_SSP0)); //return 1; }
/******************************************************************************* * Function Name : LPC17xx_SPI_SendRecvByte * Description : Send one byte then recv one byte of response * Input : - byte_s: byte_s * Output : None * Return : None * Attention : None *******************************************************************************/ uint8_t LPC17xx_SPI_SendRecvByte (uint8_t byte_s) { uint32_t timeout = 0xFFFFFF; /* wait for current SSP activity complete */ while ((SSP_GetStatus(RTC_FLASH_SSP, SSP_STAT_BUSY) == SET )); //SSP_SendData(RTC_FLASH_SSP, (uint16_t) byte_s); RTC_FLASH_SSP->DR = byte_s; while ((SSP_GetStatus(RTC_FLASH_SSP, SSP_STAT_RXFIFO_NOTEMPTY) == RESET)); return RTC_FLASH_SSP->DR; //return (SSP_ReceiveData(RTC_FLASH_SSP)); }
/***************************************************************************** * Function Name : Flash_ReadWriteByte * Description : send a byte to SST25VF016B * Input : - data: send data * Output : None * Return : return data * Attention : None *******************************************************************************/ uint8_t SPI_ReadByte(uint8_t* data) { uint16_t tmp; while ((SSP_GetStatus(RTC_FLASH_SSP, SSP_STAT_RXFIFO_NOTEMPTY) == SET )) { tmp = SSP_ReceiveData(RTC_FLASH_SSP); } SSP_SendData(RTC_FLASH_SSP, (uint16_t) 0xFFFF); while ((SSP_GetStatus(RTC_FLASH_SSP, SSP_STAT_RXFIFO_NOTEMPTY) == RESET )) { } tmp = SSP_ReceiveData(RTC_FLASH_SSP); return tmp; }
/*********************************************************************//** * @brief Send respond to master in slave mode * @param[in] None * @return None **********************************************************************/ void ssp_MW_SendRSP(LPC_SSP_TypeDef *SSPx, uint16_t Rsp) { // wait for current SSP activity complete while (SSP_GetStatus(SSPx, SSP_STAT_BUSY) == SET); SSP_SendData(SSPx, Rsp); }
/*********************************************************************//** * @brief Get command from master in slave mode * @param[in] None * @return None **********************************************************************/ uint8_t ssp_MW_GetCMD(LPC_SSP_TypeDef *SSPx) { // Wait for coming CMD while (SSP_GetStatus(SSPx, SSP_STAT_RXFIFO_NOTEMPTY) == RESET); return ((uint8_t)(SSP_ReceiveData(SSPx))); }
/*********************************************************************//** * @brief Send command to slave in master mode * @param[in] None * @return None **********************************************************************/ void ssp_MW_SendCMD(LPC_SSP_TypeDef *SSPx, uint8_t cmd) { // wait for current SSP activity complete while (SSP_GetStatus(SSPx, SSP_STAT_BUSY) == SET); SSP_SendData(SSPx, (uint16_t) cmd); }
void speed_write(uint8_t data) { while (SSP_GetStatus(LPC_SSP0, SSP_STAT_TXFIFO_NOTFULL) == RESET); SSP_SendData(LPC_SSP0, (uint16_t) data); }
inline void WaitForSend(void){ while(SSP_GetStatus(LED_SPI_CHN,SSP_STAT_BUSY)){ #if 0 for(uint32_t i=0;i<20;i++){ asm("mov r0,r0"); } #endif } // while(!SSP_GetStatus(LED_SPI_CHN,SSP_STAT_TXFIFO_EMPTY)); }
static int ssp_drv_pio_read(mdev_t *dev, uint8_t *data, uint32_t num) { int len = 0; sspdev_data_t *ssp_data_p; ssp_data_p = (sspdev_data_t *) dev->private_data; if (ssp_data_p->slave == SSP_SLAVE) { while (num > 0) { if (!is_rx_buf_empty(ssp_data_p)) *data = (uint8_t)read_rx_buf(ssp_data_p); else break; num--; len++; data++; } } else { /* In master mode, first send dummy data in TX line and read * simultaneously. If nothing is on RX line then it can read * 0x0 or 0xff. Application should check whether data is * vaild or not. */ while (num > 0) { while (SSP_GetStatus(dev->port_id, SSP_STATUS_TFNF) != SET) os_thread_relinquish(); SSP_SendData(dev->port_id, SPI_DUMMY_BYTE); while (SSP_GetStatus(dev->port_id, SSP_STATUS_RFNE) != SET) os_thread_relinquish(); *data = (uint8_t)SSP_RecvData(dev->port_id); data++; len++; num--; } } return len; }
/* * This is a bit special SPI method. * - Pulses Asserts SSEL (CS) and holds high for the duration of command. * - Does not pulse SSEL between bytes. * - Does not change SSEL after the write. */ void SPI_Write(const uint8_t *data, uint16_t len) { if (len == 0) return; while (SSP_GetStatus(CL632_SPI, SSP_STAT_TXFIFO_EMPTY) == RESET); // Send reset. GPIO_ResetBits(CL632_SSEL_PORT, CL632_SSEL_PIN); delay_ns(100); GPIO_SetBits(CL632_SSEL_PORT, CL632_SSEL_PIN); delay_ns(100); while (len-- > 0) { SSP_SendData(CL632_SPI, *data++); while (SSP_GetStatus(CL632_SPI, SSP_STAT_TXFIFO_NOTFULL) == RESET); } while (SSP_GetStatus(CL632_SPI, SSP_STAT_TXFIFO_EMPTY) == RESET); delay_ns(100); }
/*********************************************************************//** * @brief SSP Read write in polling mode function (Slave mode) * @param[in] SSPdev: Pointer to SSP device * @param[out] rbuffer: pointer to read buffer * @param[in] wbuffer: pointer to write buffer * @param[in] length: length of data to read and write * @return 0 if there no data to send, otherwise return 1 ***********************************************************************/ int32_t ssp_SlaveReadWrite (LPC_SSP_TypeDef *SSPx, void *rbuffer, void *wbuffer, uint32_t length) { uint16_t tmp; pRdBuf_S = (uint8_t *) rbuffer; pWrBuf_S = (uint8_t *) wbuffer; DatLen_S = length; RdIdx_S = 0; WrIdx_S = 0; // wait for current SSP activity complete while (SSP_GetStatus(SSPx, SSP_STAT_BUSY)) { tmp = SSP_ReceiveData(SSPx); } /* Clear all remaining data in RX FIFO */ while (SSP_GetStatus(SSPx, SSP_STAT_RXFIFO_NOTEMPTY)) { tmp = SSP_ReceiveData(SSPx); } #if (USEDSSPDEV_S == 0) if (length != 0) { SSP0_IRQHandler(); } #endif #if (USEDSSPDEV_S == 1) if (length != 0) { SSP1_IRQHandler(); } #endif // Return 0 return 0; }
/***************************************************************************** * Function Name : Flash_ReadWriteByte * Description : send a byte to SST25VF016B * Input : - data: send data * Output : None * Return : return data * Attention : None *******************************************************************************/ void SPI_WriteByte(uint8_t data) { while ((SSP_GetStatus(RTC_FLASH_SSP, SSP_STAT_TXFIFO_NOTFULL) == RESET )); SSP_SendData(RTC_FLASH_SSP, (uint16_t) data); }
void TIMER0_IRQHandler(void){ // xprintf("TIMER0_IRQ"); if (TIM_GetIntStatus(LPC_TIM0,TIM_MR0_INT)){ TIM_ClearIntPending(LPC_TIM0, TIM_MR0_INT); #if 0 if(TOG[0]) // FIO_SetValue(LED_LE_PORT, LED_LE_BIT); GPIO_SetValue(LED_4_PORT, LED_4_BIT); else // FIO_ClearValue(LED_LE_PORT, LED_LE_BIT); GPIO_ClearValue(LED_4_PORT, LED_4_BIT); TOG[0]=!TOG[0]; // TIM_ClearIntPending(LPC_TIM0, TIM_MR0_INT); // return; #endif // xprintf(INFO "RIT N=%d B=%x NXT_T=%d TX=%x\n",SENDSEQ,SEND_BIT,DELAY_TIME,LED_PRECALC[0][SEND_BIT]); //Setup new timing for next Timer DELAY_TIME=SEQ_TIME[SENDSEQ]; SEND_BIT=SEQ_BIT[SENDSEQ]; //Retart sequence if required SENDSEQ++; SENDSEQ>=no_SEQ_BITS ? SENDSEQ=0 : 0; #ifdef DMA // xprintf("SEND_BIT:%d\n",SEND_BIT); // xprintf("DELAY_TIME:%d\n",DELAY_TIME); GPDMACfg.DMALLI = (uint32_t) &LinkerList[0][SEND_BIT][BufferNo]; GPDMA_Setup(&GPDMACfg); GPDMA_ChannelCmd(0, ENABLE); #endif TIM_UpdateMatchValue(LPC_TIM0,0,DELAY_TIME); FIO_SetValue(LED_OE_PORT, LED_OE_BIT); #ifdef RxDMA GPDMA_ChannelCmd(1, ENABLE); uint8_t reg; for(reg=6; 0<reg;reg--){ xprintf("%d ",reg-1); #if 0 if(BUFFER==1) SSP_SendData(LED_SPI_CHN, LED_PRECALC1[reg][SEND_BIT]); else SSP_SendData(LED_SPI_CHN, LED_PRECALC2[reg][SEND_BIT]); #endif //WaitForSend();//Wait if TX buffer full //while(LED_SPI_CHN->SR & SSP_STAT_BUSY); while(SSP_GetStatus(LED_SPI_CHN, SSP_STAT_BUSY)){ }; SSP_SendData(LED_SPI_CHN, LED_PRECALC[reg-1][SEND_BIT]); xprintf("%4x ",(LED_PRECALC[reg-1][SEND_BIT])); } for(reg=12; reg>6;reg--){ xprintf("%d ",reg-1); #if 0 if(BUFFER==1) SSP_SendData(LED_SPI_CHN, LED_PRECALC1[reg][SEND_BIT]); else SSP_SendData(LED_SPI_CHN, LED_PRECALC2[reg][SEND_BIT]); #endif //WaitForSend();//Wait if TX buffer full while(SSP_GetStatus(LED_SPI_CHN, SSP_STAT_BUSY)){ } SSP_SendData(LED_SPI_CHN, LED_PRECALC[reg-1][SEND_BIT]); // if (reg==7){ xprintf("%4x ",(LED_PRECALC[reg-1][SEND_BIT])); // } } LatchIn(); #endif /* UPDATE_COUNT+=1; ATE_COUNT=0; LED_UPDATE_REQUIRED=1; }*/ } }
static int ssp_drv_pio_write(mdev_t *dev, const uint8_t *data, uint8_t *din, uint32_t num, bool flag) { uint32_t len = 0; sspdev_data_t *ssp_data_p; ssp_data_p = (sspdev_data_t *) dev->private_data; while (num > 0) { /* Wait if fifo is full */ while (SSP_GetStatus(dev->port_id, SSP_STATUS_TFNF) != SET) os_thread_relinquish(); SSP_SendData(dev->port_id, *data); /* Enable read RXFIFO during write operation if flag is set */ if (flag) { /* read data while write operation is on to enable * full duplex support in SPI protocol*/ /* * Read rxfifo and store data, provided valid din * buffer is provided by user else discard it. */ if (ssp_data_p->slave == SSP_MASTER) { /* SSP_STATUS_BIT == SET when SSPx port is * currently transmitting or receiving framed * data. * */ while (SSP_GetStatus(dev->port_id, SSP_STATUS_BUSY) == SET) os_thread_relinquish(); /* SSP_STATUS_RFNE == SET when RXFIFO is * non-empty */ while (SSP_GetStatus(dev->port_id, SSP_STATUS_RFNE) != SET) os_thread_relinquish(); if (din) *din++ = (uint8_t) SSP_RecvData(dev->port_id); else SSP_RecvData(dev->port_id); } else { /* if slave mode is enabled read from software * fifo*/ while (is_rx_buf_empty(ssp_data_p) == true) os_thread_relinquish(); if (!is_rx_buf_empty(ssp_data_p) && din) *din++ = (uint8_t) read_rx_buf(ssp_data_p); } } data++; num--; len++; } return len; }
static void sendSPI(byte data) { WriteSPDR (data); while (SSP_GetStatus(SSP, SSP_STAT_BUSY)) ; }
/*********************************************************************//** * @brief c_entry: Main MICROWIRE program body * @param[in] None * @return int **********************************************************************/ int c_entry(void) { uint32_t cnt; PINSEL_CFG_Type PinCfg; /* Initialize debug via UART0 * – 115200bps * – 8 data bit * – No parity * – 1 stop bit * – No flow control */ debug_frmwrk_init(); // print welcome screen print_menu(); /* * Initialize SSP pin connect * P0.6 - SSEL1 * P0.7 - SCK1 * P0.8 - MISO1 * P0.9 - MOSI1 */ PinCfg.Funcnum = 2; PinCfg.OpenDrain = 0; PinCfg.Pinmode = 0; PinCfg.Portnum = 0; PinCfg.Pinnum = 6; PINSEL_ConfigPin(&PinCfg); PinCfg.Pinnum = 7; PINSEL_ConfigPin(&PinCfg); PinCfg.Pinnum = 8; PINSEL_ConfigPin(&PinCfg); PinCfg.Pinnum = 9; PINSEL_ConfigPin(&PinCfg); /* * Initialize SSP pin connect * P0.15 - SCK * P0.16 - SSEL * P0.17 - MISO * P0.18 - MOSI */ PinCfg.Funcnum = 2; PinCfg.OpenDrain = 0; PinCfg.Pinmode = 0; PinCfg.Portnum = 0; PinCfg.Pinnum = 15; PINSEL_ConfigPin(&PinCfg); PinCfg.Pinnum = 17; PINSEL_ConfigPin(&PinCfg); PinCfg.Pinnum = 18; PINSEL_ConfigPin(&PinCfg); PinCfg.Pinnum = 16; PINSEL_ConfigPin(&PinCfg); /* Initializing Master SSP device section ------------------------------------------- */ // initialize SSP configuration structure to default SSP_ConfigStructInit(&SSP_ConfigStruct); // Re-configure SSP to MicroWire frame format SSP_ConfigStruct.FrameFormat = SSP_FRAME_MICROWIRE; // Initialize SSP peripheral with parameter given in structure above SSP_Init(SSPDEV_M, &SSP_ConfigStruct); // Enable SSP peripheral SSP_Cmd(SSPDEV_M, ENABLE); /* Initializing Slave SSP device section ------------------------------------------- */ // initialize SSP configuration structure to default SSP_ConfigStructInit(&SSP_ConfigStruct); /* Re-configure mode for SSP device */ SSP_ConfigStruct.Mode = SSP_SLAVE_MODE; // Re-configure SSP to MicroWire frame format SSP_ConfigStruct.FrameFormat = SSP_FRAME_MICROWIRE; // Initialize SSP peripheral with parameter given in structure above SSP_Init(SSPDEV_S, &SSP_ConfigStruct); // Enable SSP peripheral SSP_Cmd(SSPDEV_S, ENABLE); /* Initializing Buffer section ------------------------------------------------- */ Buffer_Init(); /* Start Transmit/Receive between Master and Slave ----------------------------- */ pRdBuf_M = (uint8_t *)&Master_Rx_Buf[0]; RdIdx_M = 0; DatLen_M = BUFFER_SIZE; pWrBuf_S = (uint8_t *)&Slave_Tx_Buf[0]; WrIdx_S = 0; DatLen_S = BUFFER_SIZE; /* Force Last command to Read command as default */ Last_cmd = MicroWire_RD_CMD; /* Clear all remaining data in RX FIFO */ while (SSP_GetStatus(SSPDEV_M, SSP_STAT_RXFIFO_NOTEMPTY)) { SSP_ReceiveData(SSPDEV_M); } while (SSP_GetStatus(SSPDEV_S, SSP_STAT_RXFIFO_NOTEMPTY)) { SSP_ReceiveData(SSPDEV_S); } for (cnt = 0; cnt < BUFFER_SIZE; cnt++) { /* The slave must initialize data in FIFO for immediately transfer from master * due to last received command */ if (Last_cmd == MicroWire_RD_CMD) { // Then send the respond to master, this contains data ssp_MW_SendRSP(SSPDEV_S, (uint16_t) *(pWrBuf_S + WrIdx_S++)); } else { // Then send the respond to master, this contains data ssp_MW_SendRSP(SSPDEV_S, 0xFF); } /* Master must send a read command to slave, * the slave then respond with its data in FIFO */ ssp_MW_SendCMD(SSPDEV_M, MicroWire_RD_CMD); // Master receive respond *(pRdBuf_M + RdIdx_M++) = (uint8_t) ssp_MW_GetRSP(SSPDEV_M); // Re-assign Last command Last_cmd = ssp_MW_GetCMD(SSPDEV_S); } /* Verify buffer */ Buffer_Verify(); _DBG_("Verify success!\n\r"); /* Loop forever */ while(1); return 1; }
/*********************************************************************//** * @brief Get respond from slave after sending a command in master mode * @param[in] None * @return None **********************************************************************/ uint16_t ssp_MW_GetRSP(LPC_SSP_TypeDef *SSPx) { while (SSP_GetStatus(SSPx, SSP_STAT_RXFIFO_NOTEMPTY) == RESET); return (SSP_ReceiveData(SSPx)); }
/*********************************************************************//** * @brief SSP Slave Interrupt sub-routine used for reading * and writing handler * @param None * @return None ***********************************************************************/ void ssp_Slave_IntHandler(void) { uint16_t tmp; /* Clear all interrupt */ SSP_ClearIntPending(SSPDEV_S, SSP_INTCLR_ROR); SSP_ClearIntPending(SSPDEV_S, SSP_INTCLR_RT); /* check if RX FIFO contains data */ while (SSP_GetStatus(SSPDEV_S, SSP_STAT_RXFIFO_NOTEMPTY) == SET) { tmp = SSP_ReceiveData(SSPDEV_S); if ((pRdBuf_S!= NULL) && (RdIdx_S < DatLen_S)) { *(pRdBuf_S + RdIdx_S) = (uint8_t) tmp; } RdIdx_S++; } /* Check if TX FIFO is not full */ while ((SSP_GetStatus(SSPDEV_S, SSP_STAT_TXFIFO_NOTFULL) == SET) && (WrIdx_S < DatLen_S)) { /* check if RX FIFO contains data */ while (SSP_GetStatus(SSPDEV_S, SSP_STAT_RXFIFO_NOTEMPTY) == SET) { tmp = SSP_ReceiveData(SSPDEV_S); if ((pRdBuf_S!= NULL) && (RdIdx_S < DatLen_S)) { *(pRdBuf_S + RdIdx_S) = (uint8_t) tmp; } RdIdx_S++; } if (pWrBuf_S != NULL) { SSP_SendData(SSPDEV_S, (uint16_t)(*(pWrBuf_S + WrIdx_S))); } else { SSP_SendData(SSPDEV_S, IDLE_CHAR); } WrIdx_S++; } /* There're more data to send */ if (WrIdx_S < DatLen_S) { SSP_IntConfig(SSPDEV_S, SSP_INTCFG_TX, ENABLE); } /* Otherwise */ else { SSP_IntConfig(SSPDEV_S, SSP_INTCFG_TX, DISABLE); } /* There're more data to receive */ if (RdIdx_S < DatLen_S) { SSP_IntConfig(SSPDEV_S, SSP_INTCFG_ROR, ENABLE); SSP_IntConfig(SSPDEV_S, SSP_INTCFG_RT, ENABLE); SSP_IntConfig(SSPDEV_S, SSP_INTCFG_RX, ENABLE); } /* Otherwise */ else { SSP_IntConfig(SSPDEV_S, SSP_INTCFG_ROR, DISABLE); SSP_IntConfig(SSPDEV_S, SSP_INTCFG_RT, DISABLE); SSP_IntConfig(SSPDEV_S, SSP_INTCFG_RX, DISABLE); } /* Set Flag if both Read and Write completed */ if ((WrIdx_S == DatLen_S) && (RdIdx_S == DatLen_S)) { complete_S = TRUE; } }
/*********************************************************************//** * @brief SSP0 Interrupt used for reading and writing handler * @param None * @return None ***********************************************************************/ void SSP0_IRQHandler(void) { SSP_DATA_SETUP_Type *xf_setup; uint16_t tmp; uint8_t dataword; // Disable all SSP interrupts SSP_IntConfig(LPC_SSP0, SSP_INTCFG_ROR|SSP_INTCFG_RT|SSP_INTCFG_RX|SSP_INTCFG_TX, DISABLE); if(SSP_GetDataSize(LPC_SSP0)>8) dataword = 1; else dataword = 0; xf_setup = &xferConfig; // save status tmp = SSP_GetRawIntStatusReg(LPC_SSP0); xf_setup->status = tmp; // Check overrun error if (tmp & SSP_RIS_ROR){ // Clear interrupt SSP_ClearIntPending(LPC_SSP0, SSP_INTCLR_ROR); // update status xf_setup->status |= SSP_STAT_ERROR; // Set Complete Flag complete = SET; return; } if ((xf_setup->tx_cnt != xf_setup->length) || (xf_setup->rx_cnt != xf_setup->length)){ /* check if RX FIFO contains data */ while ((SSP_GetStatus(LPC_SSP0, SSP_STAT_RXFIFO_NOTEMPTY)) && (xf_setup->rx_cnt != xf_setup->length)){ // Read data from SSP data tmp = SSP_ReceiveData(LPC_SSP0); // Store data to destination if (xf_setup->rx_data != NULL) { if (dataword == 0){ *(uint8_t *)((uint32_t)xf_setup->rx_data + xf_setup->rx_cnt) = (uint8_t) tmp; } else { *(uint16_t *)((uint32_t)xf_setup->rx_data + xf_setup->rx_cnt) = (uint16_t) tmp; } } // Increase counter if (dataword == 0){ xf_setup->rx_cnt++; } else { xf_setup->rx_cnt += 2; } } while ((SSP_GetStatus(LPC_SSP0, SSP_STAT_TXFIFO_NOTFULL)) && (xf_setup->tx_cnt != xf_setup->length)){ // Write data to buffer if(xf_setup->tx_data == NULL){ if (dataword == 0){ SSP_SendData(LPC_SSP0, 0xFF); xf_setup->tx_cnt++; } else { SSP_SendData(LPC_SSP0, 0xFFFF); xf_setup->tx_cnt += 2; } } else { if (dataword == 0){ SSP_SendData(LPC_SSP0, (*(uint8_t *)((uint32_t)xf_setup->tx_data + xf_setup->tx_cnt))); xf_setup->tx_cnt++; } else { SSP_SendData(LPC_SSP0, (*(uint16_t *)((uint32_t)xf_setup->tx_data + xf_setup->tx_cnt))); xf_setup->tx_cnt += 2; } } // Check overrun error if (SSP_GetRawIntStatus(LPC_SSP0, SSP_INTSTAT_RAW_ROR)){ // update status xf_setup->status |= SSP_STAT_ERROR; // Set Complete Flag complete = SET; return; } // Check for any data available in RX FIFO while ((SSP_GetStatus(LPC_SSP0, SSP_STAT_RXFIFO_NOTEMPTY)) && (xf_setup->rx_cnt != xf_setup->length)){ // Read data from SSP data tmp = SSP_ReceiveData(LPC_SSP0); // Store data to destination if (xf_setup->rx_data != NULL) { if (dataword == 0){ *(uint8_t *)((uint32_t)xf_setup->rx_data + xf_setup->rx_cnt) = (uint8_t) tmp; } else { *(uint16_t *)((uint32_t)xf_setup->rx_data + xf_setup->rx_cnt) = (uint16_t) tmp; } } // Increase counter if (dataword == 0){ xf_setup->rx_cnt++; } else { xf_setup->rx_cnt += 2; } } } } // If there more data to sent or receive if ((xf_setup->rx_cnt != xf_setup->length) || (xf_setup->tx_cnt != xf_setup->length)){ // Enable all interrupt SSP_IntConfig(LPC_SSP0, SSP_INTCFG_ROR|SSP_INTCFG_RT|SSP_INTCFG_RX|SSP_INTCFG_TX, ENABLE); } else { // Save status xf_setup->status = SSP_STAT_DONE; // Set Complete Flag complete = SET; } }