コード例 #1
0
ファイル: myI2C.c プロジェクト: dulithag/applicationIMU
void I2C_writeSlv(const unsigned int slvAddr, const unsigned int slvReg, const unsigned int data){
	
    volatile unsigned int x_data_a = 0;	
		unsigned int Error = 0;
	
		//Waits for i2c
		I2C_waitTillDone();
			
		//Send START, Register
		I2C_setReadSlv(slvAddr,0);
		I2C_setData(slvReg,0);							
		I2C_Execute(I2C_START_EXECUTE);
		I2C_waitTillIdle();
		Error = I2C_CheckError();
		if(Error)
			UART4_DATA = 'E';
		
		//Send Data, STOP
		I2C_setData(data,0);							
		I2C_Execute(I2C_EXECUTE_STOP);
	
		
		I2C_waitTillDone();
		
		Error = I2C_CheckError();
		if(Error)
			UART4_DATA = 'E';
		
}
コード例 #2
0
ファイル: myI2C.c プロジェクト: dulithag/applicationIMU
void I2C_readSlv(const unsigned int slvAddr, const unsigned int slvReg){
	
    volatile unsigned int x_data_a = 0;	
		unsigned int Error = 0;
	
		//Waits for i2c
		I2C_waitTillDone();
			
		//Send Register
		I2C_setReadSlv(slvAddr,0);
		I2C_setData(slvReg,0);							
		I2C_sendRecieveWithStop(0);
		I2C_waitTillIdle();
		Error = I2C_CheckError();
		if(Error)
			UART4_DATA = 'E';
		
		//Receive Data
		I2C_setReadSlv(slvAddr,1);
		I2C_sendRecieveWithStop(1);
		I2C_waitTillDone();
		if(I2C_CheckError()==0){
			x_data_a = I2C0_MDR;
			UART4_DATA = x_data_a;
		}
}
コード例 #3
0
/* General Slave Interrupt handler for I2C peripheral */
void IP_I2C_Interrupt_SlaveHandler(IP_I2C_001_Type *LPC_I2C, I2C_ID_Type I2C_Num)
{
	uint32_t returnCode;
	I2C_S_SETUP_Type *txrx_setup;
	int32_t Ret = I2C_OK;

	txrx_setup = (I2C_S_SETUP_Type *) &i2cdat[I2C_Num].txrx_setup_slave;

	while (!(LPC_I2C->CONSET & I2C_I2CONSET_SI)) {}

	returnCode = (uint32_t) (LPC_I2C->STAT & I2C_STAT_CODE_BITMASK);
	/* Save current status */
	txrx_setup->status = returnCode;

	Ret = IP_I2C_SlaveHanleStates(LPC_I2C, returnCode, txrx_setup);

	if ((I2C_CheckError(Ret)) || (Ret & I2C_STA_STO_RECV) || (Ret & I2C_SEND_END)) {
		goto s_int_end;
	}
	else {
		return;
	}

s_int_end:
	LPC_I2C->CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;

	I2C_SlaveComplete[I2C_Num] = true;
}
コード例 #4
0
ファイル: myI2C.c プロジェクト: dulithag/applicationIMU
void I2C_readSlvChunk(const unsigned int slvAddr, const unsigned int startReg, const unsigned int noRegs,  char array[]){
		
		volatile char data_a = 0;
		int i=0;
	
		//Waits for i2c
		I2C_waitTillDone();
	
		//Send Register
		I2C_setReadSlv(slvAddr,0);
		I2C_setData(startReg, 1);	
		I2C_sendRecieveWithStop(0);
		//I2C_Execute(I2C_START_EXECUTE);
		I2C_waitTillIdle();
	
		I2C_setReadSlv(slvAddr,1);
		I2C_Execute(0x0B);
		for(i=0; i<noRegs; i++){
			I2C_waitTillIdle();
			if(I2C_CheckError()==0){
				data_a = I2C0_MDR;
				array[i] = data_a;
				//UART4_DATA = x_data_a;
			}
			I2C_Execute((i==noRegs-1)?I2C_EXECUTE_STOP:I2C_EXECUTE);
		}

		
}
コード例 #5
0
/* General Master Interrupt handler for I2C peripheral */
void IP_I2C_Interrupt_MasterHandler(IP_I2C_001_Type *LPC_I2C, I2C_ID_Type I2C_Num)
{
	uint32_t returnCode;
	I2C_M_SETUP_Type *txrx_setup;
	int32_t Ret = I2C_OK;

	txrx_setup = (I2C_M_SETUP_Type *) &i2cdat[I2C_Num].txrx_setup_master;

	while (!(LPC_I2C->CONSET & I2C_I2CONSET_SI)) {}

	returnCode = (uint32_t) (LPC_I2C->STAT & I2C_STAT_CODE_BITMASK);

	/* Save current status */
	txrx_setup->status = returnCode;

	Ret = IP_I2C_MasterHanleStates(LPC_I2C, returnCode, txrx_setup, I2C_TRANSFER_INTERRUPT);

	if (I2C_CheckError(Ret)) {
		if (txrx_setup->retransmissions_count < txrx_setup->retransmissions_max) {
			/* Retry */
			txrx_setup->retransmissions_count++;
			txrx_setup->tx_count = 0;
			txrx_setup->rx_count = 0;
			/* Reset STA, STO, SI */
			IP_I2C_Start(LPC_I2C, I2C_TRANSFER_INTERRUPT);
			return;
		}
		else {
			goto s_int_end;
		}
	}
	else if (Ret & I2C_SEND_END) {
		/* If no need to wait for data from Slave */
		if (txrx_setup->rx_count >= (txrx_setup->rx_length)) {
			goto s_int_end;
		}
		else {	/* Start to wait for data from Slave */
			/* Reset STA, STO, SI */
			IP_I2C_Start(LPC_I2C, I2C_TRANSFER_INTERRUPT);
			return;
		}
	}
	else if (Ret & I2C_RECV_END) {
		goto s_int_end;
	}
	else {
		return;
	}

s_int_end:

	LPC_I2C->CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;

	I2C_MasterComplete[I2C_Num] = true;
}
コード例 #6
0
ファイル: lpc8xx_i2c.c プロジェクト: AlexandreN7/Liqui_lense
/*****************************************************************************
** Function name:		I2C_MstReceive
** Descriptions:		the module will receive a block of data from 
**						the I2C.
** parameters:			Device address, buffer pointer, and block length
** Returned value:		None
** 
*****************************************************************************/
void I2C_MstReceive( LPC_I2C_TypeDef *I2Cx, uint32_t addr, uint8_t *rx, uint32_t Length )
{
  uint32_t i;

  I2Cx->MSTDAT = addr;  
  I2Cx->MSTCTL = CTL_MSTSTART;
#if I2C_INTERRUPT
  mstrxrdy = 0;
  I2Cx->INTENSET = STAT_MSTPEND;
#endif 
	for ( i = 0; i < Length; i++ )
	{
#if I2C_INTERRUPT
		while(!mstrxrdy)
		{
			if ( I2C_CheckError(I2Cx) ) {
				I2C_CheckIdle(I2Cx);
				/* Recursive call here. Be very careful with stack over flow if come here. especially
				when the other master trys to grab the bus all the time. */
//	    while ( 1 );
				I2C_MstReceive( I2Cx, addr, rx, Length );
				return;
			}
		}
		mstrxrdy = 0;
		*rx++ = I2Cx->MSTDAT;
		if ( i != Length -1 )
		{
			I2Cx->MSTCTL = CTL_MSTCONTINUE;
			I2Cx->INTENSET = STAT_MSTPEND;
		}
#else
		/* Slave address has been sent, master receive is ready. */
		while (!(I2Cx->STAT & STAT_MSTPEND));
		if((I2Cx->STAT & MASTER_STATE_MASK) != STAT_MSTRX)
			while( 1 );
		*rx++ = I2Cx->MSTDAT;
		if ( i != Length -1 )
		{
			I2Cx->MSTCTL = CTL_MSTCONTINUE;
		}
#endif
  }
  I2Cx->MSTCTL = CTL_MSTSTOP | CTL_MSTCONTINUE;
  I2C_CheckIdle(I2Cx);
  return; 
}
コード例 #7
0
/* Receive and Transmit data in slave mode */
Status IP_I2C_SlaveTransferData(IP_I2C_001_Type *LPC_I2C,
								I2C_ID_Type I2C_Num,
								I2C_S_SETUP_Type *TransferCfg,
								I2C_TRANSFER_OPT_Type Opt)
{
	int32_t   Ret = I2C_OK;
	uint32_t CodeStatus = 0;

	/* Reset I2C setup value to default state */
	TransferCfg->tx_count = 0;
	TransferCfg->rx_count = 0;
	TransferCfg->status = 0;

	/* Polling option */
	if (Opt == I2C_TRANSFER_POLLING) {
		/* Set AA bit to ACK command on I2C bus */
		LPC_I2C->CONSET = I2C_I2CONSET_AA;

		/* Clear SI bit to be ready ... */
		LPC_I2C->CONCLR = (I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC | I2C_I2CONCLR_STOC);

		while (1) {
			/* Check SI flag ready */
			if (LPC_I2C->CONSET & I2C_I2CONSET_SI) {
				CodeStatus = (LPC_I2C->STAT & I2C_STAT_CODE_BITMASK);

				Ret = IP_I2C_SlaveHanleStates(LPC_I2C, CodeStatus, TransferCfg);
				if (I2C_CheckError(Ret)) {
					goto s_error;
				}
				else if ((Ret & I2C_STA_STO_RECV) || (Ret & I2C_SEND_END)) {
					goto s_end_stage;
				}
			}
		}

s_end_stage:
		/* Clear AA bit to disable ACK on I2C bus */
		LPC_I2C->CONCLR = I2C_I2CONCLR_AAC;

		/* Check if there's no error during operation
		 * Update status
		 */
		TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_DONE;
		return SUCCESS;

s_error:
		/* Clear AA bit to disable ACK on I2C bus */
		LPC_I2C->CONCLR = I2C_I2CONCLR_AAC;

		/* Update status */
		TransferCfg->status = CodeStatus;
		return ERROR;
	}

	else if (Opt == I2C_TRANSFER_INTERRUPT) {
		I2C_SlaveComplete[I2C_Num] = false;
		/* Setup tx_rx data, callback and interrupt handler */
		i2cdat[I2C_Num].txrx_setup_slave = *TransferCfg;

		/* Set direction phase, read first */
		i2cdat[I2C_Num].dir = 1;

		/* Enable AA */
		LPC_I2C->CONSET = I2C_I2CONSET_AA;
		LPC_I2C->CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;

		return SUCCESS;
	}

	return ERROR;
}
コード例 #8
0
/* Transmit and Receive data in master mode */
Status IP_I2C_MasterTransferData(IP_I2C_001_Type *LPC_I2C,
								 I2C_ID_Type I2C_Num,
								 I2C_M_SETUP_Type *TransferCfg,
								 I2C_TRANSFER_OPT_Type Opt)
{
	uint32_t CodeStatus;
	int32_t Ret = I2C_OK;

	/* Reset I2C setup value to default state */
	TransferCfg->tx_count = 0;
	TransferCfg->rx_count = 0;
	TransferCfg->status = 0;

	if (Opt == I2C_TRANSFER_POLLING) {
		/* First Start condition -------------------------------------------------------------- */
		TransferCfg->retransmissions_count = 0;
retry:
		/* Reset I2C setup value to default state */
		TransferCfg->tx_count = 0;
		TransferCfg->rx_count = 0;

		/* Start command */
		CodeStatus = IP_I2C_Start(LPC_I2C, I2C_TRANSFER_POLLING);

		while (1) {	/* send data first and then receive data from Slave */
			Ret = IP_I2C_MasterHanleStates(LPC_I2C, CodeStatus, TransferCfg, I2C_TRANSFER_POLLING);
			if (I2C_CheckError(Ret)) {
				TransferCfg->retransmissions_count++;
				if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max) {
					/* save status */
					TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF;
					goto error;
				}
				else {
					goto retry;
				}
			}
			else if ( (Ret & I2C_BYTE_SENT) ||
					  (Ret & I2C_BYTE_RECV)) {
				/* Wait for sending ends/ Wait for next byte */
				while (!(LPC_I2C->CONSET & I2C_I2CONSET_SI)) {}
			}
			else if (Ret & I2C_SEND_END) {	/* already send all data */
				/* If no need to wait for data from Slave */
				if (TransferCfg->rx_count >= (TransferCfg->rx_length)) {
					break;
				}
				else {
					IP_I2C_Start(LPC_I2C, I2C_TRANSFER_POLLING);
				}
			}
			else if (Ret & I2C_RECV_END) {	/* already receive all data */
				break;
			}
			CodeStatus = LPC_I2C->STAT & I2C_STAT_CODE_BITMASK;
		}
		return SUCCESS;
error:
		return ERROR;
	}
	else if (Opt == I2C_TRANSFER_INTERRUPT) {
		I2C_MasterComplete[I2C_Num] = false;
		/* Setup tx_rx data, callback and interrupt handler */
		i2cdat[I2C_Num].txrx_setup_master = *TransferCfg;

		/* Set direction phase, write first */
		i2cdat[I2C_Num].dir = 0;

		/* First Start condition -------------------------------------------------------------- */
		/* Reset STA, STO, SI */
		LPC_I2C->CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STOC | I2C_I2CONCLR_STAC;
		LPC_I2C->CONSET = I2C_I2CONSET_STA;

		return SUCCESS;
	}

	return ERROR;
}
コード例 #9
0
ファイル: lpc177x_8x_i2c.c プロジェクト: saeedhadi/Metering
/*********************************************************************//**
 * @brief 		Transmit and Receive data in master mode
 * @param[in]	I2Cx			I2C peripheral selected, should be:
 *				- LPC_I2C0
 *				- LPC_I2C1
 *				- LPC_I2C2
 * @param[in]	TransferCfg		Pointer to a I2C_M_SETUP_Type structure that
 * 								contains specified information about the
 * 								configuration for master transfer.
 * @param[in]	Opt				a I2C_TRANSFER_OPT_Type type that selected for
 * 								interrupt or polling mode.
 * @return 		SUCCESS or ERROR
 *
 * Note:
 * - In case of using I2C to transmit data only, either transmit length set to 0
 * or transmit data pointer set to NULL.
 * - In case of using I2C to receive data only, either receive length set to 0
 * or receive data pointer set to NULL.
 * - In case of using I2C to transmit followed by receive data, transmit length,
 * transmit data pointer, receive length and receive data pointer should be set
 * corresponding.
 **********************************************************************/
Status I2C_MasterTransferData(en_I2C_unitId i2cId, I2C_M_SETUP_Type *TransferCfg,
																	I2C_TRANSFER_OPT_Type Opt)
{
	LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId);

	uint32_t CodeStatus;
	int32_t Ret = I2C_OK;

	// Reset I2C setup value to default state
	TransferCfg->tx_count = 0;
	TransferCfg->rx_count = 0;
	TransferCfg->status = 0;

	if (Opt == I2C_TRANSFER_POLLING)
	{
		/* First Start condition -------------------------------------------------------------- */
		TransferCfg->retransmissions_count = 0;
retry:
		// Reset I2C setup value to default state
		TransferCfg->tx_count = 0;
		TransferCfg->rx_count = 0;

		// Start command
		CodeStatus = I2C_Start(I2Cx, I2C_TRANSFER_POLLING);
		
		while(1)	// send data first and then receive data from Slave.
		{
			Ret = I2C_MasterHanleStates(i2cId, CodeStatus, TransferCfg, I2C_TRANSFER_POLLING);
			if(I2C_CheckError(Ret))
			{
				TransferCfg->retransmissions_count++;
				if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){
						// save status
						TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF;
						goto error;
					} else {
						goto retry;
					}
			}
			else if( (Ret & I2C_BYTE_SENT) ||
					(Ret & I2C_BYTE_RECV))
			{
				// Wait for sending ends/ Wait for next byte			
				while (!(I2Cx->CONSET & I2C_I2CONSET_SI));
			}
			else if (Ret & I2C_SEND_END) // already send all data
			{
				// If no need to wait for data from Slave
				if(TransferCfg->rx_count >= (TransferCfg->rx_length)) 
				{
					break;
				}
				else
				{
					I2C_Start(I2Cx, I2C_TRANSFER_POLLING);
				}
			}
			else if (Ret & I2C_RECV_END) // already receive all data
			{
				break;
			}
            CodeStatus = I2Cx->STAT & I2C_STAT_CODE_BITMASK;
		}
		return SUCCESS;
