Example #1
1
uint32_t I2CWriteSingle(uint32_t i2c_base, uint8_t address, uint8_t reg, uint8_t data) {

	// Set slave register to be written
	while(I2CMasterBusy(i2c_base));
	I2CMasterSlaveAddrSet(i2c_base, address, 0);
	I2CMasterDataPut(i2c_base, reg);
	I2CMasterControl(i2c_base, I2C_MASTER_CMD_BURST_SEND_START);
	while(I2CMasterBusy(i2c_base));

	// Check for errors
	if (I2CMasterErr(i2c_base) != I2C_MASTER_ERR_NONE) return 0;

	// Write data
	I2CMasterDataPut(i2c_base, data);
	I2CMasterControl(i2c_base, I2C_MASTER_CMD_BURST_SEND_CONT);
	while(I2CMasterBusy(i2c_base));

	// Check for errors
	if (I2CMasterErr(i2c_base) != I2C_MASTER_ERR_NONE) return 0;

	// End transmission
	I2CMasterControl(i2c_base, I2C_MASTER_CMD_BURST_SEND_FINISH);
	while(I2CMasterBusy(i2c_base));

	// Check for errors
	if (I2CMasterErr(i2c_base) != I2C_MASTER_ERR_NONE) return 0;

	return 1;
}
Example #2
0
unsigned long I2CController::nolock_read(uint8_t addr, uint8_t *buf, int count, bool sendStartCondition, bool sendStopCondition)
{
	unsigned long ret;

	if (count<1) return 0;
	ret = nolock_read8(addr, buf, sendStartCondition, (sendStopCondition && count==1));
	if (ret != I2C_MASTER_ERR_NONE) {
		return ret;
	}

	for (uint8_t i=1; i<count; i++) {
		I2CMasterControl(_base, ((i==(count-1)) && sendStopCondition) ? I2C_MASTER_CMD_BURST_RECEIVE_FINISH : I2C_MASTER_CMD_BURST_RECEIVE_CONT);
		ret = I2CMasterErr(_base);
		if (ret != I2C_MASTER_ERR_NONE) {
			return ret;
		}
		ret = waitFinish();
		if (ret != I2C_MASTER_ERR_NONE) {
			return ret;
		}
		buf[i] = I2CMasterDataGet(_base);
		ret = I2CMasterErr(_base);
		if (ret != I2C_MASTER_ERR_NONE) {
			return ret;
		}

	}

	return 0;
}
Example #3
0
unsigned long I2CController::nolock_write8(uint8_t addr, uint8_t data, bool sendStartCondition, bool sendStopCondition)
{
	unsigned long ret;

	I2CMasterSlaveAddrSet(_base, addr, 0);
	I2CMasterDataPut(_base, data);
	if (sendStartCondition) {
		I2CMasterControl(_base, sendStopCondition ? I2C_MASTER_CMD_SINGLE_SEND : I2C_MASTER_CMD_BURST_SEND_START);
		ret = I2CMasterErr(_base);
		if (ret != I2C_MASTER_ERR_NONE) {
			return ret;
		}

	} else {
		I2CMasterControl(_base, sendStopCondition ? I2C_MASTER_CMD_BURST_SEND_FINISH : I2C_MASTER_CMD_BURST_SEND_CONT);
		ret = I2CMasterErr(_base);
		if (ret != I2C_MASTER_ERR_NONE) {
			return ret;
		}

	}
	ret = waitFinish();
	if (ret != I2C_MASTER_ERR_NONE) {
		return ret;
	}

	return 0;
}
Example #4
0
unsigned long I2CController::waitFinish(uint32_t timeout_ms)
{
	unsigned long ret;

	if (_interruptsEnabled) {
		if (_interruptSemaphore.take(timeout_ms)) {
			return I2CMasterErr(_base);
		} else {
			return 0xFFFFFFFF; // timeout;
		}
	} else {
		uint32_t timeout_time = Task::getTime() + timeout_ms;
		while (I2CMasterBusy(_base)) {
			ret = I2CMasterErr(_base);
			if (ret != I2C_MASTER_ERR_NONE) {
				return ret;
			}
			if ( (timeout_ms!=0xFFFFFFFF) && (Task::getTime() > timeout_time) ) {
				return 0xFFFFFFFF; // timeout;
			}
			Task::yield();
		}
		return I2CMasterErr(_base);
	}
}
Example #5
0
uint32_t I2CReadSingle(uint32_t i2c_base, uint8_t address, uint8_t reg) {
	uint32_t data = 0;

	// Set slave register to be read
	while(I2CMasterBusy(i2c_base));
	I2CMasterSlaveAddrSet(i2c_base, address, 0);
	I2CMasterDataPut(i2c_base, reg);
	I2CMasterControl(i2c_base, I2C_MASTER_CMD_SINGLE_SEND);
	while(I2CMasterBusy(i2c_base));

	// Check for errors
	if (I2CMasterErr(i2c_base) != I2C_MASTER_ERR_NONE) return 0;

	// Request for register data
	I2CMasterSlaveAddrSet(i2c_base, address, 1);
	I2CMasterControl(i2c_base, I2C_MASTER_CMD_SINGLE_RECEIVE);
	while(I2CMasterBusy(i2c_base));

	// Check for errors
	if (I2CMasterErr(i2c_base) != I2C_MASTER_ERR_NONE) return 0;

	// Read received data
	data = I2CMasterDataGet(i2c_base);

	return data;
}
Example #6
0
unsigned long I2CController::read8(uint8_t addr, uint8_t *data, bool sendStartCondition, bool sendStopCondition)
{
	RecursiveMutexGuard guard(&_lock);
	unsigned long ret;

	I2CMasterSlaveAddrSet(_base, addr, 1);
	if (sendStartCondition) {
		I2CMasterControl(_base, sendStopCondition ? I2C_MASTER_CMD_SINGLE_SEND : I2C_MASTER_CMD_BURST_RECEIVE_START);
		ret = I2CMasterErr(_base);
		if (ret != I2C_MASTER_ERR_NONE) {
			return ret;
		}
	} else {
		I2CMasterControl(_base, sendStopCondition ? I2C_MASTER_CMD_BURST_RECEIVE_FINISH : I2C_MASTER_CMD_BURST_RECEIVE_CONT);
		ret = I2CMasterErr(_base);
		if (ret != I2C_MASTER_ERR_NONE) {
			return ret;
		}
	}
	ret = waitFinish(_defaultTimeout);
	if (ret != I2C_MASTER_ERR_NONE) {
		return ret;
	}

	*data = I2CMasterDataGet(_base);
	ret = I2CMasterErr(_base);
	if (ret != I2C_MASTER_ERR_NONE) {
		return ret;
	}
	return 0;
}
Example #7
0
unsigned long I2CController::read(uint8_t addr, void *ptr, int count, bool sendStartCondition, bool sendStopCondition)
{
	uint8_t *buf = (uint8_t *) ptr;

	RecursiveMutexGuard guard(&_lock);
	unsigned long ret;

	if (count<1) return 0;
	ret = read8(addr, buf, sendStartCondition, (sendStopCondition && count==1));
	if (ret != I2C_MASTER_ERR_NONE) {
		return ret;
	}

	for (uint8_t i=1; i<count; i++) {
		I2CMasterControl(_base, ((i==(count-1)) && sendStopCondition) ? I2C_MASTER_CMD_BURST_RECEIVE_FINISH : I2C_MASTER_CMD_BURST_RECEIVE_CONT);
		ret = I2CMasterErr(_base);
		if (ret != I2C_MASTER_ERR_NONE) {
			return ret;
		}
		ret = waitFinish(_defaultTimeout);
		if (ret != I2C_MASTER_ERR_NONE) {
			return ret;
		}
		buf[i] = I2CMasterDataGet(_base);
		ret = I2CMasterErr(_base);
		if (ret != I2C_MASTER_ERR_NONE) {
			return ret;
		}

	}

	return 0;
}
Example #8
0
unsigned long I2CController::write(uint8_t addr, const void *ptr, int count, bool sendStartCondition, bool sendStopCondition)
{
	const uint8_t *buf = (const uint8_t *) ptr;

	RecursiveMutexGuard guard(&_lock);
	unsigned long ret;

	if (count<1) return 0;

	ret = write8(addr, buf[0], sendStartCondition, (count==1) && sendStopCondition);
	if (ret != I2C_MASTER_ERR_NONE) { return ret; }

	ret = I2CMasterErr(_base);
	if (ret != I2C_MASTER_ERR_NONE) { return ret; }

	for(int i=1; i<count; i++) {
		I2CMasterDataPut(_base, buf[i]);
		I2CMasterControl(_base, (sendStopCondition && (i == count-1)) ? I2C_MASTER_CMD_BURST_SEND_FINISH : I2C_MASTER_CMD_BURST_SEND_CONT);
		ret = I2CMasterErr(_base);
		if (ret != I2C_MASTER_ERR_NONE) {
			return ret;
		}
		ret = waitFinish(_defaultTimeout);
		if (ret != I2C_MASTER_ERR_NONE) {
			return ret;
		}
	}
  return 0;
}
/*
*********************************************************************************************************
*                     BSP_DACReadRegister (CPU_INT08U ucRegister, CPU_INT08U *pucData)
*
* Description : Read a register in the TLV320AIC3107 DAC.
*
* Argument(s) : ucRegister is the offset to the register to write.
*               pucData is a pointer to the returned data.
*
* Return(s)   : True on success or false on error.
*
* Caller(s)   : Sound driver.
*
* Note(s)     : 
*
*********************************************************************************************************
*/
static  CPU_BOOLEAN  BSP_DACReadRegister (CPU_INT08U ucRegister, CPU_INT08U *pucData)
{
    // Set the slave address and "WRITE"/false.
    I2CMasterSlaveAddrSet(DAC_I2C_MASTER_BASE, TI_TLV320AIC3107_ADDR, false);

    // Write the first byte to the controller (register)
    I2CMasterDataPut(DAC_I2C_MASTER_BASE, ucRegister);

    // Continue the transfer.
    I2CMasterControl(DAC_I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);

    // Wait until the current byte has been transferred.
    while(I2CMasterIntStatus(DAC_I2C_MASTER_BASE, false) == 0)
    {
    }

    if(I2CMasterErr(DAC_I2C_MASTER_BASE) != I2C_MASTER_ERR_NONE)
    {
        I2CMasterIntClear(DAC_I2C_MASTER_BASE);
        return(false);
    }

    // Wait until the current byte has been transferred.
    while(I2CMasterIntStatus(DAC_I2C_MASTER_BASE, false))
    {
        I2CMasterIntClear(DAC_I2C_MASTER_BASE);
    }


    // Set the slave address and "READ"/true.
    I2CMasterSlaveAddrSet(DAC_I2C_MASTER_BASE, TI_TLV320AIC3107_ADDR, true);

    // Read Data Byte.
    I2CMasterControl(DAC_I2C_MASTER_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);

    // Wait until the current byte has been transferred.
    while(I2CMasterIntStatus(DAC_I2C_MASTER_BASE, false) == 0)
    {
    }

    if(I2CMasterErr(DAC_I2C_MASTER_BASE) != I2C_MASTER_ERR_NONE)
    {
        I2CMasterIntClear(DAC_I2C_MASTER_BASE);
        return(false);
    }

    // Wait until the current byte has been transferred.
    while(I2CMasterIntStatus(DAC_I2C_MASTER_BASE, false))
    {
        I2CMasterIntClear(DAC_I2C_MASTER_BASE);
    }

	*pucData  = I2CMasterDataGet(DAC_I2C_MASTER_BASE);

    return(true);
}
/*
*********************************************************************************************************
*                        BSP_DACWriteRegister (CPU_INT08U ucRegister, CPU_INT32U ulData)
*
* Description : Write a register in the TLV320AIC3107 DAC.
*
* Argument(s) : ucRegister is the offset to the register to write.
*               ulData is the data to be written to the DAC register.
*
* Return(s)   : True on success or false on error.
*
* Caller(s)   : Sound driver.
*
* Note(s)     : This function will write the register passed in ucAddr with the value
*               passed in to ulData.  The data in ulData is actually 9 bits and the
*               value in ucAddr is interpreted as 7 bits.
*********************************************************************************************************
*/
static  CPU_BOOLEAN  BSP_DACWriteRegister (CPU_INT08U ucRegister, CPU_INT32U ulData)
{
    // Set the slave address.
    I2CMasterSlaveAddrSet(DAC_I2C_MASTER_BASE, TI_TLV320AIC3107_ADDR, false);

    // Write the first byte to the controller (register)
    I2CMasterDataPut(DAC_I2C_MASTER_BASE, ucRegister);

    // Continue the transfer.
    I2CMasterControl(DAC_I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);

    // Wait until the current byte has been transferred.
    while(I2CMasterIntStatus(DAC_I2C_MASTER_BASE, false) == 0)
    {
    }

    if(I2CMasterErr(DAC_I2C_MASTER_BASE) != I2C_MASTER_ERR_NONE)
    {
        I2CMasterIntClear(DAC_I2C_MASTER_BASE);
        return(false);
    }

    // Wait until the current byte has been transferred.
    while(I2CMasterIntStatus(DAC_I2C_MASTER_BASE, false))
    {
        I2CMasterIntClear(DAC_I2C_MASTER_BASE);
    }

    // Write the data byte to the controller.
    I2CMasterDataPut(DAC_I2C_MASTER_BASE, ulData);

    // End the transfer.
    I2CMasterControl(DAC_I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);

    // Wait until the current byte has been transferred.
    while(I2CMasterIntStatus(DAC_I2C_MASTER_BASE, false) == 0)
    {
    }

    if(I2CMasterErr(DAC_I2C_MASTER_BASE) != I2C_MASTER_ERR_NONE)
    {
        return(false);
    }

    while(I2CMasterIntStatus(DAC_I2C_MASTER_BASE, false))
    {
        I2CMasterIntClear(DAC_I2C_MASTER_BASE);
    }

    return(true);
}
Example #11
0
void init_nunchuck(){

    UARTprintf("Initializing Wireless Nunchuck\n\n");   
    while(1){
        I2CSend(0x52<<1, 2, 0xF0, 0x55);
        if (I2CMasterErr(I2C0_MASTER_BASE) == I2C_MASTER_ERR_NONE){
            Wait(1);
            I2CSend(0x52<<1, 2, 0xFB, 0x00);
            if (I2CMasterErr(I2C0_MASTER_BASE) == I2C_MASTER_ERR_NONE)
                break;
        }
        
        Wait(10);
    }
}
Example #12
0
unsigned long I2CController::waitFinish()
{
	unsigned long ret;

	while (I2CMasterBusy(_base)) {
		ret = I2CMasterErr(_base);
		if (ret != I2C_MASTER_ERR_NONE) {
			return ret;
		}
	}
	ret = I2CMasterErr(_base);
	if (ret != I2C_MASTER_ERR_NONE) {
		return ret;
	}
	return 0;
}
static tBoolean
WaitI2CFinished(void)
{
    //
    // Wait until the current byte has been transferred.
    //
    while(ROM_I2CMasterIntStatus(I2C0_MASTER_BASE, false) == 0)
    {
    }

    if(I2CMasterErr(I2C0_MASTER_BASE) != I2C_MASTER_ERR_NONE)
    {
        ROM_I2CMasterIntClear(I2C0_MASTER_BASE);
        return(false);
    }

    //
    // Clear any interrupts set.
    //
    while(ROM_I2CMasterIntStatus(I2C0_MASTER_BASE, false))
    {
        ROM_I2CMasterIntClear(I2C0_MASTER_BASE);
    }

    return(true);
}
Example #14
0
uint32_t I2CReadMultiple(uint32_t i2c_base, uint8_t address, uint8_t reg, uint8_t *data, uint32_t size) {
	uint32_t byte_count;
	uint32_t master_command;

	// Set slave register to be read
	while(I2CMasterBusy(i2c_base));
	I2CMasterSlaveAddrSet(i2c_base, address, 0);
	I2CMasterDataPut(i2c_base, reg);
	I2CMasterControl(i2c_base, I2C_MASTER_CMD_SINGLE_SEND);
	while(I2CMasterBusy(i2c_base));

	// Check for errors
	if (I2CMasterErr(i2c_base) != I2C_MASTER_ERR_NONE) return 0;

	// Start burst read
	I2CMasterSlaveAddrSet(i2c_base, address, 1);
	master_command = I2C_MASTER_CMD_BURST_RECEIVE_START;

	for (byte_count = 0; byte_count < size; byte_count++) {

		// The second byte has to be read with CONT
		if (byte_count == 1) master_command = I2C_MASTER_CMD_BURST_RECEIVE_CONT;

		// The last byte has to be read with FINISH
		if (byte_count == size - 1) master_command = I2C_MASTER_CMD_BURST_RECEIVE_FINISH;

		// If only one byte, reconfigure to SINGLE
		if (size == 1) master_command = I2C_MASTER_CMD_SINGLE_RECEIVE;

		// Initiate read
		I2CMasterControl(i2c_base, master_command);

		// Wait for master operation
		while(I2CMasterBusy(i2c_base));

		// Check for errors
		if (I2CMasterErr(i2c_base) != I2C_MASTER_ERR_NONE) return 0;

		// Put data into array
		data[byte_count] = I2CMasterDataGet(i2c_base);
	}

	return byte_count;
}
Example #15
0
uint8_t TwoWire::sendTxData(unsigned long cmd, uint8_t data) {
    while(I2CMasterBusy(MASTER_BASE));
    I2CMasterDataPut(MASTER_BASE, data);

    HWREG(MASTER_BASE + I2C_O_MCS) = cmd;
    while(I2CMasterBusy(MASTER_BASE));
    uint8_t error = I2CMasterErr(MASTER_BASE);
    if (error != I2C_MASTER_ERR_NONE)
          I2CMasterControl(MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_ERROR_STOP);
    return(getError(error));
}
Example #16
0
uint32_t I2CWriteMultiple(uint32_t i2c_base, uint8_t address, uint8_t reg, uint8_t *data, uint32_t size) {
	uint32_t byte_count;
	uint32_t master_command;

	// Set slave register to be written
	while(I2CMasterBusy(i2c_base));
	I2CMasterSlaveAddrSet(i2c_base, address, 0);
	I2CMasterDataPut(i2c_base, reg);
	I2CMasterControl(i2c_base, I2C_MASTER_CMD_BURST_SEND_START);
	while(I2CMasterBusy(i2c_base));

	// Check for errors
	if (I2CMasterErr(i2c_base) != I2C_MASTER_ERR_NONE) return 0;

	// Start burst write
	master_command = I2C_MASTER_CMD_BURST_SEND_CONT;

	for (byte_count = 0; byte_count < size; byte_count++) {

		// The second byte has to be sent with CONT
		if (byte_count == 1) master_command = I2C_MASTER_CMD_BURST_SEND_CONT;

		// The last byte has to be sent with FINISH
		if (byte_count == size - 1) master_command = I2C_MASTER_CMD_BURST_SEND_FINISH;

		// If only one byte, reconfigure to SINGLE
		if (size == 1) master_command = I2C_MASTER_CMD_SINGLE_SEND;

		// Write byte
		I2CMasterDataPut(i2c_base, data[byte_count]);
		I2CMasterControl(i2c_base, master_command);

		// Wait for master operation
		while(I2CMasterBusy(i2c_base));

		// Check for errors
		if (I2CMasterErr(i2c_base) != I2C_MASTER_ERR_NONE) return 0;
	}

	return 1;
}
Example #17
0
unsigned long I2CController::nolock_write(uint8_t addr, uint8_t *buf, int count, bool sendStartCondition, bool sendStopCondition)
{
	unsigned long ret;

	if (count<1) return 0;
	nolock_write8(addr, buf[0], sendStartCondition, (count==1) && sendStopCondition);
	ret = I2CMasterErr(_base);
	if (ret != I2C_MASTER_ERR_NONE) {
		return ret;
	}
	for(int i=1; i<count; i++) {
		I2CMasterDataPut(_base, buf[i]);
		I2CMasterControl(_base, (sendStopCondition && (i == count-1)) ? I2C_MASTER_CMD_BURST_SEND_FINISH : I2C_MASTER_CMD_BURST_SEND_CONT);
		ret = I2CMasterErr(_base);
		if (ret != I2C_MASTER_ERR_NONE) {
			return ret;
		}
		ret = waitFinish();
		if (ret != I2C_MASTER_ERR_NONE) {
			return ret;
		}
	}
  return 0;
}
Example #18
0
void i2c3_master_interrupt(void) {
	unsigned long status = I2CMasterIntStatusEx(I2C3_MASTER_BASE, false);
	if (status & I2C_MASTER_INT_TIMEOUT) {
		i2c_flag = 2;
		I2CMasterIntClearEx(I2C3_MASTER_BASE, I2C_MASTER_INT_TIMEOUT);
	}
	if (status & I2C_MASTER_INT_DATA) {
		err = I2CMasterErr(I2C3_MASTER_BASE);
		if (err != I2C_MASTER_ERR_NONE)
			i2c_flag = 2;

		if (what_we_re_doing == sending) {
			sent_bytes++;
			if (sent_bytes < sizeof(data)-1) {
				//Continuing
				 I2CMasterDataPut(I2C3_MASTER_BASE, ((unsigned char *)&data)[sent_bytes]);
				 I2CMasterControl(I2C3_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
			}
			else if (sent_bytes == sizeof(data)-1) {
				//Last byte remaining
				 I2CMasterDataPut(I2C3_MASTER_BASE, ((unsigned char *)&data)[sent_bytes]);
				 I2CMasterControl(I2C3_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
			}
			else {
				//Transaction is done
				i2c_flag = 1;
			}
		}
		else if (what_we_re_doing == receiving) {
			unsigned char *p = (unsigned char *)&data_recv + received_bytes;
			*p = I2CMasterDataGet(I2C3_MASTER_BASE);
			received_bytes++;
			if (received_bytes < sizeof(data_recv) - 1) {
				I2CMasterControl(I2C3_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
			}
			else if (received_bytes == sizeof(data_recv) - 1) {
				I2CMasterControl(I2C3_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
			}
			else {
				//Transaction is done
				i2c_flag = 1;
			}
		}


		I2CMasterIntClearEx(I2C3_MASTER_BASE, I2C_MASTER_INT_DATA);
	}
}
Example #19
0
/**
 * Verifies that a transmission from the master has completed successfully
 *
 * \param ui32base Base address of the I2C peripheral 
 *
 * \param burst Set to true if burst mode was used for the transmission
 *
 * \param receive Set to true if a receive transmission is to be verified
 * Set to false if a send transmission is to be verified
 *
 * \note Waits until a transmission is complete and then checks that no errors have occurred
 *
 * \note If an error occurs the I2C transmission is stopped, the error LED is lit and the
 * program enters an infinite loop to hold the state.
 **/
void twe_I2CMasterVerify(uint32_t ui32base, bool burst, bool receive) {
	while(I2CMasterBusy(ui32base)) {} // Wait until the transfer is complete
	//uint32_t errorStatus = I2CMasterErr(ui32Base);
	if(I2CMasterErr(ui32base) != I2C_MASTER_ERR_NONE) {

		// An error has occured
		if(burst && !receive) {
			I2CMasterControl(ui32base, I2C_MASTER_CMD_BURST_SEND_ERROR_STOP);
		}
		else if(burst && !receive) {
			I2CMasterControl(ui32base, I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP);
		}

		while(1) {} // Capture state
	}
}
Example #20
0
uint8_t TwoWire::getRxData(unsigned long cmd) {

    if (currentState == IDLE) while(I2CMasterBusBusy(MASTER_BASE));
    HWREG(MASTER_BASE + I2C_O_MCS) = cmd;
    while(I2CMasterBusy(MASTER_BASE));
    uint8_t error = I2CMasterErr(MASTER_BASE);
    if (error != I2C_MASTER_ERR_NONE) {
        I2CMasterControl(MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP);
    }
    else {
        while(I2CMasterBusy(MASTER_BASE));
        rxBuffer[rxWriteIndex] = I2CMasterDataGet(MASTER_BASE);
        rxWriteIndex = (rxWriteIndex + 1) % BUFFER_LENGTH;
    }
    return error;

}
Example #21
0
//Initialize as a master
void TwoWire::begin(void)
{

  if(i2cModule == NOT_ACTIVE) {
      i2cModule = BOOST_PACK_WIRE;
  }

  SysCtlPeripheralEnable(g_uli2cPeriph[i2cModule]);

  //Configure GPIO pins for I2C operation
  GPIOPinConfigure(g_uli2cConfig[i2cModule][0]);
  GPIOPinConfigure(g_uli2cConfig[i2cModule][1]);
  GPIOPinTypeI2C(g_uli2cBase[i2cModule], g_uli2cSDAPins[i2cModule]);
  GPIOPinTypeI2CSCL(g_uli2cBase[i2cModule], g_uli2cSCLPins[i2cModule]);
  I2CMasterInitExpClk(MASTER_BASE, F_CPU, false);//max bus speed=400kHz for gyroscope

  //force a stop condition
  if(!GPIOPinRead(g_uli2cBase[i2cModule], g_uli2cSCLPins[i2cModule]))
      forceStop();

  //Handle any startup issues by pulsing SCL
  if(I2CMasterBusBusy(MASTER_BASE) || I2CMasterErr(MASTER_BASE)
    || !GPIOPinRead(g_uli2cBase[i2cModule], g_uli2cSCLPins[i2cModule])){
      uint8_t doI = 0;
        GPIOPinTypeGPIOOutput(g_uli2cBase[i2cModule], g_uli2cSCLPins[i2cModule]);
        unsigned long mask = 0;
        do{
            for(unsigned long i = 0; i < 10 ; i++) {
                SysCtlDelay(F_CPU/100000/3);//100Hz=desired frequency, delay iteration=3 cycles
                mask = (i%2) ? g_uli2cSCLPins[i2cModule] : 0;
                GPIOPinWrite(g_uli2cBase[i2cModule], g_uli2cSCLPins[i2cModule], mask);
            }
            doI++;
        }while(I2CMasterBusBusy(MASTER_BASE) && doI < 100);

        GPIOPinTypeI2CSCL(g_uli2cBase[i2cModule], g_uli2cSCLPins[i2cModule]);
        if(!GPIOPinRead(g_uli2cBase[i2cModule], g_uli2cSCLPins[i2cModule]))
            forceStop();

  }

}
//*****************************************************************************
//
// Write a register in the TLV320AIC23B DAC.
//
// \param ucRegister is the offset to the register to write.
// \param ulData is the data to be written to the DAC register.
//
// This function will write the register passed in /e ucAddr with the value
// passed in to /e ulData.  The data in \e ulData is actually 9 bits and the
// value in /e ucAddr is interpreted as 7 bits.
//
// \return Returns \b true on success or \b false on error.
//
//*****************************************************************************
static tBoolean
TLV320AIC23BWriteRegister(unsigned char ucRegister, unsigned long ulData)
{
    //
    // Set the slave address.
    //
    I2CMasterSlaveAddrSet(DAC_I2C_MASTER_BASE, TI_TLV320AIC23B_ADDR_0, false);

    //
    // Write the next byte to the controller.
    //
    I2CMasterDataPut(DAC_I2C_MASTER_BASE, ucRegister | ((ulData >> 8) & 1));

    //
    // Continue the transfer.
    //
    I2CMasterControl(DAC_I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);

    //
    // Wait until the current byte has been transferred.
    //
    while(I2CMasterIntStatus(DAC_I2C_MASTER_BASE, false) == 0)
    {
    }

    if(I2CMasterErr(DAC_I2C_MASTER_BASE) != I2C_MASTER_ERR_NONE)
    {
        I2CMasterIntClear(DAC_I2C_MASTER_BASE);
        return(false);
    }

    //
    // Wait until the current byte has been transferred.
    //
    while(I2CMasterIntStatus(DAC_I2C_MASTER_BASE, false))
    {
        I2CMasterIntClear(DAC_I2C_MASTER_BASE);
    }

    //
    // Write the next byte to the controller.
    //
    I2CMasterDataPut(DAC_I2C_MASTER_BASE, ulData);

    //
    // End the transfer.
    //
    I2CMasterControl(DAC_I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);

    //
    // Wait until the current byte has been transferred.
    //
    while(I2CMasterIntStatus(DAC_I2C_MASTER_BASE, false) == 0)
    {
    }

    if(I2CMasterErr(DAC_I2C_MASTER_BASE) != I2C_MASTER_ERR_NONE)
    {
        return(false);
    }

    while(I2CMasterIntStatus(DAC_I2C_MASTER_BASE, false))
    {
        I2CMasterIntClear(DAC_I2C_MASTER_BASE);
    }

    return(true);
}
Example #23
0
//*****************************************************************************
//
//! Reads the I2C slave register.
//!
//! \param ulI2CBase is the base for the I2C module.
//! \param ucSlaveAdress is the 7-bit address of the slave to be addressed.
//! \param ucReg is the register to read from.
//!
//! This function initiates a read from the slave device.
//! The ulI2CBase parameter is the I2C modules master base address.
//! \e ulI2CBase parameter can be one of the following values:
//!
//! - \b I2C0_MASTER_BASE
//! - \b I2C1_MASTER_BASE
//! - \b I2C2_MASTER_BASE
//! - \b I2C3_MASTER_BASE
//!
//! \return Register value in an unsigned long format.  Note that 0 will be
//! returned if there is ever an error, 1 if there was not.
//
//*****************************************************************************
unsigned long
I2CRegRead(unsigned long ulI2CBase, unsigned char ucSlaveAdress, unsigned char ucReg)
{
unsigned long ulRegValue = 0;

	//
	// Check the arguments.
	//
	ASSERT(I2CMasterBaseValid(ulI2CBase));

	//
	// Wait until master module is done transferring.
	//
	while(I2CMasterBusy(ulI2CBase))
	{
	};

    //
    // Tell the master module what address it will place on the bus when
    // writing to the slave.
    //
    I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, 0);

    //
    // Place the command to be sent in the data register.
    //
    I2CMasterDataPut(ulI2CBase, ucReg);

    //
    // Initiate send of data from the master.
    //
    I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_SINGLE_SEND);

    //
    // Wait until master module is done transferring.
    //
    while(I2CMasterBusy(ulI2CBase))
    {
    };

    //
    // Check for errors.
    //
    if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    {
        return 0;
    }

    //
    // Tell the master module what address it will place on the bus when
    // reading from the slave.
    //
    I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, 1);

    //
    // Tell the master to read data.
    //
    I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_SINGLE_RECEIVE);

    //
    // Wait until master module is done receiving.
    //
    while(I2CMasterBusy(ulI2CBase))
    {
    };

    //
    // Check for errors.
    //
    if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    {
        return 0;
    }

    //
    // Read the data from the master.
    //
    ulRegValue = I2CMasterDataGet(ulI2CBase);

    //
    // Return the register value.
    //
    return ulRegValue;
}
Example #24
0
//*****************************************************************************
//
//! Writes to the specified I2C slave register.
//!
//! \param ulI2CBase is the base for the I2C module.
//! \param ucSlaveAdress is the 7-bit address of the slave to be addressed.
//! \param ucReg is the register to write data to.
//! \param ucValue is the 8-bit data to be written.
//!
//! This function initiates a read from the I2C slave device.
//! The ulI2CBase parameter is the I2C modules master base address.
//! \e ulI2CBase parameter can be one of the following values:
//!
//! - \b I2C0_MASTER_BASE
//! - \b I2C1_MASTER_BASE
//! - \b I2C2_MASTER_BASE
//! - \b I2C3_MASTER_BASE
//!
//! \return Register value in an unsigned long format.  Note that 0 will be
//! returned if there is ever an error, 1 if there was not.
//
//*****************************************************************************
unsigned long
I2CRegWrite(unsigned long ulI2CBase, unsigned char ucSlaveAdress,
		 unsigned char ucReg, unsigned char ucValue)
{
	//
	// Check the arguments.
	//
	ASSERT(I2CMasterBaseValid(ulI2CBase));

	//
	// Wait until master module is done transferring.
	//
	while(I2CMasterBusy(ulI2CBase))
	{
	};

    //
    // Tell the master module what address it will place on the bus when
    // writing to the slave.
    //
    I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, 0);

    //
    // Place the command to be sent in the data register.
    //
    I2CMasterDataPut(ulI2CBase, ucReg);

    //
    // Initiate send of data from the master.
    //
    I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_START);

    //
    // Wait until master module is done transferring.
    //
    while(I2CMasterBusy(ulI2CBase))
    {
    };

    //
    // Check for errors.
    //
    if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    {
        return 0;
    }

    //
    // Place the value to be sent in the data register.
    //
    I2CMasterDataPut(ulI2CBase, ucValue);

    //
    // Initiate send of data from the master.
    //
    I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_CONT);

    //
    // Wait until master module is done transferring.
    //
    while(I2CMasterBusy(ulI2CBase))
    {
    };

    //
    // Check for errors.
    //
    if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    {
        return 0;
    }

    //
    // Initiate send of data from the master.
    //
    I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_FINISH);

    //
    // Wait until master module is done transferring.
    //
    while(I2CMasterBusy(ulI2CBase))
    {
    };

    //
    // Check for errors.
    //
    if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    {
        return 0;
    }

    //
    // Return 1 if there is no error.
    //
    return 1;
}
Example #25
0
//*****************************************************************************
//
//! Writes one/multiple bytes of data to an I2C slave device.
//! Ensure to use auto-increment options on some devices
//! (Control Registers, refer to data sheet).
//! I.e. store related command in the first position of your data array.
//!
//! \param ulI2CBase is the base for the I2C module.
//! \param ucSlaveAdress is the 7-bit address of the slave to be addressed.
//! \param ucReg is the register to start writing to.
//! \param cSendData is a pointer to the array to be send.
//! \param uiSize is the number of bytes to send from array cSendData[].
//!
//! This function writes multiple bytes of data an I2C slave device.
//! The ulI2CBase parameter is the I2C modules master base address.
//! \e ulI2CBase parameter can be one of the following values:
//!
//! - \b I2C0_MASTER_BASE
//! - \b I2C1_MASTER_BASE
//! - \b I2C2_MASTER_BASE
//! - \b I2C3_MASTER_BASE
//!
//! \return 0 if there was an error or 1 if there was not.
//
//*****************************************************************************
unsigned long
I2CWriteData(unsigned long ulI2CBase, unsigned char ucSlaveAdress,
		unsigned char ucReg, char* cSendData, unsigned int uiSize)
{
	unsigned int uibytecount;		// local variable used for byte counting/state determination
	int MasterOptionCommand;		// used to assign the commands for ROM_I2CMasterControl() function

	//
	// Check the arguments.
	//
	ASSERT(I2CMasterBaseValid(ulI2CBase));

	//
	// Wait until master module is done transferring.
	//
	while(I2CMasterBusy(ulI2CBase))
	{
	};

    //
    // Tell the master module what address it will place on the bus when
    // writing to the slave.
    //
    I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, false);

    //
    // Place the value to be sent in the data register.
    //
    I2CMasterDataPut(ulI2CBase, ucReg);

    //
    // Initiate send of data from the master.
    //
    I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_START);

    //
    // Wait until master module is done transferring.
    //
    while(I2CMasterBusy(ulI2CBase))
    {
    };

    //
    // Check for errors.
    //
    if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    {
        return 0;
    }

	//
	// Start with CONT for more than one byte to write
	//
	MasterOptionCommand = I2C_MASTER_CMD_BURST_SEND_CONT;


	for(uibytecount = 0; uibytecount < uiSize; uibytecount++)
	{
		//
		// The second and intermittent byte has to be send with CONTINUE control word
		//
		if(uibytecount == 1)
			MasterOptionCommand = I2C_MASTER_CMD_BURST_SEND_CONT;

		//
		// The last byte has to be send with FINISH control word
		//
		if(uibytecount == uiSize - 1)
			MasterOptionCommand = I2C_MASTER_CMD_BURST_SEND_FINISH;

		//
		// Re-configure to SINGLE if there is only one byte to write
		//
		if(uiSize == 1)
			MasterOptionCommand = I2C_MASTER_CMD_SINGLE_SEND;

		//
		// Send data byte
		//
		I2CMasterDataPut(ulI2CBase, cSendData[uibytecount]);

		//
		// Initiate send of data from the master.
		//
		I2CMasterControl(ulI2CBase, MasterOptionCommand);

		//
		// Wait until master module is done transferring.
		//
		while(I2CMasterBusy(ulI2CBase))
		{
		};

		//
        // Check for errors.
        //
        if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
        {
            return 0;
        }
	}

    //
    // Return 1 if there is no error.
    //
    return 1;
}
Example #26
0
int main(void){
    char i;
	unsigned char data[16];
    short wiichuck[7], xinit=0, yinit=0, l_vel, r_vel;
    int xpow, ypow;

 	LockoutProtection();
	InitializeMCU();
	InitializeUART();
    InitializeI2C();
    
	InitializeServos();
    SetServoPosition(SERVO_0, 140);
    
	InitializeMotors(true, false);
	InitializeEncoders(true, false);
    
//	UARTprintf("Initializing Nunchuck\n\n");
//	I2CSend(0x52<<1, 2, 0x40, 0x00);
//  Wait(25);
    
    init_nunchuck();
    
    // Wireless Nunchucks Zero @ 128
    xinit = yinit = 128;
        
	while(1){
		//Start Recalculating Values
        Wait(1);
		I2CSend(0x52<<1, 1, 0x00);
        Wait(1);   
		I2CSend(0x52<<1, 1, 0x00);
        Wait(1);     
		I2CSend(0x52<<1, 1, 0x00);
        
        if (I2CMasterErr(I2C0_MASTER_BASE) != I2C_MASTER_ERR_NONE){
            UARTprintf("Send Zero Error:\n");
            switch(I2CMasterErr(I2C0_MASTER_BASE)){
                case I2C_MASTER_ERR_ADDR_ACK:
                    UARTprintf(" I2C_MASTER_ERR_ADDR_ACK\n");
                    break;
                case I2C_MASTER_ERR_DATA_ACK:
                    UARTprintf(" I2C_MASTER_ERR_DATA_ACK\n");
                    break;
                case I2C_MASTER_ERR_ARB_LOST:
                    UARTprintf(" I2C_MASTER_ERR_ARB_LOST\n");
                    break;
                default:
                    UARTprintf("WTF: %d\n", I2CMasterErr(I2C0_MASTER_BASE));
            }
            
            // Reinitialize Nunchuck on error
            init_nunchuck();
        }else{
            Wait(1);
            I2CRecieve(0x52<<1, data, 6);   // Nunchuck data is 6 bytes, but for whatever reason, MEMOREX Wireless Nunchuck wants to send 8...
            
            if (I2CMasterErr(I2C0_MASTER_BASE) != I2C_MASTER_ERR_NONE){
                UARTprintf("Send Zero Error:\n");
                switch(I2CMasterErr(I2C0_MASTER_BASE)){
                    case I2C_MASTER_ERR_ADDR_ACK:
                        UARTprintf(" I2C_MASTER_ERR_ADDR_ACK\n");
                        break;
                    case I2C_MASTER_ERR_DATA_ACK:
                        UARTprintf(" I2C_MASTER_ERR_DATA_ACK\n");
                        break;
                    case I2C_MASTER_ERR_ARB_LOST:
                        UARTprintf(" I2C_MASTER_ERR_ARB_LOST\n");
                        break;
                }
                
                // Reinitialize Nunchuck on error
                init_nunchuck();
            }else{
                //for(i=0; i<6; i++)
                //    data[i] = (data[i] ^ 0x17) + 0x17;  // Nintendo decided to encrypt thir data...
        
        		// Save Joystick Data
        		wiichuck[0] = data[1];                                          // X Axis Joystick
        	    wiichuck[1] = data[0];                                          // Y Axis Joystick
        		wiichuck[2] = (((unsigned short) data[2]) << 2) + (((unsigned short) data[5]) & (3<<2));    // X Axis Accel
        		wiichuck[3] = (((unsigned short) data[3]) << 2) + (((unsigned short) data[5]) & (3<<4));    // Y Axis Accel
        		wiichuck[4] = (((unsigned short) data[4]) << 2) + (((unsigned short) data[5]) & (3<<6));    // Z Axis Accel
        		wiichuck[5] = data[5] & (1 << 1) ? 0 : 1;                              //'C' Button 
        		wiichuck[6] = data[5] & (1 << 0) ? 0 : 1;                              //'Z' Button
            
            //if (xinit == 0 && yinit == 0){
            //    xinit = wiichuck[0]-127;
            //    yinit = wiichuck[1]-127;
           //}else{
                xpow = (wiichuck[0]-xinit)/2;
                ypow = (wiichuck[1]-yinit)/2;
                l_vel = (xpow - ypow)*2;
                r_vel = (xpow + ypow)*2;
                
                l_vel = l_vel > 127 ? 127 : l_vel;
                r_vel = r_vel > 127 ? 127 : r_vel;
                l_vel = l_vel < -127 ? -127 : l_vel;
                r_vel = r_vel < -127 ? -127 : r_vel;
                
                //UARTprintf("X: %d\tY: %d\n", xpow*2, ypow*2);
                SetMotorPowers(l_vel / (wiichuck[5]==0 ? 2 : 1), r_vel / (wiichuck[5]==0 ? 2 : 1));
                UARTprintf("Motor L: %d\tMotor R: %d\n", l_vel, r_vel);
                SetServoPosition(SERVO_0, wiichuck[6]==1 ? 255 : 140);
                UARTprintf("Nunchuck Data:\n");
                for(i=0; i<7; i++){
                    UARTprintf(" %d\n", wiichuck[i]);
                }NL;
                
                Wait(100);
            }
        }
	}
}
Example #27
0
//*****************************************************************************
//
//! Probes the selected I2C bus for available slave devices
//!
//! \param ulI2CBase is the base for the I2C module.
//!
//! This function scans the selected I2C bus for available I2C slave device.
//! The ulI2CBase parameter is the I2C modules master base address.
//! \e ulI2CBase parameter can be one of the following values:
//!
//! - \b I2C0_MASTER_BASE
//! - \b I2C1_MASTER_BASE
//! - \b I2C2_MASTER_BASE
//! - \b I2C3_MASTER_BASE
//!
//! \return 0 if there was an error or 1 if there was not.
//
//*****************************************************************************
unsigned long
I2CBusScan(unsigned long ulI2CBase)
{
	unsigned char ucProbeAdress;
	unsigned long ucerrorstate;

	//
	// Check the arguments.
	//
	ASSERT(I2CMasterBaseValid(ulI2CBase));

	//
	// Wait until master module is done transferring.
	//
	while(I2CMasterBusy(ulI2CBase))
	{
	};

	//
	// I2C Addresses are 7-bit values
	// probe the address range of 0 to 127 to find I2C slave devices on the bus
	//
	for (ucProbeAdress = 0; ucProbeAdress < 127; ucProbeAdress++)
	{
	    //
	    // Tell the master module what address it will place on the bus when
	    // writing to the slave.
	    //
		I2CMasterSlaveAddrSet(ulI2CBase, ucProbeAdress, false);
	    SysCtlDelay(50000);

	    //
	    // Place the command to be sent in the data register.
	    //
	    I2CMasterDataPut(ulI2CBase, 0x00);

	    //
	    // Initiate send of data from the master.
	    //
	    I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_START);

	    //
	    // Make some delay
	    //
	    SysCtlDelay(500000);

	    //
	    // Read the I2C Master Control/Status (I2CMCS) Register to a local
	    // variable
	    //
	    ucerrorstate = I2CMasterErr(ulI2CBase);

	    //
	    // Examining the content I2C Master Control/Status (I2CMCS) Register
	    // to see if the ADRACK-Bit (Acknowledge Address) is TRUE (1)
	    // ( 1: The transmitted address was not acknowledged by the slave)
	    //
	    if(ucerrorstate & I2C_MASTER_ERR_ADDR_ACK)
	    {
	    	//
	    	// device at selected address did not acknowledge --> there's no device
	    	// with this address present on the I2C bus
	    	//
	        //
	        // Print a message to Stdio
	        //
	    	//UARTprintf("Address not found: 0x%2x - %3d\n",ucProbeAdress,ucProbeAdress);
		    //
		    // Make some delay
		    //
	    	//ROM_SysCtlDelay(1500000);
	    }

	    //
	    // ( 0: The transmitted address was acknowledged by the slave)
	    //
	    else
	    {
	    	//
	    	// device at selected address acknowledged --> there is a device
	    	// with this address present on the I2C bus
	    	//
	        //
	        // Print a message to Stdio
	        //
	    	//UARTprintf("Address found: 0x%2x - %3d\n",ucProbeAdress,ucProbeAdress);

		    //
		    // Make some delay
		    //
	    	SysCtlDelay(1500000);
	    }
	}

	//
	// End transfer of data from the master.
	//
	I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);

    //
    // Print a message to Stdio
    //
	//UARTprintf("I2C Bus-Scan done...\n");

    //
    // Return 1 if there is no error.
    //
    return 1;
}
/*
 *  ======== I2CCC26XX_hwiFxn ========
 *  Hwi interrupt handler to service the I2C peripheral
 *
 *  The handler is a generic handler for a I2C object.
 */
