Skip to content

Instantly share code, notes, and snippets.

@mattwilliamson
Last active December 12, 2015 07:58
Show Gist options
  • Save mattwilliamson/89878d6b58261dc9a4c9 to your computer and use it in GitHub Desktop.
Save mattwilliamson/89878d6b58261dc9a4c9 to your computer and use it in GitHub Desktop.
Stellaris I2C Bus Scanner
//*****************************************************************************
//
//! 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.
//
//*****************************************************************************
#include "stdint.h"
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/pin_map.h"
#include "driverlib/i2c.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "utils/uartstdio.h"
#define MPU6050_ADDRESS 0x68
//#define MPU6050_ADDRESS 0x69
#define HMC5883_ADDRESS 0x1E
#define MS561101BA_ADDRESS 0x77
//#define MS561101BA_ADDRESS 0x76
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.
//
UARTprintf("ROM_I2CMasterBusy\n");
while(ROM_I2CMasterBusy(ulI2CBase)){};
UARTprintf("Probing...\n");
//
// 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.
//
ROM_I2CMasterSlaveAddrSet(ulI2CBase, ucProbeAdress, false);
ROM_SysCtlDelay(50000);
//
// Place the command to be sent in the data register.
//
ROM_I2CMasterDataPut(ulI2CBase, 0x00);
//
// Initiate send of data from the master.
//
ROM_I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_START);
//
// Make some delay
//
ROM_SysCtlDelay(500000);
//
// Read the I2C Master Control/Status (I2CMCS) Register to a local
// variable
//
ucerrorstate = ROM_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
//
ROM_SysCtlDelay(1500000);
}
}
//
// End transfer of data from the master.
//
ROM_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;
}
int main(void) {
// Enable FPU for interrupt routines
// ROM_FPULazyStackingEnable();
// ROM_FPUEnable();
// Set clock to 80MHz
SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
// Turn off LEDs
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2|GPIO_PIN_3, 0);
// Setup I2C on PB2 & PB3 (I2C0)
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
ROM_GPIOPinConfigure(GPIO_PB2_I2C0SCL);
ROM_GPIOPinConfigure(GPIO_PB3_I2C0SDA);
ROM_GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3);
ROM_I2CMasterInitExpClk(I2C0_MASTER_BASE, SysCtlClockGet(), false);
ROM_I2CMasterEnable(I2C0_MASTER_BASE);
// I2C doesn't seem to work without this with the MPU-6050
// Found it at http://e2e.ti.com/support/microcontrollers/stellaris_arm_cortex-m3_microcontroller/f/473/p/169023/639164.aspx#639164
ROM_GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_2, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);
ROM_GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_3, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_OD_WPU);
// Initialize the UART.
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
UARTStdioInit(0);
UARTprintf("I2C Bus-Scan starting...\n");
// Start probing sensors
ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_3);
I2CBusScan(I2C0_MASTER_BASE);
ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
UARTprintf("I2C Bus-Scan complete\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment