Beispiel #1
0
/*******************************************************************************
* mvTwsiStopBitSet - Set stop bit on the bus
*
* DESCRIPTION:
*       This routine set the stop bit on the TWSI bus.
*       The function then wait for the stop bit to be cleared by the HW.
*       Finally the function checks for status of 0xF8.
*
* INPUT:
*	chanNum - TWSI channel
*
* OUTPUT:
*       None.
*
* RETURN:
*       MV_TRUE is stop bit was set successfuly on the bus.
*
*******************************************************************************/
MV_STATUS mvTwsiStopBitSet(MV_U8 chanNum)
{
	MV_U32	timeout, temp;

	/* Generate stop bit */
	temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
	MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_STOP_BIT);

	twsiIntFlgClr(chanNum);

	/* wait for stop bit to come down */
	timeout = 0;
	while( ((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_STOP_BIT) != 0) && (timeout++ < TWSI_TIMEOUT_VALUE));

	/* check for timeout */
	if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: mvTwsiStopBitSet ERROR - Stop bit TimeOut .\n"))
		return MV_TIMEOUT;

	/* check that the stop bit went down */
	if((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_STOP_BIT) != 0)
	{
		mvOsPrintf("TWSI: mvTwsiStopBitSet ERROR - stop bit didn't went down. \n");
		return MV_FAIL;
	}

	/* check the status */
	temp = twsiStsGet(chanNum);
	if( temp != TWSI_NO_REL_STS_INT_FLAG_IS_KEPT_0){
		mvOsPrintf("TWSI: mvTwsiStopBitSet ERROR - status %x after Stop Bit. \n", temp);
		return MV_FAIL;
	}

	return MV_OK;
}
/*******************************************************************************
* mvTwsiStopBitSet - Set stop bit on the bus
*
* DESCRIPTION:
*       This routine set the stop bit on the TWSI bus.
*       The function then wait for the stop bit to be cleared by the HW.
*       Finally the function checks for status of 0xF8.
*
* INPUT:
*       chanNum - TWSI channel.
*
* OUTPUT:
*       None.
*
* RETURN:
*       MV_TRUE is stop bit was set successfuly on the bus.
*
*******************************************************************************/
MV_STATUS mvTwsiStopBitSet(MV_U8 chanNum)
{
	MV_U32 timeout, temp;

	/* Generate stop bit */
	temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
	MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_STOP_BIT);

	twsiIntFlgClr(chanNum);

	/* wait for stop bit to come down */
	timeout = 0;
	while (((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_STOP_BIT) != 0)
			&& (timeout++ < TWSI_TIMEOUT_VALUE))
			;

	/* check for timeout */
	if (MV_TRUE == twsiTimeoutChk(timeout, "TWSI: mvTwsiStopBitSet ERROR - Stop bit TimeOut .\n"))
		return MV_TIMEOUT;

	/* check that the stop bit went down */
	if ((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_STOP_BIT) != 0)
		return MV_FAIL;

	/* check the status */
	temp = twsiStsGet(chanNum);
	if ((TWSI_M_LOST_ARB_DUR_AD_OR_DATA_TRA == temp) ||
		(TWSI_M_LOST_ARB_DUR_AD_TRA_GNL_CALL_AD_REC_ACK_TRA == temp))
		return MV_TWSI_RETRY;
	else if (temp != TWSI_NO_REL_STS_INT_FLAG_IS_KEPT_0)
		return MV_FAIL;

	return MV_OK;
}
Beispiel #3
0
/*******************************************************************************
* twsiAckBitSet - Set acknowledge bit on the bus
*
* DESCRIPTION:
*       This routine set the acknowledge bit on the TWSI bus.
*
* INPUT:
*       None.
*
* OUTPUT:
*       None.
*
* RETURN:
*       None.
*
*******************************************************************************/
static MV_VOID twsiAckBitSet(MV_U8 chanNum)
{
	MV_U32 temp;

	/*Set the Ack bit */
	temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
	MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_ACK);

	/* Add delay of 1ms */
	mvOsDelay(1);
	return;
}
Beispiel #4
0
/*******************************************************************************
* twsiIntFlgClr - Clear Interrupt flag.
*
* DESCRIPTION:
*       This routine clears the interrupt flag. It does NOT poll the interrupt
*       to make sure the clear. After clearing the interrupt, it waits for at
*       least 1 miliseconds.
*
* INPUT:
*	chanNum - TWSI channel
*
* OUTPUT:
*       None.
*
* RETURN:
*       None.
*
*******************************************************************************/
static MV_VOID twsiIntFlgClr(MV_U8 chanNum)
{
	MV_U32 temp;

	/* wait for 1 mili to prevent TWSI register write after write problems */
	mvOsDelay(1);
	/* clear the int flag bit */
	temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
	MV_REG_WRITE(TWSI_CONTROL_REG(chanNum),temp & ~(TWSI_CONTROL_INT_FLAG_SET));

	/* wait for 1 mili sec for the clear to take effect */
	mvOsDelay(1);

	return;
}
/*******************************************************************************
* mvTwsiStartBitSet - Set start bit on the bus
*
* DESCRIPTION:
*       This routine sets the start bit on the TWSI bus.
*       The routine first checks for interrupt flag condition, then it sets
*       the start bit  in the TWSI Control register.
*       If the interrupt flag condition check previously was set, the function
*       will clear it.
*       The function then wait for the start bit to be cleared by the HW.
*       Then it waits for the interrupt flag to be set and eventually, the
*       TWSI status is checked to be 0x8 or 0x10(repeated start bit).
*
* INPUT:
*       chanNum - TWSI channel.
*
* OUTPUT:
*       None.
*
* RETURN:
*       MV_OK is start bit was set successfuly on the bus.
*       MV_FAIL if interrupt flag was set before setting start bit.
*
*******************************************************************************/
MV_STATUS mvTwsiStartBitSet(MV_U8 chanNum)
{
	MV_BOOL isIntFlag = MV_FALSE;
	MV_U32 timeout, temp;

	DB(mvOsPrintf("TWSI: mvTwsiStartBitSet \n"));
	/* check Int flag */
	if (twsiMainIntGet(chanNum))
		isIntFlag = MV_TRUE;
	/* set start Bit */
	temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
	MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_START_BIT);

	/* in case that the int flag was set before i.e. repeated start bit */
	if (isIntFlag) {
		DB(mvOsPrintf("TWSI: mvTwsiStartBitSet repeated start Bit\n"));
		twsiIntFlgClr(chanNum);
	}

	/* wait for interrupt */
	timeout = 0;
	while (!twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE))
		;

	/* check for timeout */
	if (MV_TRUE == twsiTimeoutChk(timeout,
				      (const MV_8 *)"TWSI: mvTwsiStartBitSet ERROR - Start Clear bit TimeOut .\n"))
		return MV_TIMEOUT;

	/* check that start bit went down */
	if ((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_START_BIT) != 0) {
		mvOsPrintf("TWSI: mvTwsiStartBitSet ERROR - start bit didn't went down\n");
		return MV_FAIL;
	}

	/* check the status */
	temp = twsiStsGet(chanNum);
	if ((TWSI_M_LOST_ARB_DUR_AD_OR_DATA_TRA == temp) || (TWSI_M_LOST_ARB_DUR_AD_TRA_GNL_CALL_AD_REC_ACK_TRA == temp)) {
		DB(mvOsPrintf("TWSI: Lost Arb, status %x \n", temp));
		return MV_RETRY;
	} else if ((temp != TWSI_START_CON_TRA) && (temp != TWSI_REPEATED_START_CON_TRA)) {
		mvOsPrintf("TWSI: mvTwsiStartBitSet ERROR - status %x after Set Start Bit. \n", temp);
		return MV_FAIL;
	}

	return MV_OK;

}
Beispiel #6
0
/*******************************************************************************
* twsiInit - Initialize TWSI interface
*
* DESCRIPTION:
*       This routine:
*	-Reset the TWSI.
*	-Initialize the TWSI clock baud rate according to given frequancy
*	 parameter based on Tclk frequancy and enables TWSI slave.
*       -Set the ack bit.
*	-Assign the TWSI slave address according to the TWSI address Type.
*
*
* INPUT:
*	chanNum - TWSI channel
*       frequancy - TWSI frequancy in KHz. (up to 100KHZ)
*
* OUTPUT:
*       None.
*
* RETURN:
*       Actual frequancy.
*
*******************************************************************************/
MV_U32 mvTwsiInit(MV_U8 chanNum, MV_HZ frequancy, MV_U32 Tclk, MV_TWSI_ADDR *pTwsiAddr, MV_BOOL generalCallEnable)
{
	MV_U32	n,m,freq,margin,minMargin = 0xffffffff;
	MV_U32	power;
	MV_U32	actualFreq = 0,actualN = 0,actualM = 0,val;

	if(frequancy > 100000)
	{
		mvOsPrintf("Warning TWSI frequancy is too high, please use up tp 100Khz. \n");
	}

	DB(mvOsPrintf("TWSI: mvTwsiInit - Tclk = %d freq = %d\n",Tclk,frequancy));
	/* Calucalte N and M for the TWSI clock baud rate */
	for(n = 0 ; n < 8 ; n++)
	{
		for(m = 0 ; m < 16 ; m++)
		{
			power = 2 << n; /* power = 2^(n+1) */
			freq = Tclk/(10*(m+1)*power);
			margin = MV_ABS(frequancy - freq);
			if(margin < minMargin)
			{
				minMargin   = margin;
				actualFreq  = freq;
				actualN     = n;
				actualM     = m;
			}
		}
		}
	DB(mvOsPrintf("TWSI: mvTwsiInit - actN %d actM %d actFreq %d\n",actualN , actualM, actualFreq));
	/* Reset the TWSI logic */
	twsiReset(chanNum);

	/* Set the baud rate */
	val = ((actualM<< TWSI_BAUD_RATE_M_OFFS) | actualN << TWSI_BAUD_RATE_N_OFFS);
	MV_REG_WRITE(TWSI_STATUS_BAUDE_RATE_REG(chanNum),val);

	/* Enable the TWSI and slave */
	MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), TWSI_CONTROL_ENA | TWSI_CONTROL_ACK);

	/* set the TWSI slave address */
	if( pTwsiAddr->type == ADDR10_BIT )/* 10 Bit deviceAddress */
	{
		/* writing the 2 most significant bits of the 10 bit address*/
		val = ((pTwsiAddr->address & TWSI_SLAVE_ADDR_10BIT_MASK) >> TWSI_SLAVE_ADDR_10BIT_OFFS );
		/* bits 7:3 must be 0x11110 */
		val |= TWSI_SLAVE_ADDR_10BIT_CONST;
		/* set GCE bit */
		if(generalCallEnable)
			val |= TWSI_SLAVE_ADDR_GCE_ENA;
		/* write slave address */
		MV_REG_WRITE(TWSI_SLAVE_ADDR_REG(chanNum),val);

		/* writing the 8 least significant bits of the 10 bit address*/
		val = (pTwsiAddr->address << TWSI_EXTENDED_SLAVE_OFFS) & TWSI_EXTENDED_SLAVE_MASK;
		MV_REG_WRITE(TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum), val);
	}
