예제 #1
0
파일: pmu.c 프로젝트: robbie-cao/wmd
/* PMU task entry */
void PMU_IndHandler(void)
{
    u8 status;

#ifndef DEBUG
    /* read pmu interrupt status */
    I2C_ReadFrom(PMU_I2C_ADDR(OOL0));
    status = I2C_GetByte(I2C_LAST);

    /* clear pmu interrupt */
    I2C_WriteTo(PMU_I2C_ADDR(OOL2));
    I2C_PutByte(status);
#else
    /* read interrupt status */
    status = I2C_ReadFrom(PMU_I2C_ADDR(OOL0));
    puthex(PMU_I2C_ADDR(OOL0));
    putch(':');
    puthex(status);
    putch(',');
    status = I2C_GetByte(I2C_LAST);
    puthex(status);
    putch('\r');

    /* clear pmu interrupt */
    status = I2C_WriteTo(PMU_I2C_ADDR(OOL2));
    puthex(PMU_I2C_ADDR(OOL2));
    putch(':');
    puthex(status);
    putch(',');
    status = I2C_PutByte(status);
    puthex(status);
    putch('\r');
#endif

    /* send msg to main loop */
    Task_Push(MSG_ID_BATT_IND, status, 0);
}
예제 #2
0
파일: i2c.c 프로젝트: rainfd/CH-K-Lib
/**
 * @brief  I2C read mutiple data
 * \param[in]  instance    instance of i2c moudle
 * \param[in]  chipAddr    i2c slave addr
 * \param[in]  addr        i2c slave register offset
 * \param[in]  addrLen     len of slave register addr(in byte)
 * \param[out] buf         data buf
 * \param[in]  len         data length
 * \retval 0 success
 * \retval 1 failure
 */
int  I2C_BurstRead(uint32_t instance ,uint8_t chipAddr, uint32_t addr, uint32_t addrLen, uint8_t *buf, uint32_t len)
{
    uint8_t *p;
    uint8_t err;
    
    p = (uint8_t*)&addr;
    err = 0;
    chipAddr <<= 1;
    
    I2C_Start();
    I2C_SendByte(chipAddr);
    err += I2C_WaitAck();
    
    while(addrLen--)
    {
        I2C_SendByte(*p++);
        err += I2C_WaitAck();
    }
    
    I2C_Start();
    I2C_SendByte(chipAddr+1);
    err += I2C_WaitAck();
    
    while(len--)
    {
        *buf++ = I2C_GetByte();
        if(len)
        {
            I2C_Ack();
        }
    }
    
    I2C_NAck();
    I2C_Stop();
    
    return err;
}
예제 #3
0
파일: i2c.c 프로젝트: rainfd/CH-K-Lib
/**
 * @brief  SCCB(protocol,the same as i2c) read single register value
 * \param[in]  instance   instance of i2c moudle
 * \param[in]  chipAddr   i2c slave addr
 * \param[in]  addr       i2c slave register offset
 * \param[out] data       data pointer
 * @note   usually used on i2c sensor devices
 * \retval 0 success
 * \retval 1 failure
 */
