Hi everyone,
I'm currently trying to interface with the SHT21 on the SensorHub Boosterpack without using the I2CM libraries, and I'm running into some trouble with the I2C communications. I've included my code below, and at https://gist.github.com/madvoid/9481264 for easy viewing.
// Defines -------------------------------------------------------------------------------------------
#define LED_RED GPIO_PIN_1
#define LED_BLUE GPIO_PIN_2
#define LED_GREEN GPIO_PIN_3
#define SHT21_I2C_ADDRESS 0x40
#define SHT21_TEMP_NOBLOCK 0xE3
// Variables -----------------------------------------------------------------------------------------
static uint32_t g_I2C3Data; // Data gathered from I2C3 master
static bool g_I2C3DataReceived = false; // Flag indicating whether data has been received
// Functions -----------------------------------------------------------------------------------------
void ConfigureUART(void){
// Enable the peripherals used by UART
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
// Set GPIO A0 and A1 as UART pins.
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
// Configure UART clock using UART utils
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
UARTStdioConfig(0, 115200, 16000000);
}
void ConfigureI2C3(void){
// Enable peripherals used by I2C
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C3);
// Set GPIO D0 and D1 as SCL and SDA
ROM_GPIOPinConfigure(GPIO_PD0_I2C3SCL);
ROM_GPIOPinConfigure(GPIO_PD1_I2C3SDA);
// Setup SCL and SDA
ROM_GPIOPinTypeI2CSCL(GPIO_PORTD_BASE, GPIO_PIN_0);
ROM_GPIOPinTypeI2C(GPIO_PORTD_BASE, GPIO_PIN_1);
// Initialize as master - Chane 'false' to 'true' if fast mode is desired
ROM_I2CMasterInitExpClk(I2C3_BASE, ROM_SysCtlClockGet(), false);
// Enable I2C Interrupts
ROM_IntEnable(INT_I2C3);
ROM_I2CMasterIntEnableEx(I2C3_BASE, I2C_MASTER_INT_DATA);
// Debug
UARTprintf("I2C3 Setup\n");
}
void I2C3MasterIntHandler(void){
// Clear interrupt
ROM_I2CMasterIntClear(I2C3_BASE);
// Control master?
ROM_I2CMasterControl(I2C3_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
// Gather data
g_I2C3Data = ROM_I2CMasterDataGet(I2C3_BASE);
// Set flag
g_I2C3DataReceived = true;
// Print confirmation
UARTprintf("Interrupt Received\n");
}
// Main ----------------------------------------------------------------------------------------------
int main(void){
// Enable lazy stacking
ROM_FPULazyStackingEnable();
// Set the system clock to run at 40Mhz off PLL with external crystal as reference.
ROM_SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
// Initialize the UART and write status.
ConfigureUART();
UARTprintf("SHT21 Example\n");
// Enable LEDs
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, LED_RED|LED_BLUE|LED_GREEN);
// Enable I2C3
ConfigureI2C3();
// Insert sleep mode stuff here in the future
// Enable Interrupts
ROM_IntMasterEnable();
// Main loop
while(1){
// Set address, put data in buffer, and send
ROM_I2CMasterSlaveAddrSet(I2C3_BASE, SHT21_I2C_ADDRESS, false);
ROM_I2CMasterDataPut(I2C3_BASE, SHT21_TEMP_NOBLOCK);
ROM_I2CMasterControl(I2C3_BASE, I2C_MASTER_CMD_SINGLE_SEND);
// Wait until data is received
while(!g_I2C3DataReceived){
}
// Print raw result
UARTprintf("Raw Result: %i\n",g_I2C3Data);
g_I2C3DataReceived = false;
// Blink LED
ROM_GPIOPinWrite(GPIO_PORTF_BASE, LED_RED|LED_GREEN|LED_BLUE, LED_GREEN);
ROM_SysCtlDelay(ROM_SysCtlClockGet()/3/10); // Delay for 100ms (1/10s) :: ClockGet()/3 = 1second
ROM_GPIOPinWrite(GPIO_PORTF_BASE, LED_RED|LED_GREEN|LED_BLUE, 0);
ROM_SysCtlDelay(ROM_SysCtlClockGet()/3); // Delay for 1 second
}
}
When I run this code, the "Interrupt Received" print statement will repeatedly print, and the LED will never blink, which makes me think that the interrupt is not properly cleared or keeps getting called. When I move the data print statement to inside the interrupt handler, the data is printed as zero. Or, am I missing a disable command somewhere?
According to the SHT21 data sheet, the process for getting a raw temp measurement is address write, temp command write, and then after some time a read will be available, which is what I (think) I am doing.
I am using a Tiva Launchpad with arm-none-eabi-gcc, OS X 10.9.2, and I'm programming with the lm4flash programmer.
Any insight will be immensely helpful, and thanks in advance!