示例#1
0
void TaskRun_Batt_LTC2943(void)
{
	int16_t status;
	u32 iic_option;

	/*Wait for IIC data transfer*/
	if(s_iic_status == LTC2943_TRANSFERRING)
		return;

	else if(s_iic_status == LTC2943_TRANSFERRED_DONE)
	{

		switch(s_ltc2943_state)
		{

			/*Done data write operation*/
			case LTC2943_WriteWait:
				 /*Release IIC Resource*/
				 status = EndoIicClose(BATT_LTC2943);
				 /*Set the status to transferring*/
				 s_iic_status = LTC2943_IDLE ;
				 /*Finish a write operation, and wait for next command*/
				 s_ltc2943_state = LTC2943_WaitForCommand;

				break;

			case LTC2943_WriteRepeatedStartWait:
				iic_option = XIic_GetOptions(iic_ptr);
				XIic_SetOptions(iic_ptr, iic_option &= XII_REPEATED_START_OPTION);
				/*Set the status to transferring*/
				s_iic_status = LTC2943_TRANSFERRING;
				/*Read 14 bytes of data from LTC2943_VOLTAGE_MSB_REG
				 * to LTC2943_TEMPERATURE_LSB_REG*/
				//memset(rx_buffer,0, 16);
				(void)XIic_MasterRecv(iic_ptr, rx_buffer, 24);

				/*Update the LTC2943 state*/
				s_ltc2943_state = LTC2943_ReadAdcValueWait;
				break;


			case LTC2943_ReadAdcValueWait:
				/*Finish a repeated START read*/
				status = EndoIicClose(BATT_LTC2943);
				if(status == ENDO_SUCCESS)
				{
					/*Convert raw data to voltage, current, temperature*/
					LTC2943_ConvertData(rx_buffer+8, 14);
				}
				/*Set the status to transferring*/
				s_iic_status = LTC2943_IDLE ;
				/*Finish the write-read operation, and wait for next command*/
				s_ltc2943_state = LTC2943_WaitForCommand;
				break;


			default:
				/*Error happen here*/
				s_iic_status = LTC2943_IDLE ;

				s_ltc2943_state = LTC2943_Error;
					break;
		}



	}
	else /*s_iic_status == LTC2943_IDLE*/
	{
		switch(s_ltc2943_state)
				{
					case LTC2943_Init:
						 status = EndoIicSensorInit(BATT_LTC2943, iic_ptr,
								 	 	 	 	 	 LTC2943_SendHandler,
								 	 	 	 	 	 LTC2943_RecvHandler,
								 	 	 	 	 	 LTC2943_StatusHandler);

						 if(status == ENDO_SUCCESS)
							 s_ltc2943_state = LTC2943_WaitForCommand;

						break;


					case LTC2943_WaitForCommand:
						break;

					case LTC2943_Error:
						s_ltc2943_state = LTC2943_WaitForCommand;
						break;

					default:
						break;
				}
	}


}
示例#2
0
/*
 * *********************************************************
 * IicReadData3 with address added as an input parameter - two bytes address
 * *********************************************************
 */