error:
		return ERROR;
	}

	else if (Opt == I2C_TRANSFER_INTERRUPT)
	{
		// Setup tx_rx data, callback and interrupt handler
		i2cdat[i2cId].txrx_setup = (uint32_t) TransferCfg;

		// Set direction phase, write first
		i2cdat[i2cId].dir = 0;

		/* First Start condition -------------------------------------------------------------- */
		// Reset STA, STO, SI
		I2C_Start(I2Cx, I2C_TRANSFER_INTERRUPT);

		I2C_IntCmd(i2cId, TRUE);

		return (SUCCESS);
	}

	return ERROR;
}
コード例 #10
0
ファイル: lpc177x_8x_i2c.c プロジェクト: saeedhadi/Metering
/*********************************************************************//**
 * @brief 		General Slave Interrupt handler for I2C peripheral
 * @param[in]	I2Cx	I2C peripheral selected, should be:
 *  			- LPC_I2C0
 *  			- LPC_I2C1
 *  			- LPC_I2C2
 * @return 		None
 **********************************************************************/
void I2C_SlaveHandler (en_I2C_unitId i2cId)
{
	LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId);

	uint8_t returnCode;
	I2C_S_SETUP_Type *txrx_setup;
	uint32_t timeout;
	int32_t Ret = I2C_OK;

	txrx_setup = (I2C_S_SETUP_Type *) i2cdat[i2cId].txrx_setup;