int SCCB_ReadSingleRegister(uint32_t instance, uint8_t chipAddr, uint8_t addr, uint8_t* data)
{
    uint8_t err;
    uint8_t retry;
    
    retry = 10;
    chipAddr <<= 1;
    
    while(retry--)
    {
        err = 0;
        I2C_Start();
        I2C_SendByte(chipAddr);
        err += I2C_WaitAck();
        
        I2C_SendByte(addr);
        err += I2C_WaitAck();
        
        I2C_Stop();
        I2C_Start();
        I2C_SendByte(chipAddr+1);
        err += I2C_WaitAck();
        
        *data = I2C_GetByte();
       // err += I2C_WaitAck();
        
        I2C_NAck();
        I2C_Stop();
        if(!err)
        {
            break;
        }
    }

    return err;
}
/*********************************************************************//**
 * @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(LPC_I2C_TypeDef *I2Cx, I2C_M_SETUP_Type *TransferCfg, \
								I2C_TRANSFER_OPT_Type Opt)
{
	uint8_t *txdat;
	uint8_t *rxdat;
	uint32_t CodeStatus;
	uint8_t tmp;

	// reset all default state
	txdat = (uint8_t *) TransferCfg->tx_data;
	rxdat = (uint8_t *) TransferCfg->rx_data;
	// 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 all default state
		txdat = (uint8_t *) TransferCfg->tx_data;
		rxdat = (uint8_t *) TransferCfg->rx_data;
		// Reset I2C setup value to default state
		TransferCfg->tx_count = 0;
		TransferCfg->rx_count = 0;
		CodeStatus = 0;

		// Start command
		CodeStatus = I2C_Start(I2Cx);
		if ((CodeStatus != I2C_I2STAT_M_TX_START) \
				&& (CodeStatus != I2C_I2STAT_M_TX_RESTART)){
			TransferCfg->retransmissions_count++;
			if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){
				// save status
				TransferCfg->status = CodeStatus;
				goto error;
			} else {
				goto retry;
			}
		}

		/* In case of sending data first --------------------------------------------------- */
		if ((TransferCfg->tx_length != 0) && (TransferCfg->tx_data != NULL)){

			/* Send slave address + WR direction bit = 0 ----------------------------------- */
			CodeStatus = I2C_SendByte(I2Cx, (TransferCfg->sl_addr7bit << 1));
			if (CodeStatus != I2C_I2STAT_M_TX_SLAW_ACK){
				TransferCfg->retransmissions_count++;
				if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){
					// save status
					TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF;
					goto error;
				} else {
					goto retry;
				}
			}

			/* Send a number of data bytes ---------------------------------------- */
			while (TransferCfg->tx_count < TransferCfg->tx_length)
			{
				CodeStatus = I2C_SendByte(I2Cx, *txdat);
				if (CodeStatus != I2C_I2STAT_M_TX_DAT_ACK){
					TransferCfg->retransmissions_count++;
					if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){
						// save status
						TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF;
						goto error;
					} else {
						goto retry;
					}
				}

				txdat++;
				TransferCfg->tx_count++;
			}
		}

		/* Second Start condition (Repeat Start) ------------------------------------------- */
		if ((TransferCfg->tx_length != 0) && (TransferCfg->tx_data != NULL) \
				&& (TransferCfg->rx_length != 0) && (TransferCfg->rx_data != NULL)){

			CodeStatus = I2C_Start(I2Cx);
			if ((CodeStatus != I2C_I2STAT_M_RX_START) \
					&& (CodeStatus != I2C_I2STAT_M_RX_RESTART)){
				TransferCfg->retransmissions_count++;
				if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){
					// Update status
					TransferCfg->status = CodeStatus;
					goto error;
				} else {
					goto retry;
				}
			}
		}

		/* Then, start reading after sending data -------------------------------------- */
		if ((TransferCfg->rx_length != 0) && (TransferCfg->rx_data != NULL)){
			/* Send slave address + RD direction bit = 1 ----------------------------------- */

			CodeStatus = I2C_SendByte(I2Cx, ((TransferCfg->sl_addr7bit << 1) | 0x01));
			if (CodeStatus != I2C_I2STAT_M_RX_SLAR_ACK){
				TransferCfg->retransmissions_count++;
				if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){
					// update status
					TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF;
					goto error;
				} else {
					goto retry;
				}
			}

			/* Receive a number of data bytes ------------------------------------------------- */
			while (TransferCfg->rx_count < TransferCfg->rx_length){

				/*
				 * Note that: if data length is only one, the master should not
				 * issue an ACK signal on bus after reading to avoid of next data frame
				 * on slave side
				 */
				if (TransferCfg->rx_count < (TransferCfg->rx_length - 1)){
					// Issue an ACK signal for next data frame
					CodeStatus = I2C_GetByte(I2Cx, &tmp, TRUE);
					if (CodeStatus != I2C_I2STAT_M_RX_DAT_ACK){
						TransferCfg->retransmissions_count++;
						if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){
							// update status
							TransferCfg->status = CodeStatus;
							goto error;
						} else {
							goto retry;
						}
					}
				} else {
					// Do not issue an ACK signal
					CodeStatus = I2C_GetByte(I2Cx, &tmp, FALSE);
					if (CodeStatus != I2C_I2STAT_M_RX_DAT_NACK){
						TransferCfg->retransmissions_count++;
						if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){
							// update status
							TransferCfg->status = CodeStatus;
							goto error;
						} else {
							goto retry;
						}
					}
				}
				*rxdat++ = tmp;
				TransferCfg->rx_count++;
			}
		}

		/* Send STOP condition ------------------------------------------------- */
		I2C_Stop(I2Cx);
		return SUCCESS;