int IicReadData3(u8 IicAddr, u16 addr, u8 *BufferPtr, u16 ByteCount)
{
	int Status;
	u8 IicOptions;
	u32 IicTimeoutCounter = 0;

	/*
	 * Set Receive Flag
	 */
	ReceiveComplete = 1;

	/*
	 * Start Iic Device
	 */
	Status = XIic_Start(&IicInstance);
	if (Status != XST_SUCCESS) {
#ifdef IIC_DEBUG
		xil_printf("IicReadData3: IIC Start failed with status %x\r\n", Status);
#endif
		return XST_FAILURE;
	}

	/*
	 * Set Iic Address
	 */
	Status = XIic_SetAddress(&IicInstance, XII_ADDR_TO_SEND_TYPE, IicAddr);
	if (Status != XST_SUCCESS) {
#ifdef IIC_DEBUG
		xil_printf("IicReadData3: IIC Set Address failed with status %x\r\n", Status);
#endif
		return XST_FAILURE;
	}

	/*
	 * Write addr to the device
	 */
	// Mark the Transmit Flag
	TransmitComplete = 1;
	IicInstance.Stats.TxErrors = 0;

	/*
	 * Send the Data
	 */
	u8 addrReorder[2];
	u8 *addrPtr;
	addrPtr = &addr;
	addrReorder[0] = addrPtr[1];
	addrReorder[1] = addrPtr[0];
	Status = XIic_MasterSend(&IicInstance, addrReorder, 2);
	if (Status != XST_SUCCESS) {
#ifdef IIC_DEBUG
		xil_printf("IicReadData3: IIC Master Send failed with status %x\r\n", Status);
#endif
		return XST_FAILURE;
	}

	/*
	 * Wait till the transmission is completed
	 */
	while(((TransmitComplete) || (XIic_IsIicBusy(&IicInstance)==TRUE)) && IicTimeoutCounter <= IIC_TIMEOUT) {
		IicTimeoutCounter ++;
	}

	/*
	 * Handle Tx Timeout
	 */
	if (IicTimeoutCounter > IIC_TIMEOUT) {
		XIic_Reset(&IicInstance);
		Status = XIic_Stop(&IicInstance);
#ifdef IIC_DEBUG
		xil_printf("IicReadData3: IIC Write Timeout!\r\n");
		if (Status != XST_SUCCESS) {
			xil_printf("IicReadData3: IIC Stop Failed with status %x\r\n", Status);
		}
#endif
		return XST_FAILURE;
	}

	/*
	 * Receive Data
	 */
	Status = XIic_MasterRecv(&IicInstance, BufferPtr, ByteCount);
	if(Status != XST_SUCCESS) {
		if (Status != XST_SUCCESS) {
#ifdef IIC_DEBUG
			xil_printf("IicReadData3: IIC Master Recv Failed with status %x\r\n", Status);
#endif
			return XST_FAILURE;
		}
	}

	/*
	 * Wait until all the data is received
	 */
	IicTimeoutCounter = 0;
	while(((ReceiveComplete) || (XIic_IsIicBusy(&IicInstance)==TRUE)) && IicTimeoutCounter <= IIC_TIMEOUT) {
		IicTimeoutCounter ++;
	}

	/*
	 * Handle Rx Timeout
	 */
	if (IicTimeoutCounter > IIC_TIMEOUT) {
		XIic_Reset(&IicInstance);
		Status = XIic_Stop(&IicInstance);
#ifdef IIC_DEBUG
		xil_printf("IicReadData3: IIC Recv Timeout!\r\n");
		if (Status != XST_SUCCESS) {
			xil_printf("IicReadData3: IIC Stop Failed with status %x\r\n", Status);
		}
#endif
		return XST_FAILURE;
	}

	/*
	 * Stop Iic
	 */
	Status = XIic_Stop(&IicInstance);
	if (Status != XST_SUCCESS) {
#ifdef IIC_DEBUG
		xil_printf("IicReadData3: IIC Stop Failed with status %x\r\n", Status);
#endif
		return XST_FAILURE;
	}

	return XST_SUCCESS;
}
示例#3
0
static int
xiic_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
{
    struct xiic_data *dev = (struct xiic_data *) i2c_adap;
    struct i2c_msg *pmsg;
    u32 options;
    int i, retries;
    u32 Status;
    u32 writeop;
	
    for (i = 0; i < num; i++)
    {
        pmsg = &msgs[i];

        if (!pmsg->len) /* If length is zero */
             continue;  /* on to the next request. */

        /*
         * This code checks up to 16 times for the
         * bus busy condition.
         */
        retries = 4;
        while((XIic_IsIicBusy(&dev->Iic) == TRUE) &&
              (retries-- != 0))
        {
            set_current_state(TASK_INTERRUPTIBLE);
            schedule_timeout(HZ/250);
        }


        /* If bus is still busy, bail */
        if (XIic_IsIicBusy(&dev->Iic) == TRUE)
        {
            printk(KERN_WARNING
                   "%s #%d: Could not talk to device 0x%2x (%d), bus always busy, trying to reset\n",
                   dev->adap.name, dev->index, pmsg->addr,
                   dev->status_intr_flag);

			/* Try stopping, reseting and starting device to clear condition
			*/
			if (XIic_Stop(&dev->Iic) != XST_SUCCESS)
			{
				/* The bus was in use.. */
				printk(KERN_WARNING
					   "%s #%d: Could not stop device. Restart from higher layer.\n",
					   dev->adap.name, dev->index);
				return -ENXIO;
			}
			else
			{
				XIic_Reset(&dev->Iic);
				if (XIic_Start(&dev->Iic) != XST_SUCCESS)
				{
					printk(KERN_ERR "%s #%d: Could not start device.\n",
						   dev->adap.name, dev->index);
					return -ENODEV;
				}

				return -ENXIO;
			}
        }

        options = 0;
        if (pmsg->flags & I2C_M_TEN)
            options |= XII_SEND_10_BIT_OPTION;
        XIic_SetOptions(&dev->Iic, options);

        if (XIic_SetAddress(&dev->Iic, XII_ADDR_TO_SEND_TYPE,
                    pmsg->addr) != XST_SUCCESS)
        {
            printk(KERN_WARNING
                   "%s #%d: Could not set address to 0x%2x.\n",
                   dev->adap.name, dev->index, pmsg->addr);
            return -EIO;
        }


        dev->transmit_intr_flag = 0xFFFFFFFF;
        dev->receive_intr_flag = 0xFFFFFFFF;
        dev->status_intr_flag = 0xFFFFFFFF;

        /* set the writeop flag to 0 so the adapter does not wait
         * at bottom of loop
         */
        writeop = 0;

		dev->Iic.Stats.TxErrors = 0;

        if (pmsg->flags & I2C_M_RD)
        {
            Status = XIic_MasterRecv(&dev->Iic, pmsg->buf, pmsg->len);
        }
        else
        {
            Status = XIic_MasterSend(&dev->Iic, pmsg->buf, pmsg->len);
        }

        if (Status != XST_SUCCESS)
        {
            printk(KERN_WARNING
                   "%s #%d: Unexpected error %d.\n",
                   dev->adap.name, dev->index, (int)Status);
            return -EIO;
        }

        /*
	 * Wait till the data is transmitted or received. If there is an error
	 * retry for 10 times.
	 */
	retries = 10;

	if(pmsg->flags & I2C_M_RD)
	{
		while((((volatile int)(dev->receive_intr_flag)) != 0) && (retries != 0))
		{
			if ( dev->Iic.Stats.TxErrors != 0)
			{
				udelay(25);
				Status = XIic_MasterRecv(&dev->Iic, pmsg->buf, pmsg->len);
				dev->Iic.Stats.TxErrors = 0;
				retries--;
			}

			/* the udelay was not working for Microblaze and this seems
			   like a better solution */	
			schedule_timeout_interruptible(1);
                }
	}
	else
	{
		while((((volatile int)(dev->transmit_intr_flag)) != 0) && (retries != 0))
		{
			if ( dev->Iic.Stats.TxErrors != 0)
			{
				udelay(25);
				Status = XIic_MasterSend(&dev->Iic, pmsg->buf, pmsg->len);
				dev->Iic.Stats.TxErrors = 0;
				retries--;
			}

			/* the udelay was not working for Microblaze and this seems
			   like a better solution */	
			schedule_timeout_interruptible(1);
		}
	}

	if(retries == 0)
	{
		printk("Unable to talk to Device\n");
		printk("Wrong Slave address or Slave device Busy\n");
	}
    }
    return num;
}