handle_state:

	returnCode = (I2Cx->STAT & I2C_STAT_CODE_BITMASK);
	// Save current status
	txrx_setup->status = returnCode;


	Ret = I2C_SlaveHanleStates(i2cId, returnCode, txrx_setup);

	if(I2C_CheckError(Ret))
	{
		goto s_int_end;
	}
	else if (Ret & I2C_STA_STO_RECV)
	{
		// Temporally lock the interrupt for timeout condition
		I2C_IntCmd(i2cId, FALSE);
		// enable time out
		timeout = I2C_SLAVE_TIME_OUT;
		while(1)
		{
			if (I2Cx->CONSET & I2C_I2CONSET_SI)
			{
				// re-Enable interrupt
				I2C_IntCmd(i2cId, TRUE);
				goto handle_state;
			}
			else
			{
				timeout--;
				if (timeout == 0)
				{
					// timeout occur, it's really a stop condition
					txrx_setup->status |= I2C_SETUP_STATUS_DONE;
					goto s_int_end;
				}
			}
		}	
	}
	else if(Ret &I2C_SEND_END)
	{
		goto s_int_end;
	}
	else
	{
		return;
	}

s_int_end:
	// Disable interrupt
	I2C_IntCmd(i2cId, FALSE);
	I2Cx->CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;

	I2C_SlaveComplete[i2cId] = TRUE;
}
コード例 #11
0
ファイル: lpc177x_8x_i2c.c プロジェクト: saeedhadi/Metering
/*********************************************************************//**
 * @brief 		General Master Interrupt handler for I2C peripheral
 * @param[in]	I2Cx	I2C peripheral selected, should be:
 * 				- LPC_I2C
 * 				- LPC_I2C1
 * 				- LPC_I2C2
 * @return 		None
 **********************************************************************/
void I2C_MasterHandler(en_I2C_unitId i2cId)
{
	LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId);
	uint8_t returnCode;
	I2C_M_SETUP_Type *txrx_setup;
	int32_t Ret = I2C_OK;

	txrx_setup = (I2C_M_SETUP_Type *) i2cdat[i2cId].txrx_setup;

	returnCode = (I2Cx->STAT & I2C_STAT_CODE_BITMASK);

	// Save current status
	txrx_setup->status = returnCode;

	Ret = I2C_MasterHanleStates(i2cId, returnCode, txrx_setup, I2C_TRANSFER_INTERRUPT);

	if(I2C_CheckError(Ret))
	{
		if(txrx_setup->retransmissions_count < txrx_setup->retransmissions_max)
		{
			// Retry
			txrx_setup->retransmissions_count ++;
			txrx_setup->tx_count = 0;
			txrx_setup->rx_count = 0;
			// Reset STA, STO, SI
	        I2C_Start(I2Cx, I2C_TRANSFER_INTERRUPT);
			return;
		}
		else
		{
			goto s_int_end;
		}
	}
	else if (Ret & I2C_SEND_END)
	{
		// If no need to wait for data from Slave
		if(txrx_setup->rx_count >= (txrx_setup->rx_length)) 
		{
			goto s_int_end;
		}
		else	// Start to wait for data from Slave
		{
			// Reset STA, STO, SI
			I2C_Start(I2Cx, I2C_TRANSFER_INTERRUPT);
			return;
		}
	}
	else if (Ret & I2C_RECV_END) 
	{
		goto s_int_end;
	}
	else
	{
		return;
	}

