示例#1
0
/*********************************************************************//**
 * @brief 		SPI 	Read write data function
 * @param[in]	SPIx 	Pointer to SPI peripheral, should be 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;

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

	if (xfType == SPI_TRANSFER_POLLING){

		if (spidat.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 (spidat.dataword == 0){
					SPI_SendData(SPIx, 0xFF);
				} else {
					SPI_SendData(SPIx, 0xFFFF);
				}
			} else {
				if (spidat.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 (spidat.dataword == 0){
					*(rdata8) = (uint8_t) temp;
					rdata8++;
				} else {
					*(rdata16) = (uint16_t) temp;
					rdata16++;
				}
			}
			// Increase counter
			if (spidat.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 {
		spidat.txrx_setup = (uint32_t)dataCfg;
		spidat.inthandler = SPI_IntHandler;

		// 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 (spidat.dataword == 0){
					SPI_SendData(SPIx, 0xFF);
				} else {
					SPI_SendData(SPIx, 0xFFFF);
				}
			} else {
				if (spidat.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 		Standard Private SPI Interrupt handler
 * @param[in]	None
 * @return 		None
 ***********************************************************************/
void SPI_IntHandler(void)
{
	SPI_DATA_SETUP_Type *xf_setup;
    uint16_t tmp;
    xf_setup = (SPI_DATA_SETUP_Type *)spidat.txrx_setup;
    CS_Force(1);
    /* Dummy read to clear SPI interrupt flag */
    if (LPC_SPI->SPINT & SPI_SPINT_INTFLAG){
    	LPC_SPI->SPINT = SPI_SPINT_INTFLAG;
    }

    // save status
    tmp = LPC_SPI->SPSR;
    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);
    	if (xf_setup->callback != NULL){
    		xf_setup->callback();
    	}
    	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 (spidat.dataword == 0){
//				*(uint8_t *)(xf_setup->rx_data + xf_setup->counter) = (uint8_t) tmp;
//			} else {
//				*(uint16_t *)(xf_setup->rx_data + xf_setup->counter) = (uint8_t) tmp;
//			}
			if (spidat.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;
			}
		}
        if (xf_setup->rd_length) {
            xf_setup->rd_length--;        
        }
        if(xf_setup->rd_length==0)
        {
            xf_setup->rx_data = NULL;
        }
        
        /*
        if (!(GPIO_ReadValue(0) & (1<<3))||(xf_setup->tx_data != NULL)) {
            if (spidat.dataword == 0){
                xf_setup->counter++;
            } else {
                xf_setup->counter += 2;
            }
        }*/
        
        if ((xf_setup->rd_length == 0) && (xf_setup->wr_length == 0)) {
            xf_setup->counter = xf_setup->length;
        }
        else {
            // Increase counter
            if (spidat.dataword == 0){
                xf_setup->counter++;
            } else {
                xf_setup->counter += 2;
            }
        }
    }

    if (xf_setup->counter < xf_setup->length) {
        
        if (xf_setup->wr_length) {
            xf_setup->wr_length--;
        }
        if(xf_setup->wr_length==0)
        {
            xf_setup->tx_data = NULL;
        }
		// Write data to buffer
		if(xf_setup->tx_data == NULL){
			if (spidat.dataword == 0){
				SPI_SendData(LPC_SPI, 0xFF);
			} else {
				SPI_SendData(LPC_SPI, 0xFFFF);
			}
		} else {
//			if (spidat.dataword == 0){
//				SPI_SendData(SPI, (*(uint8_t *)(xf_setup->tx_data + xf_setup->counter)));
//			} else {
//				SPI_SendData(SPI, (*(uint16_t *)(xf_setup->tx_data + xf_setup->counter)));
//			}
			if (spidat.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);
    	if (xf_setup->callback != NULL){
    		xf_setup->callback();
    	}
	}
}
示例#3
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;
	}
}