Other Parts Discussed in Thread: SYSCONFIG
Tool/software:
Hello ,
I am using TI mspm0g3107 microcontroller for my project where i am using the i2c for controlling my display and EEPROM .
I was getting problem when I continuesly try to write and read from EEPROM using the example code : i2c_controller_rw_multibyte_fifo_interrupts
In this If I provide Delay between read and write operation then only i am able to read.
I don't want use that dilay because in my actual project application it will delay my loop cycle.
I am provideing you my sysconfig and code.
/*
* Copyright (c) 2021, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ti_msp_dl_config.h"
/* Maximum size of TX packet */
#define I2C_TX_MAX_PACKET_SIZE (16)
/* Number of bytes to send to target device */
#define I2C_TX_PACKET_SIZE (16)
/* Maximum size of RX packet */
#define I2C_RX_MAX_PACKET_SIZE (16)
/* Number of bytes to received from target */
#define I2C_RX_PACKET_SIZE (16)
/* I2C Target address */
#define I2C_TARGET_ADDRESS (0x50)
/* Data sent to the Target */
uint8_t gTxPacket[I2C_TX_MAX_PACKET_SIZE] = {0x00, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
/* Counters for TX length and bytes sent */
uint32_t gTxLen, gTxCount;
/* Data received from Target */
uint8_t gRxPacket[I2C_RX_MAX_PACKET_SIZE];
/* Counters for TX length and bytes sent */
uint32_t gRxLen, gRxCount;
/* Indicates status of I2C */
enum I2cControllerStatus {
I2C_STATUS_IDLE = 0,
I2C_STATUS_TX_STARTED,
I2C_STATUS_TX_INPROGRESS,
I2C_STATUS_TX_COMPLETE,
I2C_STATUS_RX_STARTED,
I2C_STATUS_RX_INPROGRESS,
I2C_STATUS_RX_COMPLETE,
I2C_STATUS_ERROR,
} gI2cControllerStatus;
int main(void)
{
SYSCFG_DL_init();
// DL_I2C_setTimerPeriod(I2C_INST, 79);
/* Set LED to indicate start of transfer */
DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
NVIC_EnableIRQ(I2C_INST_INT_IRQN);
DL_SYSCTL_disableSleepOnExit();
gI2cControllerStatus = I2C_STATUS_IDLE;
gTxLen = I2C_TX_PACKET_SIZE;
/*
* Fill the FIFO
* The FIFO is 8-bytes deep, and this function will return number
* of bytes written to FIFO */
gTxCount = DL_I2C_fillControllerTXFIFO(I2C_INST, &gTxPacket[0], gTxLen);
/* Enable TXFIFO trigger interrupt if there are more bytes to send */
if (gTxCount < gTxLen) {
DL_I2C_enableInterrupt(
I2C_INST, DL_I2C_INTERRUPT_CONTROLLER_TXFIFO_TRIGGER);
} else {
DL_I2C_disableInterrupt(
I2C_INST, DL_I2C_INTERRUPT_CONTROLLER_TXFIFO_TRIGGER);
}
/*
* Send the packet to the controller.
* This function will send Start + Stop automatically.
*/
gI2cControllerStatus = I2C_STATUS_TX_STARTED;
while (!(
DL_I2C_getControllerStatus(I2C_INST) & DL_I2C_CONTROLLER_STATUS_IDLE))
;
DL_I2C_startControllerTransfer(
I2C_INST, I2C_TARGET_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_TX, gTxLen);
/* Wait until the Controller sends all bytes */
while ((gI2cControllerStatus != I2C_STATUS_TX_COMPLETE) &&
(gI2cControllerStatus != I2C_STATUS_ERROR)) {
__WFE();
}
while (DL_I2C_getControllerStatus(I2C_INST) &
DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
;
/* Trap if there was an error */
if (DL_I2C_getControllerStatus(I2C_INST) &
DL_I2C_CONTROLLER_STATUS_ERROR) {
/* LED will remain high if there is an error */
__BKPT(0);
}
while (!(
DL_I2C_getControllerStatus(I2C_INST) & DL_I2C_CONTROLLER_STATUS_IDLE))
;
/* Add delay between transfers */
delay_cycles(1000 * 1000);
/* Send a read request to Target */
gRxLen = I2C_RX_PACKET_SIZE;
gRxCount = 0;
gI2cControllerStatus = I2C_STATUS_RX_STARTED;
DL_I2C_startControllerTransfer(
I2C_INST, I2C_TARGET_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_RX, gRxLen);
/* Wait for all bytes to be received in interrupt */
while (gI2cControllerStatus != I2C_STATUS_RX_COMPLETE) {
__WFE();
}
while (DL_I2C_getControllerStatus(I2C_INST) &
DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
;
while(1);
/* If write and read were successful, toggle LED */
// while (1) {
// DL_GPIO_togglePins(GPIO_LEDS_PORT,
// GPIO_LEDS_USER_LED_1_PIN | GPIO_LEDS_USER_TEST_PIN);
// delay_cycles(16000000);
// }
}
void I2C_INST_IRQHandler(void)
{
switch (DL_I2C_getPendingInterrupt(I2C_INST)) {
case DL_I2C_IIDX_CONTROLLER_RX_DONE:
gI2cControllerStatus = I2C_STATUS_RX_COMPLETE;
break;
case DL_I2C_IIDX_CONTROLLER_TX_DONE:
DL_I2C_disableInterrupt(
I2C_INST, DL_I2C_INTERRUPT_CONTROLLER_TXFIFO_TRIGGER);
gI2cControllerStatus = I2C_STATUS_TX_COMPLETE;
break;
case DL_I2C_IIDX_CONTROLLER_RXFIFO_TRIGGER:
gI2cControllerStatus = I2C_STATUS_RX_INPROGRESS;
/* Receive all bytes from target */
while (DL_I2C_isControllerRXFIFOEmpty(I2C_INST) != true) {
if (gRxCount < gRxLen) {
gRxPacket[gRxCount++] =
DL_I2C_receiveControllerData(I2C_INST);
} else {
/* Ignore and remove from FIFO if the buffer is full */
DL_I2C_receiveControllerData(I2C_INST);
}
}
break;
case DL_I2C_IIDX_CONTROLLER_TXFIFO_TRIGGER:
gI2cControllerStatus = I2C_STATUS_TX_INPROGRESS;
/* Fill TX FIFO with next bytes to send */
if (gTxCount < gTxLen) {
gTxCount += DL_I2C_fillControllerTXFIFO(
I2C_INST, &gTxPacket[gTxCount], gTxLen - gTxCount);
}
break;
/* Not used for this example */
case DL_I2C_IIDX_CONTROLLER_ARBITRATION_LOST:
case DL_I2C_IIDX_CONTROLLER_NACK:
if ((gI2cControllerStatus == I2C_STATUS_RX_STARTED) ||
(gI2cControllerStatus == I2C_STATUS_TX_STARTED)) {
/* NACK interrupt if I2C Target is disconnected */
gI2cControllerStatus = I2C_STATUS_ERROR;
}
case DL_I2C_IIDX_CONTROLLER_RXFIFO_FULL:
case DL_I2C_IIDX_CONTROLLER_TXFIFO_EMPTY:
case DL_I2C_IIDX_CONTROLLER_START:
case DL_I2C_IIDX_CONTROLLER_STOP:
case DL_I2C_IIDX_CONTROLLER_EVENT1_DMA_DONE:
case DL_I2C_IIDX_CONTROLLER_EVENT2_DMA_DONE:
default:
break;
}
}
/**
* These arguments were used when this file was generated. They will be automatically applied on subsequent loads
* via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments.
* @cliArgs --device "MSPM0G350X" --part "Default" --package "LQFP-64(PM)" --product "mspm0_sdk@2.04.00.06"
* @v2CliArgs --device "MSPM0G3507" --package "LQFP-64(PM)" --product "mspm0_sdk@2.04.00.06"
* @versions {"tool":"1.22.0+3893"}
*/
/**
* Import the modules used in this configuration.
*/
const GPIO = scripting.addModule("/ti/driverlib/GPIO", {}, false);
const GPIO1 = GPIO.addInstance();
const I2C = scripting.addModule("/ti/driverlib/I2C", {}, false);
const I2C1 = I2C.addInstance();
/**
* Write custom configuration values to the imported modules.
*/
GPIO1.$name = "GPIO_LEDS";
GPIO1.port = "PORTA";
GPIO1.associatedPins.create(2);
GPIO1.associatedPins[0].$name = "USER_LED_1";
GPIO1.associatedPins[0].initialValue = "SET";
GPIO1.associatedPins[0].assignedPin = "0";
GPIO1.associatedPins[1].$name = "USER_TEST";
GPIO1.associatedPins[1].initialValue = "SET";
GPIO1.associatedPins[1].assignedPin = "15";
const Board = scripting.addModule("/ti/driverlib/Board", {}, false);
Board.peripheral.$assign = "DEBUGSS";
Board.peripheral.swclkPin.$assign = "PA20";
Board.peripheral.swdioPin.$assign = "PA19";
I2C1.basicEnableController = true;
I2C1.basicControllerBusSpeed = 400000;
I2C1.advControllerTXFIFOTRIG = "BYTES_1";
I2C1.intController = ["ARBITRATION_LOST","NACK","RXFIFO_TRIGGER","RX_DONE","TX_DONE"];
I2C1.$name = "I2C";
I2C1.advAnalogGlitchFilter = "DISABLED";
I2C1.peripheral.$assign = "I2C1";
I2C1.sdaPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric0";
I2C1.sdaPinConfig.hideOutputInversion = scripting.forceWrite(false);
I2C1.sdaPinConfig.onlyInternalResistor = scripting.forceWrite(false);
I2C1.sdaPinConfig.passedPeripheralType = scripting.forceWrite("Digital");
I2C1.sclPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric1";
I2C1.sclPinConfig.hideOutputInversion = scripting.forceWrite(false);
I2C1.sclPinConfig.onlyInternalResistor = scripting.forceWrite(false);
I2C1.sclPinConfig.passedPeripheralType = scripting.forceWrite("Digital");
const SYSCTL = scripting.addModule("/ti/driverlib/SYSCTL", {}, false);
SYSCTL.forceDefaultClkConfig = true;
SYSCTL.clockTreeEn = true;
/**
* Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future
* version of the tool will not impact the pinmux you originally saw. These lines can be completely deleted in order to
* re-solve from scratch.
*/
GPIO1.associatedPins[0].pin.$suggestSolution = "PA0";
GPIO1.associatedPins[1].pin.$suggestSolution = "PA15";
I2C1.peripheral.sdaPin.$suggestSolution = "PA10";
I2C1.peripheral.sclPin.$suggestSolution = "PA11";