s_int_end:
	// Disable interrupt
	I2C_IntCmd(i2cId, FALSE);

	I2Cx->CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;

	I2C_MasterComplete[i2cId] = TRUE;
		
}
コード例 #12
0
ファイル: lpc177x_8x_i2c.c プロジェクト: saeedhadi/Metering
/*********************************************************************//**
 * @brief 		Receive and Transmit data in slave mode
 * @param[in]	I2Cx			I2C peripheral selected, should be
 *				- LPC_I2C0
 *				- LPC_I2C1
 *				- LPC_I2C2
 * @param[in]	TransferCfg		Pointer to a I2C_S_SETUP_Type structure that
 * 								contains specified information about the
 * 								configuration for master transfer.
 * @param[in]	Opt				I2C_TRANSFER_OPT_Type type that selected for
 * 								interrupt or polling mode.
 * @return 		SUCCESS or ERROR
 *
 * Note:
 * The mode of slave's operation depends on the command sent from master on
 * the I2C bus. If the master send a SLA+W command, this sub-routine will
 * use receive data length and receive data pointer. If the master send a SLA+R
 * command, this sub-routine will use transmit data length and transmit data
 * pointer.
 * If the master issue an repeat start command or a stop command, the slave will
 * enable an time out condition, during time out condition, if there's no activity
 * on I2C bus, the slave will exit, otherwise (i.e. the master send a SLA+R/W),
 * the slave then switch to relevant operation mode. The time out should be used
 * because the return status code can not show difference from stop and repeat
 * start command in slave operation.
 * In case of the expected data length from master is greater than data length
 * that slave can support:
 * - In case of reading operation (from master): slave will return I2C_I2DAT_IDLE_CHAR
 * value.
 * - In case of writing operation (from master): slave will ignore remain data from master.
 **********************************************************************/
