Part Number: SW-EK-TM4C123GXL
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!!