I'm have some issues understanding what is going on in the below code. When I run the first code block i get a valid return value in rdac from an I2C device. The returned value checks out with the parts data sheet. Here is the code that works.
//***************************************************************************** // // interrupts.c - Interrupt preemption and tail-chaining example. // // Copyright (c) 2012-2013 Texas Instruments Incorporated. All rights reserved. // Software License Agreement // // Texas Instruments (TI) is supplying this software for use solely and // exclusively on TI's microcontroller products. The software is owned by // TI and/or its suppliers, and is protected under applicable copyright // laws. You may not combine this software with "viral" open-source // software in order to form a larger program. // // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL // DAMAGES, FOR ANY REASON WHATSOEVER. // // This is part of revision 1.1 of the EK-TM4C123GXL Firmware Package. // //***************************************************************************** #include <stdint.h> #include <stdbool.h> #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_nvic.h" #include "inc/hw_types.h" #include "driverlib/debug.h" #include "driverlib/fpu.h" #include "driverlib/gpio.h" #include "driverlib/interrupt.h" #include "driverlib/pin_map.h" #include "driverlib/rom.h" #include "driverlib/sysctl.h" #include "driverlib/systick.h" #include "driverlib/uart.h" #include "utils/uartstdio.h" #include "driverlib/i2c.h" uint32_t rdac; //***************************************************************************** // // The error routine that is called if the driver library encounters an error. // //***************************************************************************** #ifdef DEBUG void __error__(char *pcFilename, uint32_t ui32Line) { } #endif //***************************************************************************** // // I2C ISR // //***************************************************************************** void I2C_ISR() { I2CMasterIntClear(I2C1_BASE); } //***************************************************************************** // // Get RDAC Value // //***************************************************************************** int GetRDAC() { uint32_t value; // // Send I2C read instruction // I2CMasterDataPut(I2C1_BASE, 0x08); // MSB read command I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START); while(I2CMasterBusy(I2C1_BASE)); I2CMasterDataPut(I2C1_BASE, 0x00); // LSB read command I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH); while(I2CMasterBusy(I2C1_BASE)); // // Read RDAC reg // I2CMasterSlaveAddrSet(I2C1_BASE, 0x2F, true); I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START); while(I2CMasterBusy(I2C1_BASE)); value = (I2CMasterDataGet(I2C1_BASE)) << 8; I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH); while(I2CMasterBusy(I2C1_BASE)); value += I2CMasterDataGet(I2C1_BASE); SysCtlDelay(100); return value; } int main(void) { rdac = 0; // // Enable lazy stacking for interrupt handlers. This allows floating-point // instructions to be used within interrupt handlers, but at the expense of // extra stack usage. // FPULazyStackingEnable(); // // Set the clocking to run directly from the crystal. // SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); //SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN); // // Enable GPIOA and set pins to I2C1 // SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7); GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6); GPIOPinConfigure(GPIO_PA6_I2C1SCL); GPIOPinConfigure(GPIO_PA7_I2C1SDA); // // Setup I2C1 // I2CMasterInitExpClk(I2C1_BASE, SysCtlClockGet(), false); I2CMasterSlaveAddrSet(I2C1_BASE, 0x2F, false); // // Enable interrupts to the processor. // ROM_IntMasterEnable(); // // Loop forever. // while(1) { rdac = GetRDAC(); SysCtlDelay(1); for(;;){} } }
When I comment out the
SysCtlDelay(1);
instruction and immediately hit the for loop after the GetRDAC() function CCS shows 0 for rdac in the watch window. When I have the delay in i get the valid value as expected. The rdac variable is a global variable. Why can't the value be seen in watch without the delay? This may be a dumb question, but I would like some guidance regarding this if possible so if I am making a dumb mistake I can correct it.
Also, this is a working I2C conafiguration for the Tiva C launchpad (TM4C123GH6PMI) so feel free to use it. It configures I2C1.
Thanks,
Rob