static void I2CCC26XX_hwiFxn(UArg arg)
{
    I2CDataType              errStatus;
    I2CCC26XX_Object         *object;
    I2CCC26XX_HWAttrs const  *hwAttrs;

    /* Get the pointer to the object and hwAttrs */
    object = ((I2C_Handle)arg)->object;
    hwAttrs = ((I2C_Handle)arg)->hwAttrs;

    /* Get the interrupt status of the I2C controller */
    errStatus = I2CMasterErr(hwAttrs->baseAddr);

    /* Clear interrupt source to avoid additional interrupts */
    I2CMasterIntClear(hwAttrs->baseAddr);

    /* Check for I2C Errors */
    if ((errStatus == I2C_MASTER_ERR_NONE) || (object->mode == I2CCC26XX_ERROR)) {

        /* No errors, now check what we need to do next */
        switch (object->mode) {

            /*
             * ERROR case is OK because if an Error is detected, a STOP bit is
             * sent; which in turn will call another interrupt. This interrupt
             * call will then post the transferComplete semaphore to unblock the
             * I2C_transfer function
             */
            case I2CCC26XX_ERROR:
                break;

            case I2CCC26XX_IDLE_MODE:
                I2CCC26XX_completeTransfer((I2C_Handle) arg);
                break;

            case I2CCC26XX_WRITE_MODE:
                /* Decrement write Counter */
                object->writeCountIdx--;

                /* Check if more data needs to be sent */
                if (object->writeCountIdx) {
                    Log_print3(Diags_USER2,
                            "I2C:(%p) ISR I2CCC26XX_WRITE_MODE: Data to write: 0x%x; "
                            "To slave: 0x%x",
                            hwAttrs->baseAddr,
                            *(object->writeBufIdx),
                            object->currentTransaction->slaveAddress);

                    /* Write data contents into data register */
                    I2CMasterDataPut(hwAttrs->baseAddr,
                                   *(object->writeBufIdx));
                    object->writeBufIdx++;

                    if ((object->writeCountIdx < 2) && !(object->readCountIdx)) {
                        /* Everything has been sent, nothing to receive */
                        /* Next state: Idle mode */
                        object->mode = I2CCC26XX_IDLE_MODE;

                        /* Send last byte with STOP bit */
                        I2CMasterControl(hwAttrs->baseAddr,
                                I2C_MASTER_CMD_BURST_SEND_FINISH);

                        Log_print1(Diags_USER2,
                                "I2C:(%p) ISR I2CCC26XX_WRITE_MODE: ACK received; "
                                "Writing w/ STOP bit",
                                hwAttrs->baseAddr);
                    }
                    else {
                        /*
                         * Either there is more date to be transmitted or some
                         * data needs to be received next
                         */
                        I2CMasterControl(hwAttrs->baseAddr,
                                I2C_MASTER_CMD_BURST_SEND_CONT);

                        Log_print1(Diags_USER2,
                                "I2C:(%p) ISR I2CCC26XX_WRITE_MODE: ACK received; Writing",
                                hwAttrs->baseAddr);
                    }
                }

                /* At this point, we know that we need to receive data */
                else {
                    /*
                     * We need to check after we are done transmitting data, if
                     * we need to receive any data.
                     * In a corner case when we have only one byte transmitted
                     * and no data to receive, the I2C will automatically send
                     * the STOP bit. In other words, here we only need to check
                     * if data needs to be received. If so, how much.
                     */
                    if (object->readCountIdx) {
                        /* Next state: Receive mode */
                        object->mode = I2CCC26XX_READ_MODE;

                        /* Switch into Receive mode */
                        I2CMasterSlaveAddrSet(hwAttrs->baseAddr,
                                object->currentTransaction->slaveAddress, true);

                        if (object->readCountIdx > 1) {
                            /* Send a repeated START */
                            I2CMasterControl(hwAttrs->baseAddr,
                                    I2C_MASTER_CMD_BURST_RECEIVE_START);

                            Log_print1(Diags_USER2,
                                "I2C:(%p) ISR I2CCC26XX_WRITE_MODE: -> I2CCC26XX_READ_MODE; "
                                "Reading w/ RESTART and ACK",
                                hwAttrs->baseAddr);
                        }
                        else {
                            /*
                             * Send a repeated START with a NACK since it's the
                             * last byte to be received.
                             * I2C_MASTER_CMD_BURST_RECEIVE_START_NACK is
                             * is locally defined because there is no macro to
                             * receive data and send a NACK after sending a
                             * start bit (0x00000003)
                             */
                            I2CMasterControl(hwAttrs->baseAddr,
                                    I2C_MASTER_CMD_BURST_RECEIVE_START_NACK);

                            Log_print1(Diags_USER2,
                                "I2C:(%p) ISR I2CCC26XX_WRITE_MODE: -> I2CCC26XX_READ_MODE; "
                                "Reading w/ RESTART and NACK",
                                hwAttrs->baseAddr);
                        }
                    }
                    else {
                        /* Done with all transmissions */
                        object->mode = I2CCC26XX_IDLE_MODE;
                        /*
                         * No more data needs to be received, so follow up with
                         * a STOP bit
                         * Again, there is no equivalent macro (0x00000004) so
                         * I2C_MASTER_CMD_BURST_RECEIVE_STOP is used.
                         */
                        I2CMasterControl(hwAttrs->baseAddr,
                                I2C_MASTER_CMD_BURST_RECEIVE_STOP);

                        Log_print1(Diags_USER2,
                                "I2C:(%p) ISR I2CCC26XX_WRITE_MODE: -> I2CCC26XX_IDLE_MODE; "
                                "Sending STOP bit",
                                hwAttrs->baseAddr);

                    }
                }
                break;

            case I2CCC26XX_READ_MODE:
                /* Save the received data */
                *(object->readBufIdx) =
                    I2CMasterDataGet(hwAttrs->baseAddr);

                Log_print2(Diags_USER2,
                        "I2C:(%p) ISR I2CCC26XX_READ_MODE: Read data byte: 0x%x",
                        hwAttrs->baseAddr,
                        *(object->readBufIdx));

                object->readBufIdx++;

                /* Check if any data needs to be received */
                object->readCountIdx--;
                if (object->readCountIdx) {
                    if (object->readCountIdx > 1) {
                        /* More data to be received */
                        I2CMasterControl(hwAttrs->baseAddr,
                                I2C_MASTER_CMD_BURST_RECEIVE_CONT);

                        Log_print1(Diags_USER2,
                                "I2C:(%p) ISR I2CCC26XX_READ_MODE: Reading w/ ACK",
                                hwAttrs->baseAddr);
                    }
                    else {
                        /*
                         * Send NACK because it's the last byte to be received
                         * There is no NACK macro equivalent (0x00000001) so
                         * I2C_MASTER_CMD_BURST_RECEIVE_CONT_NACK is used
                         */
                        I2CMasterControl(hwAttrs->baseAddr,
                                I2C_MASTER_CMD_BURST_RECEIVE_CONT_NACK);

                        Log_print1(Diags_USER2,
                                "I2C:(%p) ISR I2CCC26XX_READ_MODE: Reading w/ NACK",
                                hwAttrs->baseAddr);
                    }
                }
                else {
                    /* Next state: Idle mode */
                    object->mode = I2CCC26XX_IDLE_MODE;

                    /*
                     * No more data needs to be received, so follow up with a
                     * STOP bit
                     * Again, there is no equivalent macro (0x00000004) so
                     * I2C_MASTER_CMD_BURST_RECEIVE_STOP is used
                     */
                    I2CMasterControl(hwAttrs->baseAddr,
                            I2C_MASTER_CMD_BURST_RECEIVE_STOP);

                    Log_print1(Diags_USER2,
                            "I2C:(%p) ISR I2CCC26XX_READ_MODE: -> I2CCC26XX_IDLE_MODE; "
                            "Sending STOP bit",
                            hwAttrs->baseAddr);

                }

                break;

            default:
                object->mode = I2CCC26XX_ERROR;
                break;
        }

    }
    else {
        /* Some sort of error happened! */
        object->mode = I2CCC26XX_ERROR;

        if (errStatus & I2C_MASTER_ERR_ARB_LOST) {
            I2CCC26XX_completeTransfer((I2C_Handle) arg);
        }
        else {
        /* Try to send a STOP bit to end all I2C communications immediately */
        /*
         * I2C_MASTER_CMD_BURST_SEND_ERROR_STOP -and-
         * I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP
         * have the same values
         */
            I2CMasterControl(hwAttrs->baseAddr,
                    I2C_MASTER_CMD_BURST_SEND_ERROR_STOP);

            I2CCC26XX_completeTransfer((I2C_Handle) arg);
        }

        Log_print2(Diags_USER1,
                "I2C:(%p) ISR I2C Bus fault (Status Reg: 0x%x)",
                hwAttrs->baseAddr,
                errStatus);
    }

    return;
}
Example #29
0
//*****************************************************************************
//
// Reads from the I2C-attached EEPROM device.
//
// \param pucData points to storage for the data read from the EEPROM.
// \param ulOffset is the EEPROM address of the first byte to read.
// \param ulCount is the number of bytes of data to read from the EEPROM.
//
// This function reads one or more bytes of data from a given address in the
// ID EEPROM found on several of the lm3s9b96 development kit daughter boards.
// The return code indicates whether the read was successful.
//
// \return Returns \b true on success of \b false on failure.
//
//*****************************************************************************
static tBoolean
EEPROMReadPolled(unsigned char *pucData, unsigned long ulOffset,
                 unsigned long ulCount)
{
    unsigned long ulToRead;

    //
    // Clear any previously signalled interrupts.
    //
    I2CMasterIntClear(ID_I2C_MASTER_BASE);

    //
    // Start with a dummy write to get the address set in the EEPROM.
    //
    I2CMasterSlaveAddrSet(ID_I2C_MASTER_BASE, ID_I2C_ADDR, false);

    //
    // Place the address to be written in the data register.
    //
    I2CMasterDataPut(ID_I2C_MASTER_BASE, ulOffset);

    //
    // Perform a single send, writing the address as the only byte.
    //
    I2CMasterControl(ID_I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);

    //
    // Wait until the current byte has been transferred.
    //
    while(I2CMasterIntStatus(ID_I2C_MASTER_BASE, false) == 0)
    {
    }

    if(I2CMasterErr(ID_I2C_MASTER_BASE) != I2C_MASTER_ERR_NONE)
    {
        I2CMasterIntClear(ID_I2C_MASTER_BASE);
        return(false);
    }

    //
    // Clear any interrupts set.
    //
    I2CMasterIntClear(ID_I2C_MASTER_BASE);

    //
    // Put the I2C master into receive mode.
    //
    I2CMasterSlaveAddrSet(ID_I2C_MASTER_BASE, ID_I2C_ADDR, true);

    //
    // Start the receive.
    //
    I2CMasterControl(ID_I2C_MASTER_BASE,
                     ((ulCount > 1) ? I2C_MASTER_CMD_BURST_RECEIVE_START :
                     I2C_MASTER_CMD_SINGLE_RECEIVE));

    //
    // Receive the required number of bytes.
    //
    ulToRead = ulCount;

    while(ulToRead)
    {
        //
        // Wait until the current byte has been read.
        //
        while(I2CMasterIntStatus(ID_I2C_MASTER_BASE, false) == 0)
        {
        }

        //
        // Read the received character.
        //
        *pucData++ = I2CMasterDataGet(ID_I2C_MASTER_BASE);
        ulToRead--;

        //
        // Clear pending interrupt notifications.
        //
        I2CMasterIntClear(ID_I2C_MASTER_BASE);

        //
        // Set up for the next byte if any more remain.
        //
        if(ulToRead)
        {
            I2CMasterControl(ID_I2C_MASTER_BASE,
                             ((ulToRead == 1) ?
                              I2C_MASTER_CMD_BURST_RECEIVE_FINISH :
                              I2C_MASTER_CMD_BURST_RECEIVE_CONT));
        }
    }

    //
    // Clear pending interrupt notification.
    //
    I2CMasterIntClear(ID_I2C_MASTER_BASE);

    //
    // Tell the caller we read the required data.
    //
    return(true);
}
Example #30
0
int main(void)
{
    // Clock (80MHz)
    SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
    
    
    // GPIO
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1);
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0);

    
    // UART
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE | UART_CONFIG_WLEN_8));
    
    UARTEnable(UART0_BASE);
    

    // I2C
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
    GPIOPinConfigure(GPIO_PB2_I2C0SCL);
    GPIOPinConfigure(GPIO_PB3_I2C0SDA);
    GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
    GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
    I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), false);
    
    I2CMasterEnable(I2C0_BASE);
    

    
    // Scan for addresses
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1);
    
    printf("Scan started\r\n");

    for(i=0; i<255; i++)
    {
        I2CMasterSlaveAddrSet(I2C0_BASE, i>>1, false);
        I2CMasterDataPut(I2C0_BASE, 0);
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);

        SysCtlDelay(SysCtlClockGet()/10000);

        if (I2CMasterErr(I2C0_BASE) ==  I2C_MASTER_ERR_NONE)
        {
            printf("x%02X\r\n", i);
        }
        else
        {
            //printf(" N\r\n");
        }
    }

    printf("\r\nScan complete\r\n\r\n");

    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0);



    while(1);
}