//***************************************************************************** // //! Controls the state of the I2C Master module. //! //! \param ulBase is the base address of the I2C Master module. //! \param ulCmd command to be issued to the I2C Master module. //! //! This function is used to control the state of the Master module send and //! receive operations. The \e ucCmd parameter can be one of the following //! values: //! //! - \b I2C_MASTER_CMD_SINGLE_SEND //! - \b I2C_MASTER_CMD_SINGLE_RECEIVE //! - \b I2C_MASTER_CMD_BURST_SEND_START //! - \b I2C_MASTER_CMD_BURST_SEND_CONT //! - \b I2C_MASTER_CMD_BURST_SEND_FINISH //! - \b I2C_MASTER_CMD_BURST_SEND_ERROR_STOP //! - \b I2C_MASTER_CMD_BURST_RECEIVE_START //! - \b I2C_MASTER_CMD_BURST_RECEIVE_CONT //! - \b I2C_MASTER_CMD_BURST_RECEIVE_FINISH //! - \b I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP //! - \b I2C_MASTER_CMD_QUICK_COMMAND //! - \b I2C_MASTER_CMD_HS_MASTER_CODE_SEND //! //! \return None. // //***************************************************************************** void I2CMasterControl(unsigned long ulBase, unsigned long ulCmd) { // // Check the arguments. // ASSERT(I2CMasterBaseValid(ulBase)); ASSERT((ulCmd == I2C_MASTER_CMD_SINGLE_SEND) || (ulCmd == I2C_MASTER_CMD_SINGLE_RECEIVE) || (ulCmd == I2C_MASTER_CMD_BURST_SEND_START) || (ulCmd == I2C_MASTER_CMD_BURST_SEND_CONT) || (ulCmd == I2C_MASTER_CMD_BURST_SEND_FINISH) || (ulCmd == I2C_MASTER_CMD_BURST_SEND_ERROR_STOP) || (ulCmd == I2C_MASTER_CMD_BURST_RECEIVE_START) || (ulCmd == I2C_MASTER_CMD_BURST_RECEIVE_CONT) || (ulCmd == I2C_MASTER_CMD_BURST_RECEIVE_FINISH) || (ulCmd == I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP) || (ulCmd == I2C_MASTER_CMD_QUICK_COMMAND) || (ulCmd == I2C_MASTER_CMD_HS_MASTER_CODE_SEND)); // // Send the command. // HWREG(ulBase + I2C_O_MCS) = ulCmd; }
//***************************************************************************** // //! Registers an interrupt handler for the I2C module. //! //! \param ulBase is the base address of the I2C Master module. //! \param pfnHandler is a pointer to the function to be called when the //! I2C interrupt occurs. //! //! This function sets the handler to be called when an I2C interrupt occurs. //! This function enables the global interrupt in the interrupt controller; //! specific I2C interrupts must be enabled via I2CMasterIntEnable() and //! I2CSlaveIntEnable(). If necessary, it is the interrupt handler's //! responsibility to clear the interrupt source via I2CMasterIntClear() and //! I2CSlaveIntClear(). //! //! \sa IntRegister() for important information about registering interrupt //! handlers. //! //! \return None. // //***************************************************************************** void I2CIntRegister(unsigned long ulBase, void (*pfnHandler)(void)) { unsigned long ulInt; // // Check the arguments. // ASSERT(I2CMasterBaseValid(ulBase)); // // Determine the interrupt number based on the I2C port. // ulInt = I2CIntNumberGet(ulBase); // // Register the interrupt handler, returning an error if an error occurs. // IntRegister(ulInt, pfnHandler); // // Enable the I2C interrupt. // IntEnable(ulInt); }
//***************************************************************************** // //! Unregisters an interrupt handler for the I2C module. //! //! \param ulBase is the base address of the I2C Master module. //! //! This function clears the handler to be called when an I2C interrupt //! occurs. This function also masks off the interrupt in the interrupt r //! controlle so that the interrupt handler no longer is called. //! //! \sa IntRegister() for important information about registering interrupt //! handlers. //! //! \return None. // //***************************************************************************** void I2CIntUnregister(unsigned long ulBase) { unsigned long ulInt; // // Check the arguments. // ASSERT(I2CMasterBaseValid(ulBase)); // // Determine the interrupt number based on the I2C port. // ulInt = I2CIntNumberGet(ulBase); // // Disable the interrupt. // IntDisable(ulInt); // // Unregister the interrupt handler. // IntUnregister(ulInt); }
//***************************************************************************** // //! Sets the Master clock timeout value. //! //! \param ulBase is the base address of the I2C Master module. //! \param ulValue is the number of I2C clocks before the timeout is asserted. //! //! This function enables and configures the clock low timeout feature in the //! I2C peripheral. This feature is implemented as a 12-bit counter, with the //! upper 8-bits being programmable. For example, to program a timeout of 20ms //! with a 100kHz SCL frequency, \e ulValue would be 0x7d. //! //! \note Not all Stellaris devices support this function. Please consult the //! device data sheet to determine if this feature is supported. //! //! \return None. // //***************************************************************************** void I2CMasterTimeoutSet(unsigned long ulBase, unsigned long ulValue) { // // Check the arguments. // ASSERT(I2CMasterBaseValid(ulBase)); // // Write the timeout value. // HWREG(ulBase + I2C_O_MCLKOCNT) = ulValue; }
//***************************************************************************** // //! Receives a byte that has been sent to the I2C Master. //! //! \param ulBase is the base address of the I2C Master module. //! //! This function reads a byte of data from the I2C Master Data Register. //! //! \return Returns the byte received from by the I2C Master, cast as an //! unsigned long. // //***************************************************************************** unsigned long I2CMasterDataGet(unsigned long ulBase) { // // Check the arguments. // ASSERT(I2CMasterBaseValid(ulBase)); // // Read a byte. // return(HWREG(ulBase + I2C_O_MDR)); }
//***************************************************************************** // //! Disables the I2C master block. //! //! \param ulBase is the base address of the I2C Master module. //! //! This function disables operation of the I2C master block. //! //! \return None. // //***************************************************************************** void I2CMasterDisable(unsigned long ulBase) { // // Check the arguments. // ASSERT(I2CMasterBaseValid(ulBase)); // // Disable the master block. // HWREG(ulBase + I2C_O_MCR) &= ~(I2C_MCR_MFE); }
//***************************************************************************** // //! Reads the state of the SDA and SCL pins. //! //! \param ulBase is the base address of the I2C Master module. //! //! This function returns the state of the I2C bus by providing the real time //! values of the SDA and SCL pins. //! //! \note Not all Stellaris devices support this function. Please consult the //! device data sheet to determine if this feature is supported. //! //! \return Returns the state of the bus with SDA in bit position 1 and SCL in //! bit position 0. // //***************************************************************************** unsigned long I2CMasterLineStateGet(unsigned long ulBase) { // // Check the arguments. // ASSERT(I2CMasterBaseValid(ulBase)); // // Return the line state. // return(HWREG(ulBase + I2C_O_MBMON)); }
//***************************************************************************** // //! Clears I2C Master interrupt sources. //! //! \param ulBase is the base address of the I2C Master module. //! \param ulIntFlags is a bit mask of the interrupt sources to be cleared. //! //! The specified I2C Master interrupt sources are cleared, so that they no //! longer assert. This function must be called in the interrupt handler to //! keep the interrupt from being triggered again immediately upon exit. //! //! The \e ulIntFlags parameter has the same definition as the \e ulIntFlags //! parameter to I2CMasterIntEnableEx(). //! //! \note Because there is a write buffer in the Cortex-M processor, it may //! take several clock cycles before the interrupt source is actually cleared. //! Therefore, it is recommended that the interrupt source be cleared early in //! the interrupt handler (as opposed to the very last action) to avoid //! returning from the interrupt handler before the interrupt source is //! actually cleared. Failure to do so may result in the interrupt handler //! being immediately reentered (because the interrupt controller still sees //! the interrupt source asserted). //! //! \return None. // //***************************************************************************** void I2CMasterIntClearEx(unsigned long ulBase, unsigned long ulIntFlags) { // // Check the arguments. // ASSERT(I2CMasterBaseValid(ulBase)); // // Clear the I2C master interrupt source. // HWREG(ulBase + I2C_O_MICR) = ulIntFlags; }
//***************************************************************************** // //! Enables the I2C Master interrupt. //! //! \param ulBase is the base address of the I2C Master module. //! //! This function enables the I2C Master interrupt source. //! //! \return None. // //***************************************************************************** void I2CMasterIntEnable(unsigned long ulBase) { // // Check the arguments. // ASSERT(I2CMasterBaseValid(ulBase)); // // Enable the master interrupt. // HWREG(ulBase + I2C_O_MIMR) = 1; }
//***************************************************************************** // //! Disables individual I2C Master interrupt sources. //! //! \param ulBase is the base address of the I2C Master module. //! \param ulIntFlags is the bit mask of the interrupt sources to be disabled. //! //! This function disables the indicated I2C Master interrupt sources. Only //! the sources that are enabled can be reflected to the processor interrupt; //! disabled sources have no effect on the processor. //! //! The \e ulIntFlags parameter has the same definition as the \e ulIntFlags //! parameter to I2CMasterIntEnableEx(). //! //! \return None. // //***************************************************************************** void I2CMasterIntDisableEx(unsigned long ulBase, unsigned long ulIntFlags) { // // Check the arguments. // ASSERT(I2CMasterBaseValid(ulBase)); // // Disable the master interrupt. // HWREG(ulBase + I2C_O_MIMR) &= ~ulIntFlags; }
//***************************************************************************** // //! Transmits a byte from the I2C Master. //! //! \param ulBase is the base address of the I2C Master module. //! \param ucData data to be transmitted from the I2C Master. //! //! This function places the supplied data into I2C Master Data Register. //! //! \return None. // //***************************************************************************** void I2CMasterDataPut(unsigned long ulBase, unsigned char ucData) { // // Check the arguments. // ASSERT(I2CMasterBaseValid(ulBase)); // // Write the byte. // HWREG(ulBase + I2C_O_MDR) = ucData; }
//***************************************************************************** // //! Initializes the I2C Master block. //! //! \param ulBase is the base address of the I2C Master module. //! \param ulI2CClk is the rate of the clock supplied to the I2C module. //! \param bFast set up for fast data transfers. //! //! This function initializes operation of the I2C Master block by configuring //! the bus speed for the master and enabling the I2C Master block. //! //! If the parameter \e bFast is \b true, then the master block is set up to //! transfer data at 400 Kbps; otherwise, it is set up to transfer data at //! 100 Kbps. If Fast Mode Plus (1 Mbps) is desired, software should manually //! write the I2CMTPR after calling this function. For High Speed (3.4 Mbps) //! mode, a specific command is used to switch to the faster clocks after the //! initial communication with the slave is done at either 100 Kbps or //! 400 Kbps. //! //! The peripheral clock is the same as the processor clock. This value is //! returned by SysCtlClockGet(), or it can be explicitly hard coded if it is //! constant and known (to save the code/execution overhead of a call to //! SysCtlClockGet()). //! //! This function replaces the original I2CMasterInit() API and performs the //! same actions. A macro is provided in <tt>i2c.h</tt> to map the original //! API to this API. //! //! \return None. // //***************************************************************************** void I2CMasterInitExpClk(unsigned long ulBase, unsigned long ulI2CClk, tBoolean bFast) { unsigned long ulSCLFreq; unsigned long ulTPR; // // Check the arguments. // ASSERT(I2CMasterBaseValid(ulBase)); // // Must enable the device before doing anything else. // I2CMasterEnable(ulBase); // // Get the desired SCL speed. // if(bFast == true) { ulSCLFreq = 400000; } else { ulSCLFreq = 100000; } // // Compute the clock divider that achieves the fastest speed less than or // equal to the desired speed. The numerator is biased to favor a larger // clock divider so that the resulting clock is always less than or equal // to the desired clock, never greater. // ulTPR = ((ulI2CClk + (2 * 10 * ulSCLFreq) - 1) / (2 * 10 * ulSCLFreq)) - 1; HWREG(ulBase + I2C_O_MTPR) = ulTPR; // // Check to see if this I2C peripheral is High-Speed enabled. If yes, also // choose the fastest speed that is less than or equal to 3.4 Mbps. // if(HWREG(ulBase + I2C_O_PP) & I2C_PP_HS) { ulTPR = ((ulI2CClk + (2 * 3 * 3400000) - 1) / (2 * 3 * 3400000)) - 1; HWREG(ulBase + I2C_O_MTPR) = I2C_MTPR_HS | ulTPR; } }
//***************************************************************************** // //! Sets the address that the I2C Master places on the bus. //! //! \param ulBase is the base address of the I2C Master module. //! \param ucSlaveAddr 7-bit slave address //! \param bReceive flag indicating the type of communication with the slave //! //! This function configures the address that the I2C Master places on the //! bus when initiating a transaction. When the \e bReceive parameter is set //! to \b true, the address indicates that the I2C Master is initiating a //! read from the slave; otherwise the address indicates that the I2C //! Master is initiating a write to the slave. //! //! \return None. // //***************************************************************************** void I2CMasterSlaveAddrSet(unsigned long ulBase, unsigned char ucSlaveAddr, tBoolean bReceive) { // // Check the arguments. // ASSERT(I2CMasterBaseValid(ulBase)); ASSERT(!(ucSlaveAddr & 0x80)); // // Set the address of the slave with which the master will communicate. // HWREG(ulBase + I2C_O_MSA) = (ucSlaveAddr << 1) | bReceive; }
//***************************************************************************** // //! Indicates whether or not the I2C bus is busy. //! //! \param ulBase is the base address of the I2C Master module. //! //! This function returns an indication of whether or not the I2C bus is busy. //! This function can be used in a multi-master environment to determine if //! another master is currently using the bus. //! //! \return Returns \b true if the I2C bus is busy; otherwise, returns //! \b false. // //***************************************************************************** tBoolean I2CMasterBusBusy(unsigned long ulBase) { // // Check the arguments. // ASSERT(I2CMasterBaseValid(ulBase)); // // Return the bus busy status. // if(HWREG(ulBase + I2C_O_MCS) & I2C_MCS_BUSBSY) { return(true); } else { return(false); } }
//***************************************************************************** // //! Clears I2C Master interrupt sources. //! //! \param ulBase is the base address of the I2C Master module. //! //! The I2C Master interrupt source is cleared, so that it no longer asserts. //! This function must be called in the interrupt handler to keep the interrupt //! from being triggered again immediately upon exit. //! //! \note Because there is a write buffer in the Cortex-M processor, it may //! take several clock cycles before the interrupt source is actually cleared. //! Therefore, it is recommended that the interrupt source be cleared early in //! the interrupt handler (as opposed to the very last action) to avoid //! returning from the interrupt handler before the interrupt source is //! actually cleared. Failure to do so may result in the interrupt handler //! being immediately reentered (because the interrupt controller still sees //! the interrupt source asserted). //! //! \return None. // //***************************************************************************** void I2CMasterIntClear(unsigned long ulBase) { // // Check the arguments. // ASSERT(I2CMasterBaseValid(ulBase)); // // Clear the I2C master interrupt source. // HWREG(ulBase + I2C_O_MICR) = I2C_MICR_IC; // // Workaround for I2C master interrupt clear errata for rev B Stellaris // devices. For later devices, this write is ignored and therefore // harmless (other than the slight performance hit). // HWREG(ulBase + I2C_O_MMIS) = I2C_MICR_IC; }
//***************************************************************************** // //! Gets the current I2C Master interrupt status. //! //! \param ulBase is the base address of the I2C Master module. //! \param bMasked is false if the raw interrupt status is requested and //! true if the masked interrupt status is requested. //! //! This function returns the interrupt status for the I2C Master module. //! Either the raw interrupt status or the status of interrupts that are //! allowed to reflect to the processor can be returned. //! //! \return Returns the current interrupt status, enumerated as a bit field of //! values described in I2CMasterIntEnableEx(). // //***************************************************************************** unsigned long I2CMasterIntStatusEx(unsigned long ulBase, tBoolean bMasked) { // // Check the arguments. // ASSERT(I2CMasterBaseValid(ulBase)); // // Return either the interrupt status or the raw interrupt status as // requested. // if(bMasked) { return(HWREG(ulBase + I2C_O_MMIS)); } else { return(HWREG(ulBase + I2C_O_MRIS)); } }
//***************************************************************************** // //! Gets the error status of the I2C Master module. //! //! \param ulBase is the base address of the I2C Master module. //! //! This function is used to obtain the error status of the Master module send //! and receive operations. //! //! \return Returns the error status, as one of \b I2C_MASTER_ERR_NONE, //! \b I2C_MASTER_ERR_ADDR_ACK, \b I2C_MASTER_ERR_DATA_ACK, or //! \b I2C_MASTER_ERR_ARB_LOST. // //***************************************************************************** unsigned long I2CMasterErr(unsigned long ulBase) { unsigned long ulErr; // // Check the arguments. // ASSERT(I2CMasterBaseValid(ulBase)); // // Get the raw error state // ulErr = HWREG(ulBase + I2C_O_MCS); // // If the I2C master is busy, then all the other bit are invalid, and // don't have an error to report. // if(ulErr & I2C_MCS_BUSY) { return(I2C_MASTER_ERR_NONE); } // // Check for errors. // if(ulErr & (I2C_MCS_ERROR | I2C_MCS_ARBLST)) { return(ulErr & (I2C_MCS_ARBLST | I2C_MCS_DATACK | I2C_MCS_ADRACK)); } else { return(I2C_MASTER_ERR_NONE); } }
//***************************************************************************** // //! 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; }
//***************************************************************************** // //! 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; }
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(ROM_I2CMasterBusy(ulI2CBase)) { }; // // Tell the master module what address it will place on the bus when // writing to the slave. // ROM_I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, 0); // // Place the command to be sent in the data register. // ROM_I2CMasterDataPut(ulI2CBase, ucReg); // // Initiate send of data from the master. // ROM_I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_START); // // Wait until master module is done transferring. // while(ROM_I2CMasterBusy(ulI2CBase)) { }; // // Check for errors. // if(ROM_I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE) { return 0; } // // Place the value to be sent in the data register. // ROM_I2CMasterDataPut(ulI2CBase, ucValue); // // Initiate send of data from the master. // ROM_I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_CONT); // // Wait until master module is done transferring. // while(ROM_I2CMasterBusy(ulI2CBase)) { }; // // Check for errors. // if(ROM_I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE) { return 0; } // // Initiate send of data from the master. // ROM_I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_FINISH); // // Wait until master module is done transferring. // while(ROM_I2CMasterBusy(ulI2CBase)) { }; // // Check for errors. // if(ROM_I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE) { return 0; } // // Return 1 if there is no error. // return 1; }
//***************************************************************************** // //! Reads one/multiple bytes of data from an I2C slave device. //! //! \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 reading from. //! \param cReadData is a pointer to the array to store the data. //! \param uiSize is the number of bytes to read from the slave. //! //! This function reads one/multiple bytes of data from 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 I2CReadData(unsigned long ulI2CBase, unsigned char ucSlaveAdress, unsigned char ucReg, char* cReadData, 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(ROM_I2CMasterBusy(ulI2CBase)) { }; // // Tell the master module what address it will place on the bus when // writing to the slave. // ROM_I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, 0); // // Place the command to be sent in the data register. // ROM_I2CMasterDataPut(ulI2CBase, ucReg); // // Initiate send of data from the master. // ROM_I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_SINGLE_SEND); // // Wait until master module is done transferring. // while(ROM_I2CMasterBusy(ulI2CBase)) { }; // // Check for errors. // if(ROM_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. // ROM_I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, true); // // Start with BURST with more than one byte to write // MasterOptionCommand = I2C_MASTER_CMD_BURST_RECEIVE_START; for(uibytecount = 0; uibytecount < uiSize; uibytecount++) { // // The second and intermittent byte has to be read with CONTINUE control word // if(uibytecount == 1) MasterOptionCommand = I2C_MASTER_CMD_BURST_RECEIVE_CONT; // // The last byte has to be send with FINISH control word // if(uibytecount == uiSize - 1) MasterOptionCommand = I2C_MASTER_CMD_BURST_RECEIVE_FINISH; // // Re-configure to SINGLE if there is only one byte to read // if(uiSize == 1) MasterOptionCommand = I2C_MASTER_CMD_SINGLE_RECEIVE; // // Initiate read of data from the slave. // ROM_I2CMasterControl(ulI2CBase, MasterOptionCommand); // // Wait until master module is done reading. // while(ROM_I2CMasterBusy(ulI2CBase)) { }; // // Check for errors. // if(ROM_I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE) { return 0; } // // Move byte from register // cReadData[uibytecount] = I2CMasterDataGet(ulI2CBase); } // send number of received bytes return uibytecount; }
//***************************************************************************** // //! Initializes and enables the specified I2C block. //! //! \param ulI2CBase is the I2C peripheral to be used. //! \param ulI2CSpeed defines the normal (100kbps) or fast (400kbps) I2C mode. //! //! This function enables the specified I2C block and sets it up to run at //! the either 100kbps or 400kbps. If the \e ulI2CSpeed is false, the I2C will //! run at 100kbps and if true, then the I2C will run at 400kbps. The //! \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 None. // //***************************************************************************** void I2CSetup(unsigned long ulI2CBase, unsigned long ulI2CSpeed) { // // Check the arguments. // ASSERT(I2CMasterBaseValid(ulI2CBase)); ASSERT((ulI2CSpeed == true) || (ulI2CSpeed == false)); switch (ulI2CBase) { // I2C_PERIPH_0 case I2C0_MASTER_BASE: // // I2C0 is used with PortB[3:2]. The actual port and // pins used may be different on your part, consult the data sheet for // more information. GPIO port B needs to be enabled so these pins can // be used. // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); // // Select the I2C function for these pins. This function will also // configure the GPIO pins for I2C operation, setting them to // open-drain operation with weak pull-ups. Consult the data sheet // to see which functions are allocated per pin. // GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2); // special I2CSCL treatment for M4F devices GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3); // // Configure the pin muxing for I2C0 functions on port B2 and B3. // This step is not necessary if your part does not support pin muxing. // GPIOPinConfigure(GPIO_PB2_I2C0SCL); GPIOPinConfigure(GPIO_PB3_I2C0SDA); // // The I2C0 peripheral must be enabled before use. // SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0); // // Enable and initialize the I2C0 master module. // I2CMasterInitExpClk(I2C0_MASTER_BASE, SysCtlClockGet(), ulI2CSpeed); break; // I2C_PERIPH_1 case I2C1_MASTER_BASE: // // I2C1 is used with PortA[7:6]. The actual port and // pins used may be different on your part, consult the data sheet for // more information. GPIO port A needs to be enabled so these pins can // be used. // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // // Select the I2C function for these pins. This function will also // configure the GPIO pins for I2C operation, setting them to // open-drain operation with weak pull-ups. Consult the data sheet // to see which functions are allocated per pin. // GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6); // special I2CSCL treatment for M4F devices GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7); // // Configure the pin muxing for I2C1 functions on port A6 and A7. // This step is not necessary if your part does not support pin muxing. // GPIOPinConfigure(GPIO_PA6_I2C1SCL); GPIOPinConfigure(GPIO_PA7_I2C1SDA); // // The I2C1 peripheral must be enabled before use. // SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1); // // Enable and initialize the I2C1 master module. // I2CMasterInitExpClk(I2C1_MASTER_BASE, SysCtlClockGet(), ulI2CSpeed); break; // I2C_PERIPH_2 case I2C2_MASTER_BASE: // // I2C2 is used with PortE[5:4]. The actual port and // pins used may be different on your part, consult the data sheet for // more information. GPIO port E needs to be enabled so these pins can // be used. // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); // // Select the I2C function for these pins. This function will also // configure the GPIO pins for I2C operation, setting them to // open-drain operation with weak pull-ups. Consult the data sheet // to see which functions are allocated per pin. // GPIOPinTypeI2CSCL(GPIO_PORTE_BASE, GPIO_PIN_4); // special I2CSCL treatment for M4F devices GPIOPinTypeI2C(GPIO_PORTE_BASE, GPIO_PIN_5); // // Configure the pin muxing for I2C2 functions on port E4 and E5. // This step is not necessary if your part does not support pin muxing. // GPIOPinConfigure(GPIO_PE4_I2C2SCL); GPIOPinConfigure(GPIO_PE5_I2C2SDA); // // The I2C2 peripheral must be enabled before use. // SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C2); // // Enable and initialize the I2C2 master module. // I2CMasterInitExpClk(I2C2_MASTER_BASE, SysCtlClockGet(), ulI2CSpeed); break; // I2C_PERIPH_3 case I2C3_MASTER_BASE: // // I2C3 is used with PortD[1:0]. The actual port and // pins used may be different on your part, consult the data sheet for // more information. GPIO port D needs to be enabled so these pins can // be used. // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); // // Select the I2C function for these pins. This function will also // configure the GPIO pins for I2C operation, setting them to // open-drain operation with weak pull-ups. Consult the data sheet // to see which functions are allocated per pin. // GPIOPinTypeI2CSCL(GPIO_PORTD_BASE, GPIO_PIN_0); // special I2CSCL treatment for M4F devices GPIOPinTypeI2C(GPIO_PORTD_BASE, GPIO_PIN_1); // // Configure the pin muxing for I2C2 functions on port D0 and D1. // This step is not necessary if your part does not support pin muxing. // GPIOPinConfigure(GPIO_PD0_I2C3SCL); GPIOPinConfigure(GPIO_PD1_I2C3SDA); // // The I2C3 peripheral must be enabled before use. // SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C3); // // Enable and initialize the I2C3 master module. // I2CMasterInitExpClk(I2C3_MASTER_BASE, SysCtlClockGet(), ulI2CSpeed); break; } }