error:
		// Send stop condition
		I2C_Stop(I2Cx);
		return ERROR;
	}

	else if (Opt == I2C_TRANSFER_INTERRUPT){
		// Setup tx_rx data, callback and interrupt handler
		tmp = I2C_getNum(I2Cx);
		i2cdat[tmp].txrx_setup = (uint32_t) TransferCfg;
		// Set direction phase, write first
		i2cdat[tmp].dir = 0;

		/* First Start condition -------------------------------------------------------------- */
		I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
		I2Cx->I2CONSET = I2C_I2CONSET_STA;
		I2C_IntCmd(I2Cx, TRUE);

		return (SUCCESS);
	}

	return ERROR;
}
예제 #5
0
/*********************************************************************//**
 * @brief 		Handle I2C Master states.
 * @param[in]	I2Cx	I2C peripheral selected, should be:
 * 				- I2C_0
 * 				- I2C_1
 * 				- I2C_2
 * @param[in]	CodeStatus	I2C state
 * @param[in]	TransferCfg   Pointer to a I2C_S_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 		It can be
 *				- I2C_OK
 *				-I2C_BYTE_RECV
 *				-I2C_BYTE_SENT
 *				-I2C_SEND_END
 *				-I2C_RECV_END
 *				- I2C_ERR
 *				- I2C_NAK_RECV
 **********************************************************************/