Status I2C_SlaveTransferData(en_I2C_unitId i2cId, I2C_S_SETUP_Type *TransferCfg,
																	I2C_TRANSFER_OPT_Type Opt)
{
	LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId);
	int32_t   Ret = I2C_OK;
	
	uint32_t CodeStatus;
	uint32_t timeout;
	int32_t time_en;
	
	// Reset I2C setup value to default state
	TransferCfg->tx_count = 0;
	TransferCfg->rx_count = 0;
	TransferCfg->status = 0;

	// Polling option
	if (Opt == I2C_TRANSFER_POLLING)
	{
		/* Set AA bit to ACK command on I2C bus */
		I2Cx->CONSET = I2C_I2CONSET_AA;
		
		/* Clear SI bit to be ready ... */
		I2Cx->CONCLR = (I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC|I2C_I2CONCLR_STOC);

		time_en = 0;
		timeout = 0;

		while (1)
		{
			/* Check SI flag ready */
			if (I2Cx->CONSET & I2C_I2CONSET_SI)
			{
				time_en = 0;

				CodeStatus = (I2Cx->STAT & I2C_STAT_CODE_BITMASK);

				Ret = I2C_SlaveHanleStates(i2cId, CodeStatus, TransferCfg);
				if(I2C_CheckError(Ret))
				{
					goto s_error;
				}
				else if(Ret & I2C_STA_STO_RECV)
				{
					time_en = 1;
					timeout = 0;
				}
                else if (Ret & I2C_SEND_END)
                {
                    goto s_end_stage;
                }
			}
			else if (time_en)
			{
				if (timeout++ > I2C_SLAVE_TIME_OUT)
				{
					// it's really a stop condition, goto end stage
					goto s_end_stage;
				}
			}
		}

s_end_stage:
		/* Clear AA bit to disable ACK on I2C bus */
		I2Cx->CONCLR = I2C_I2CONCLR_AAC;

		// Check if there's no error during operation
		// Update status
		TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_DONE;
		return SUCCESS;

s_error:
		/* Clear AA bit to disable ACK on I2C bus */
		I2Cx->CONCLR = I2C_I2CONCLR_AAC;

		// Update status
		TransferCfg->status = CodeStatus;
		return ERROR;
	}

	else if (Opt == I2C_TRANSFER_INTERRUPT)
	{
		// Setup tx_rx data, callback and interrupt handler
		i2cdat[i2cId].txrx_setup = (uint32_t) TransferCfg;

		// Set direction phase, read first
		i2cdat[i2cId].dir = 1;

		// Enable AA
		I2Cx->CONSET = I2C_I2CONSET_AA;
		I2Cx->CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;
		I2C_IntCmd(i2cId, TRUE);

		return (SUCCESS);
	}

	return ERROR;
}
コード例 #13
0
ファイル: lpc8xx_i2c.c プロジェクト: AlexandreN7/Liqui_lense
/*****************************************************************************
** Function name:		I2C_MstSendRcv
**
** Descriptions:		Send a block of data to the I2C port combining master
**                      send and master recevie with repeated start in the middle.
**
** parameters:			Dev addr. TX ptr, TX length, RX ptr, and RX length.
** Returned value:		None
** 
*****************************************************************************/
void I2C_MstSendRcv( LPC_I2C_TypeDef *I2Cx, uint32_t addr, uint8_t *tx, uint32_t txlen, uint8_t *rx, uint32_t rxlen )
{
  uint32_t i;

  I2Cx->MSTDAT = addr;
  I2Cx->MSTCTL = CTL_MSTSTART;
#if I2C_INTERRUPT
  msttxrdy = mstrxrdy = 0;
  I2Cx->INTENSET = STAT_MSTPEND;
#endif 
  for ( i = 0; i < txlen; i++ ) 
  {
#if I2C_INTERRUPT
		while(!msttxrdy) 
		{
			if ( I2C_CheckError(I2Cx) ) {
				I2C_CheckIdle(I2Cx);
				/* Recursive call here. Be very careful with stack over flow if come here, especially
				when the other master trys to grab the bus all the time. */
//				while ( 1 );
				I2C_MstSend( I2Cx, addr, tx, txlen );
				return;
	  	}
		}
	msttxrdy = 0;
	I2Cx->MSTDAT = *tx++;
	I2Cx->MSTCTL = CTL_MSTCONTINUE;
	I2Cx->INTENSET = STAT_MSTPEND;
#else
	/* Move only if TXRDY is ready */
	while (!(I2Cx->STAT & STAT_MSTPEND));
	if((I2Cx->STAT & MASTER_STATE_MASK) != STAT_MSTTX)
	  while(1);
	I2Cx->MSTDAT = *tx++;
	I2Cx->MSTCTL = CTL_MSTCONTINUE;
#endif
  }

  /* Wait for the last TX to finish before setting repeated start. */
#if I2C_INTERRUPT
  while(!msttxrdy) 
  {
		if ( I2C_CheckError(I2Cx) ) {
			I2C_CheckIdle(I2Cx);
			/* Recursive call here. Be very careful with stack over flow if come here. especially
			when the other master trys to grab the bus all the time. */
//			while ( 1 );
			I2C_MstSend( I2Cx, addr, tx, txlen );
			return;
		}
  }
  msttxrdy = 0;
#else
  /* Move on only if TXRDY is ready */
  while (!(I2Cx->STAT & STAT_MSTPEND));
  if((I2Cx->STAT & MASTER_STATE_MASK) != STAT_MSTTX)
    while(1);
#endif

  /* Repeated Start */
  I2Cx->MSTDAT = addr|RD_BIT;   
  I2Cx->MSTCTL = CTL_MSTSTART|CTL_MSTCONTINUE;
#if I2C_INTERRUPT
  I2Cx->INTENSET = STAT_MSTPEND;
#endif

  for ( i = 0; i < rxlen; i++ )
  {
#if I2C_INTERRUPT
		while(!mstrxrdy) {
			if ( I2C_CheckError(I2Cx) ) {
				I2C_CheckIdle(I2Cx);
				/* Recursive call here. Be very careful with stack over flow if come here, especially
				when the other master trys to grab the bus all the time. */
//				while ( 1 );
				I2C_MstReceive( I2Cx, addr|RD_BIT, rx, rxlen );
				return;
			}
		}
		mstrxrdy = 0;
		*rx++ = I2Cx->MSTDAT;
		if ( i != rxlen-1 ) {
			I2Cx->MSTCTL = CTL_MSTCONTINUE;
			I2Cx->INTENSET = STAT_MSTPEND;
		}
#else
		/* Slave address has been sent, master receive is ready. */
		while (!(I2Cx->STAT & STAT_MSTPEND));
		if((I2Cx->STAT & MASTER_STATE_MASK) != STAT_MSTRX)
			while(1);
		*rx++ = I2Cx->MSTDAT;
		if ( i != rxlen-1 ) {
			I2Cx->MSTCTL = CTL_MSTCONTINUE;
		}
#endif
  }

  I2Cx->MSTCTL = CTL_MSTSTOP | CTL_MSTCONTINUE;
  I2C_CheckIdle(I2Cx);
  return; 
}
コード例 #14
0
ファイル: lpc8xx_i2c.c プロジェクト: AlexandreN7/Liqui_lense
/*****************************************************************************
** Function name:		I2C_MstSend
**
** Descriptions:		Send a block of data to the I2C port, the 
**									first parameter is the device addre, the 2nd is buffer 
**                  pointer, the 3rd is the block length.
**
** parameters:			device addr, buffer pointer, and the block length
** Returned value:		None
** 
*****************************************************************************/
void I2C_MstSend( LPC_I2C_TypeDef *I2Cx, uint32_t addr, uint8_t *tx, uint32_t Length )
{
  uint32_t i;

  I2Cx->MSTDAT = addr;
  I2Cx->MSTCTL = CTL_MSTSTART;
#if I2C_INTERRUPT
  msttxrdy = 0;
  I2Cx->INTENSET = STAT_MSTPEND;
#endif
#if I2C_INTERRUPT
  for ( i = 0; i < Length; i++ ) 
  {
		while(!msttxrdy) {
			if ( I2C_CheckError(I2Cx) ) {
				I2C_CheckIdle(I2Cx);
				/* Recursive call here. Be very careful with stack over flow if come here, especially
				when the other master trys to grab the bus all the time. */
//				while ( 1 );
				I2C_MstSend( I2Cx, addr, tx, Length );
				return;
			}
		}
		msttxrdy = 0;
		I2Cx->MSTDAT = tx[i];
		I2Cx->MSTCTL = CTL_MSTCONTINUE;
		I2Cx->INTENSET = STAT_MSTPEND;
  }
  
  /* Wait for the last one to go out. */
  while(!msttxrdy) {
		if ( I2C_CheckError(I2Cx) ) {
	    I2C_CheckIdle(I2Cx);
			/* Recursive call here. Be very careful with stack over flow if come here. especially
			when the other master trys to grab the bus all the time. */
//			while ( 1 );
			I2C_MstSend( I2Cx, addr, tx, Length );
			return;
		}
  }
  msttxrdy = 0;
#else
  for ( i = 0; i < Length; i++ ) 
  {
		/* Move only if TXRDY is ready */
		while (!(I2Cx->STAT & STAT_MSTPEND));
		if((I2Cx->STAT & MASTER_STATE_MASK) != STAT_MSTTX)
			while(1);
		I2Cx->MSTDAT = *tx++;
		I2Cx->MSTCTL = CTL_MSTCONTINUE;
  }
  
  /* Wait for the last one to go out. */
  while (!(I2Cx->STAT & STAT_MSTPEND));
  if((I2Cx->STAT & MASTER_STATE_MASK) != STAT_MSTTX)
		while(1);
#endif
  /* Send STOP condition. */  
  I2Cx->MSTCTL = CTL_MSTSTOP | CTL_MSTCONTINUE;
  I2C_CheckIdle(I2Cx);
  return; 
}