/*******************************************************************************
* twsiInit - Initialize TWSI interface
*
* DESCRIPTION:
*       This routine:
*   -Reset the TWSI.
*   -Initialize the TWSI clock baud rate according to given frequancy
*    parameter based on Tclk frequancy and enables TWSI slave.
*       -Set the ack bit.
*   -Assign the TWSI slave address according to the TWSI address Type.
*
* INPUT:
*   chanNum - TWSI channel
*       frequancy - TWSI frequancy in KHz. (up to 100KHZ)
*
* OUTPUT:
*       None.
*
* RETURN:
*       Actual frequancy.
*
*******************************************************************************/
MV_U32 mvTwsiInit(MV_U8 chanNum, MV_HZ frequancy, MV_U32 Tclk, MV_TWSI_ADDR *pTwsiAddr, MV_BOOL generalCallEnable)
{
	MV_U32 n, m, freq, margin, minMargin = 0xffffffff;
	MV_U32 power;
	MV_U32 actualFreq = 0, actualN = 0, actualM = 0, val;

#ifdef MV88F67XX
	/* set twsi MPPS */
	val = (MV_REG_READ(REG_MPP_CONTROL_ADDR) | (REG_MPP_CONTROL_TWSI_VALUE << REG_MPP_CONTROL_TWSI_OFFS));
	MV_REG_WRITE(REG_MPP_CONTROL_ADDR, val);
#endif

	/* Calucalte N and M for the TWSI clock baud rate */
	for (n = 0; n < 8; n++) {
		for (m = 0; m < 16; m++) {
			power = 2 << n;	/* power = 2^(n+1) */
			freq = Tclk / (10 * (m + 1) * power);
			margin = MV_ABS(frequancy - freq);

			if ((freq <= frequancy) && (margin < minMargin)) {
				minMargin = margin;
				actualFreq = freq;
				actualN = n;
				actualM = m;
			}
		}
	}
	/* Reset the TWSI logic */
	twsiReset(chanNum);

	/* Set the baud rate */
	val = ((actualM << TWSI_BAUD_RATE_M_OFFS) | actualN << TWSI_BAUD_RATE_N_OFFS);
	MV_REG_WRITE(TWSI_STATUS_BAUDE_RATE_REG(chanNum), val);

	/* Enable the TWSI and slave */
	MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), TWSI_CONTROL_ENA | TWSI_CONTROL_ACK);

	/* set the TWSI slave address */
	if (pTwsiAddr->type == ADDR10_BIT) {	/* 10 Bit deviceAddress */
		/* writing the 2 most significant bits of the 10 bit address */
		val = ((pTwsiAddr->address & TWSI_SLAVE_ADDR_10BIT_MASK) >> TWSI_SLAVE_ADDR_10BIT_OFFS);
		/* bits 7:3 must be 0x11110 */
		val |= TWSI_SLAVE_ADDR_10BIT_CONST;
		/* set GCE bit */
		if (generalCallEnable)
			val |= TWSI_SLAVE_ADDR_GCE_ENA;
		/* write slave address */
		MV_REG_WRITE(TWSI_SLAVE_ADDR_REG(chanNum), val);

		/* writing the 8 least significant bits of the 10 bit address */
		val = (pTwsiAddr->address << TWSI_EXTENDED_SLAVE_OFFS) & TWSI_EXTENDED_SLAVE_MASK;
		MV_REG_WRITE(TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum), val);
	} else {		/*7 bit address */