Пример #1
0
/*********************************************************************//**
 * @brief 		SPI 	Read write data function
 * @param[in]	SPIx 	Pointer to SPI peripheral, should be LPC_SPI
 * @param[in]	dataCfg	Pointer to a SPI_DATA_SETUP_Type structure that
 * 						contains specified information about transmit
 * 						data configuration.
 * @param[in]	xfType	Transfer type, should be:
 * 						- SPI_TRANSFER_POLLING: Polling mode
 * 						- SPI_TRANSFER_INTERRUPT: Interrupt mode
 * @return 		Actual Data length has been transferred in polling mode.
 * 				In interrupt mode, always return (0)
 * 				Return (-1) if error.
 * Note: This function can be used in both master and slave mode.
 ***********************************************************************/
int32_t SPI_ReadWrite (LPC_SPI_TypeDef *SPIx, SPI_DATA_SETUP_Type *dataCfg, \
						SPI_TRANSFER_Type xfType)
{
	uint8_t *rdata8;
    uint8_t *wdata8;
	uint16_t *rdata16;
    uint16_t *wdata16;
    uint32_t stat;
    uint32_t temp;
    uint8_t dataword;

	//read for empty buffer
	temp = SPIx->SPDR;
	//dummy to clear status
	temp = SPIx->SPSR;
	dataCfg->counter = 0;
	dataCfg->status = 0;

	if(SPI_GetDataSize (SPIx) == 8)
		dataword = 0;
	else dataword = 1;
	if (xfType == SPI_TRANSFER_POLLING){

		if (dataword == 0){
			rdata8 = (uint8_t *)dataCfg->rx_data;
			wdata8 = (uint8_t *)dataCfg->tx_data;
		} else {
			rdata16 = (uint16_t *)dataCfg->rx_data;
			wdata16 = (uint16_t *)dataCfg->tx_data;
		}

		while(dataCfg->counter < dataCfg->length)
		{
			// Write data to buffer
			if(dataCfg->tx_data == NULL){
				if (dataword == 0){
					SPI_SendData(SPIx, 0xFF);
				} else {
					SPI_SendData(SPIx, 0xFFFF);
				}
			} else {
				if (dataword == 0){
					SPI_SendData(SPIx, *wdata8);
					wdata8++;
				} else {
					SPI_SendData(SPIx, *wdata16);
					wdata16++;
				}
			}
			// Wait for transfer complete
			while (!((stat = SPIx->SPSR) & SPI_SPSR_SPIF));
			// Check for error
			if (stat & (SPI_SPSR_ABRT | SPI_SPSR_MODF | SPI_SPSR_ROVR | SPI_SPSR_WCOL)){
				// save status
				dataCfg->status = stat | SPI_STAT_ERROR;
				return (dataCfg->counter);
			}
			// Read data from SPI dat
			temp = (uint32_t) SPI_ReceiveData(SPIx);

			// Store data to destination
			if (dataCfg->rx_data != NULL)
			{
				if (dataword == 0){
					*(rdata8) = (uint8_t) temp;
					rdata8++;
				} else {
					*(rdata16) = (uint16_t) temp;
					rdata16++;
				}
			}
			// Increase counter
			if (dataword == 0){
				dataCfg->counter++;
			} else {
				dataCfg->counter += 2;
			}
		}

		// Return length of actual data transferred
		// save status
		dataCfg->status = stat | SPI_STAT_DONE;
		return (dataCfg->counter);
	}
	// Interrupt mode
	else {

		// Check if interrupt flag is already set
		if(SPIx->SPINT & SPI_SPINT_INTFLAG){
			SPIx->SPINT = SPI_SPINT_INTFLAG;
		}
		if (dataCfg->counter < dataCfg->length){
			// Write data to buffer
			if(dataCfg->tx_data == NULL){
				if (dataword == 0){
					SPI_SendData(SPIx, 0xFF);
				} else {
					SPI_SendData(SPIx, 0xFFFF);
				}
			} else {
				if (dataword == 0){
					SPI_SendData(SPIx, (*(uint8_t *)dataCfg->tx_data));
				} else {
					SPI_SendData(SPIx, (*(uint16_t *)dataCfg->tx_data));
				}
			}
			SPI_IntCmd(SPIx, ENABLE);
		} else {
			// Save status
			dataCfg->status = SPI_STAT_DONE;
		}
		return (0);
	}
}
Пример #2
0
/*********************************************************************//**
 * @brief 		SPI Interrupt used for reading and writing handler
 * @param		None
 * @return 		None
 ***********************************************************************/
void SPI_IRQHandler(void)
{
	SPI_DATA_SETUP_Type *xf_setup;
	uint16_t tmp;
	uint8_t dataword;

	xf_setup = &xferConfig;

	if(SPI_GetDataSize(LPC_SPI) == 8)
		dataword = 0;
	else dataword = 1;

	/* Dummy read to clear SPI interrupt flag */
	SPI_ClearIntPending(LPC_SPI);

	// save status
	tmp = SPI_GetStatus(LPC_SPI);
	xf_setup->status = tmp;
	// Check for error
	if (tmp & (SPI_SPSR_ABRT | SPI_SPSR_MODF | SPI_SPSR_ROVR | SPI_SPSR_WCOL)){
		xf_setup->status |= SPI_STAT_ERROR;
		// Disable Interrupt and call call-back
		SPI_IntCmd(LPC_SPI, DISABLE);
		// Set Complete Flag
		complete = SET;
		return;
	}

	/* Check SPI complete flag */
	if (tmp & SPI_SPSR_SPIF){
	   // Read data from SPI data
		tmp = SPI_ReceiveData(LPC_SPI);
		if (xf_setup->rx_data != NULL)
		{
			if (dataword == 0){
				*(uint8_t *)((uint8_t *)(xf_setup->rx_data) + xf_setup->counter) = (uint8_t) tmp;
			} else {
				*(uint16_t *)((uint8_t *)(xf_setup->rx_data) + xf_setup->counter) = (uint8_t) tmp;
			}
		}
		// Increase counter
		if (dataword == 0){
			xf_setup->counter++;
		} else {
			xf_setup->counter += 2;
		}
	}

	if (xf_setup->counter < xf_setup->length){
		// Write data to buffer
		if(xf_setup->tx_data == NULL){
			if (dataword == 0){
				SPI_SendData(LPC_SPI, 0xFF);
			} else {
				SPI_SendData(LPC_SPI, 0xFFFF);
			}
		} else {
			if (dataword == 0){
				SPI_SendData(LPC_SPI, (*(uint8_t *)((uint8_t *)(xf_setup->tx_data) + xf_setup->counter)));
			} else {
				SPI_SendData(LPC_SPI, (*(uint16_t *)((uint8_t *)(xf_setup->tx_data) + xf_setup->counter)));
			}
		}
	}
	// No more data to send
	else {
		xf_setup->status |= SPI_STAT_DONE;
		// Disable Interrupt and call call-back
		SPI_IntCmd(LPC_SPI, DISABLE);
		// Set Complete Flag
		complete = SET;
	}
}