int32_t I2C_MasterHanleStates(en_I2C_unitId i2cId, 
                                uint32_t CodeStatus, 
                                I2C_M_SETUP_Type *TransferCfg,
                                I2C_TRANSFER_OPT_Type Opt
                                )
{
	LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId);
	uint8_t *txdat;
	uint8_t *rxdat;
	uint8_t tmp;
	int32_t Ret = I2C_OK;
	
	//get buffer to send/receive
	txdat = (uint8_t *) &TransferCfg->tx_data[TransferCfg->tx_count];
	rxdat = (uint8_t *) &TransferCfg->rx_data[TransferCfg->rx_count];

	switch(CodeStatus)
	{
		case I2C_I2STAT_M_TX_START:
		case I2C_I2STAT_M_TX_RESTART:
		//case I2C_I2STAT_M_RX_START:
		//case I2C_I2STAT_M_RX_RESTART
			// Send data first
			if(TransferCfg->tx_count < TransferCfg->tx_length)
			{
				/* Send slave address + WR direction bit = 0 ----------------------------------- */
				//I2C_SendByte(I2Cx, (TransferCfg->sl_addr7bit << 1));///////////////////////////////
				I2C_SendByte(I2Cx, (TransferCfg->sl_addr7bit ));
				Ret = I2C_BYTE_SENT;
			}
			else if (TransferCfg->rx_count  < TransferCfg->rx_length)
			{
				/* Send slave address + RD direction bit = 1 ----------------------------------- */
				//I2C_SendByte(I2Cx, ((TransferCfg->sl_addr7bit << 1) | 0x01));////////////////
				I2C_SendByte(I2Cx, (TransferCfg->sl_addr7bit));
				Ret = I2C_BYTE_SENT;
			}
            // Clear STA bit after the slave address is sent
            I2Cx->CONCLR = I2C_I2CONCLR_STAC;
			break;
		case I2C_I2STAT_M_TX_SLAW_ACK:
		case I2C_I2STAT_M_TX_DAT_ACK:
			
			if(TransferCfg->tx_count < TransferCfg->tx_length)
			{
				I2C_SendByte(I2Cx, *txdat);
				
				txdat++;

				TransferCfg->tx_count++;

				Ret = I2C_BYTE_SENT;
			}
			else
			{
				if(TransferCfg->rx_count >= TransferCfg->rx_length)
                {
                    I2C_Stop(I2Cx, Opt);
                }
				Ret = I2C_SEND_END;
				
                
			}
            
			break;
		case I2C_I2STAT_M_TX_DAT_NACK:
            if(TransferCfg->rx_count >= TransferCfg->rx_length)
            {
                I2C_Stop(I2Cx, Opt);
            }
			Ret = I2C_SEND_END;
			break;
		case I2C_I2STAT_M_RX_ARB_LOST:
        case I2C_I2STAT_S_RX_ARB_LOST_M_GENCALL:
        case I2C_I2STAT_S_TX_ARB_LOST_M_SLA:
        //case I2C_I2STAT_M_TX_ARB_LOST:
			I2C_Stop(I2Cx, Opt);
            Ret = I2C_ERR;
			break;
		case I2C_I2STAT_M_RX_SLAR_ACK:
            if(TransferCfg->rx_length > 1)
                I2Cx->CONSET = I2C_I2CONSET_AA;
            else
                I2Cx->CONCLR = I2C_I2CONCLR_AAC;
			I2Cx->CONCLR = I2C_I2CONCLR_SIC;

			Ret = I2C_BYTE_RECV;
			break;
		case I2C_I2STAT_M_RX_DAT_ACK:
			if (TransferCfg->rx_count <TransferCfg->rx_length)
			{
				if ((TransferCfg->rx_length > 1) && (TransferCfg->rx_count < (TransferCfg->rx_length - 2)))
				{
					I2C_GetByte(I2Cx, &tmp, TRUE);

					Ret = I2C_BYTE_RECV;
					
				}
				else  // the next byte is the last byte, send NACK instead.
				 {
					I2C_GetByte(I2Cx, &tmp, FALSE);
					Ret = I2C_BYTE_RECV;
				 }
				*rxdat++ = tmp;

				TransferCfg->rx_count++;
			}
		    else
			{
                I2C_Stop(I2Cx, Opt);
				Ret = I2C_RECV_END;
			}
			
			break;
		case I2C_I2STAT_M_RX_DAT_NACK:
			I2C_GetByte(I2Cx, &tmp, FALSE);
            if (TransferCfg->rx_count < TransferCfg->rx_length)
            {
                *rxdat++ = tmp;
                TransferCfg->rx_count++;
            }
			I2C_Stop(I2Cx, Opt);
			Ret = I2C_RECV_END;
			break;
        
		case I2C_I2STAT_M_RX_SLAR_NACK:
		case I2C_I2STAT_M_TX_SLAW_NACK:
		case I2C_I2STAT_BUS_ERROR:
			// Send STOP condition
			I2C_Stop(I2Cx, Opt);
			Ret = I2C_ERR;
			break;
        /* No status information */
		case I2C_I2STAT_NO_INF:
          if ((TransferCfg->tx_count <TransferCfg->tx_length)||
               (TransferCfg->rx_count <TransferCfg->rx_length))
          {
            I2C_Stop(I2Cx, Opt);
            Ret = I2C_ERR;
          }
          else
          {
            Ret = I2C_RECV_END;
          }
          break;
        default:
			I2Cx->CONCLR = I2C_I2CONCLR_SIC;
			break;
	}
	
	return Ret;
}
예제 #6
0
파일: pmu.c 프로젝트: robbie-cao/wmd
/* PMU module initialization */
void PMU_Init(void)
{
#ifdef DEBUG
    u8 res;
    u8 i = 0;
#endif

    TRISA2 = 1; /* config RA2/INT as input */
    RABPU = 0;  /* PORTA/B pull-up enable */
    WPUA2 = 1;  /* RA2 weak pull-up enable */
    INTEDG = 0; /* interrupt on falling edge of INT pin */
    INTE = 1;   /* RA2/INT external interrupt enable */
    GIE = 1;    /* enable global interrupt */

#ifndef DEBUG
    /* config AS7100 interrupt enable bits */
    I2C_WriteTo(PMU_I2C_ADDR(OOL1));
    I2C_PutByte(PMU_INT_POWON | PMU_INT_POWOFF | PMU_INT_LVDSTATE | PMU_INT_OPTSTATE);

    /* config AS7100 IRQ mode */
    I2C_WriteTo(PMU_I2C_ADDR(OOL3));
    I2C_PutByte(PMU_IRQ_MODE_PULSE);

    /* enable P**N(RESETN) signal output */
    I2C_WriteTo(PMU_I2C_ADDR(OOL5));
    I2C_PutByte(PMU_PRON_ENABLE);
#else
    /* config AS7100 interrupt enable bits */
    res = I2C_WriteTo(PMU_I2C_ADDR(OOL1));
    puthex(PMU_I2C_ADDR(OOL1));
    putch(':');
    puthex(res);
    putch(',');
    res = I2C_PutByte(PMU_INT_POWON | PMU_INT_POWOFF | PMU_INT_LVDSTATE | PMU_INT_OPTSTATE);
    puthex(res);
    putch('\r');

    /* config AS7100 IRQ mode */
    res = I2C_WriteTo(PMU_I2C_ADDR(OOL3));
    puthex(PMU_I2C_ADDR(OOL3));
    putch(':');
    puthex(res);
    putch(',');
    res = I2C_PutByte(PMU_IRQ_MODE_PULSE);
    puthex(res);
    putch('\r');

    /* enable P**N(RESETN) signal output */
    res = I2C_WriteTo(PMU_I2C_ADDR(OOL5));
    puthex(PMU_I2C_ADDR(OOL5));
    putch(':');
    puthex(res);
    putch(',');
    res = I2C_PutByte(PMU_PRON_ENABLE);
    puthex(res);
    putch('\r');
#endif

#ifdef DEBUG
    /* read all register */
    for (i = 0; i < 0x10; i++) {
        u8 addr = 0x60 | i;

        res = I2C_ReadFrom(addr);
        puthex(addr);
        putch(':');
        puthex(res);
        putch(',');
        res = I2C_GetByte(I2C_LAST);
        puthex(res);
        putch('\r');
    }
#endif
}