Other Parts Discussed in Thread: EK-TM4C123GXL
Hello,
I am trying to get values from Max 30100 sensor via I2C to EK-TM4C123GXL. I am having issues where it says that 'I do not have the permission to read the register' and points to the I2CSend function. The code also doesn't get to the point of I2C interrupt handler. The following is the code I have written,
#include <stdarg.h> #include <stdbool.h> #include <stdint.h> #include "inc/hw_i2c.h" #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_gpio.h" #include "driverlib/i2c.h" #include "driverlib/sysctl.h" #include "driverlib/gpio.h" #include "driverlib/pin_map.h" //*********************************************************** Global ************************************************************************// int i; uint8_t Fifo_WR_PTR; uint8_t Fifo_RD_PTR; uint16_t Num_Samples_Available; uint16_t Num_Samples_Read; uint8_t ir1; uint8_t ir2; uint8_t red1; uint8_t red2; uint16_t ir; uint16_t red; //************************************************** Initialize I2C module 0 ***************************************************************// void InitI2C0(void) { //enable I2C module 0 SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0); //reset module SysCtlPeripheralReset(SYSCTL_PERIPH_I2C0); //enable GPIO peripheral that contains I2C 0 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); // Configure the pin muxing for I2C0 functions on port B2 and B3. GPIOPinConfigure(GPIO_PB2_I2C0SCL); GPIOPinConfigure(GPIO_PB3_I2C0SDA); // Select the I2C function for these pins. GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2); GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3); // Enable and initialize the I2C0 master module. Use the system clock for // the I2C0 module. The last parameter sets the I2C data transfer rate. // If false the data rate is set to 100kbps and if true the data rate will // be set to 400kbps. I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), true); //clear I2C FIFOs HWREG(I2C0_BASE + I2C_O_FIFOCTL) = 80008000; } //************************************************** I2C Send function ***************************************************************// void I2CSend(uint16_t device_address, uint16_t device_register, uint8_t device_data) { //specify that we want to communicate to device address with an intended write to bus I2CMasterSlaveAddrSet(I2C0_BASE, device_address, false); //register to be read I2CMasterDataPut(I2C0_BASE, device_register); //send control byte and register address byte to slave device I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START); //wait for MCU to finish transaction while(I2CMasterBusy(I2C0_BASE)); I2CMasterSlaveAddrSet(I2C0_BASE, device_address, false); //specify data to be written to the above mentioned device_register I2CMasterDataPut(I2C0_BASE, device_data); //wait while checking for MCU to complete the transaction I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH); //wait for MCU & device to complete transaction while(I2CMasterBusy(I2C0_BASE)); } //************************************************** I2C Single Receive function ***************************************************************// uint32_t I2CReceiveS(uint32_t slave_addr, uint8_t reg) { //specify that we are writing (a register address) to the slave device I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, false); //specify register to be read I2CMasterDataPut(I2C0_BASE, reg); //send control byte and register address byte to slave device I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START); //wait for MCU to finish transaction while(I2CMasterBusy(I2C0_BASE)); //specify that we are going to read from slave device I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, true); //send control byte and read from the register we specified I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE); //wait for MCU to finish transaction while(I2CMasterBusy(I2C0_BASE)); //return data pulled from the specified register return I2CMasterDataGet(I2C0_BASE); } //************************************************** I2C Burst Receive function ***************************************************************// uint32_t I2CReceiveB(uint32_t slave_addr, uint8_t reg) { //specify that we are writing (a register address) to the slave device I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, false); //specify register to be read I2CMasterDataPut(I2C0_BASE, reg); //send control byte and register address byte to slave device I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START); //wait for MCU to finish transaction while(I2CMasterBusy(I2C0_BASE)); //specify that we are going to read from slave device I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, true); //send control byte and read from the register we specified I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START); //wait for MCU to finish transaction while(I2CMasterBusy(I2C0_BASE)); //return data pulled from the specified register return I2CMasterDataGet(I2C0_BASE); } //************************************************** Slave Fifo Reset Function ***************************************************************// void resetFifo () { I2CSend(0x57, 0x02, 0x00); // Reset FIFO Write Pointer I2CSend(0x57, 0x04, 0x00); // Reset FIFO Read Pointer I2CSend(0x57, 0x03, 0x00); // Reset FIFO Overflow Counter } //************************************************** I2C Interrupt Handler Function ***************************************************************// void I2C0MasterIntHandler (void) { I2CMasterIntClear(I2C0_BASE); // Clear the I2C interrupt flag resetFifo(); // Reset Slave Fifo Fifo_WR_PTR = I2CReceiveS(0x57, 0x02); // Read FIFO Write Pointer Num_Samples_Available = Fifo_WR_PTR - Fifo_RD_PTR; // Evaluating Number of samples to be read from FIFO // Num_Samples_Read =< Num_Samples_Available; // for (i = 0; i < Num_Samples_Available; i++) { ir1 = I2CReceiveB(0x57, 0x05); // Receive first byte of sample ir2 = I2CReceiveB(0x57, 0x05); // Receive second byte of sample ir = (uint16_t) ir1 << 16 | (uint16_t) ir2; // Complete iR sample red1 = I2CReceiveB(0x57, 0x05); // Receive third byte of sample red2 = I2CReceiveB(0x57, 0x05); // Receive fourth byte of sample red = (uint16_t) red1 << 16 | (uint16_t) red2; // Complete Red sample } } //************************************************************* Main **************************************************************************// int main() { SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_INT | SYSCTL_XTAL_16MHZ); // System Clock InitI2C0(); // I2C Initialization resetFifo(); // Reset Slave Fifo I2CSend(0x57, 0x06, 0x03); // Mode Configuration I2CSend(0x57, 0x07, 0x47); // SpO2 Configuration I2CSend(0x57, 0x09, 0x44); // LEDs Configuration I2CSend(0x57, 0x00, 0xB1); // Interrupt Status I2CSend(0x57, 0x01, 0xB0); // Interrupt Enable }
I am still not processing the values. I am just trying to get the iRed and Red values and observe them in the debugger.
I have no clue what I did wrong. Any help would be appreciated!!