This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Tool/software: TI-RTOS
Dear Team,
I have two tasks one with I2C Transaction and other with SPI Transaction. when I disable SPI task I2C task is running smoothly, transaction reads data from the sensor. Even when I enable the SPI Task , I2C task working fine. But when I connect MISO and MOSI lines to the microcontroller. I2C Transaction going to Bad I2C Transfer.
To be short: when I connect the MISO and MOSI lines to microcontroller and enable SPI task . I2C task making the system_abort.
Please give your valuable suggestion that where I'm going wrong in the connections.
Here are the code snippets for each module:
I2C Pin configuration:
GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_3); GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_2); while (GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_3) != GPIO_PIN_3) { GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_2, 0); GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_2, GPIO_PIN_2); } // Configure the GPIO Pin Mux for PB2 - I2C0SCL GPIOPinConfigure(GPIO_PB2_I2C0SCL); GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2); // Configure the GPIO Pin Mux for PB3 - I2C0SDA GPIOPinConfigure(GPIO_PB3_I2C0SDA); GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
I2C Channel opening:
// I2C Channel0 opening I2C_Params_init(&signal.i2c0Params); signal.i2c0Params.bitRate = I2C_100kHz; signal.i2c0 = I2C_open(I2C_IMU_LEFT_DIAGONALS, &signal.i2c0Params); if (signal.i2c0 == NULL) { System_abort("Error Initializing I2C channel0\n"); } else { System_printf("I2C Channel 0 Initialized!\n"); }
#define I2C_IMU_LEFT_DIAGONALS I2C0_IMU_LEFT_DIAGONALS
const I2CTiva_HWAttrs i2cTivaHWAttrs[I2CCOUNT] = { { .baseAddr = I2C0_BASE, .intNum = INT_I2C0, .intPriority = (~0) }, { .baseAddr = I2C1_BASE, .intNum = INT_I2C1, .intPriority = (~0) } }; const I2C_Config I2C_config[] = { { .fxnTablePtr = &I2CTiva_fxnTable, .object = &i2cTivaObjects[0], .hwAttrs = &i2cTivaHWAttrs[0] }, { .fxnTablePtr = &I2CTiva_fxnTable, .object = &i2cTivaObjects[1], .hwAttrs = &i2cTivaHWAttrs[1] }, {NULL, NULL, NULL} };
WriteRegister code:
void CSupport::i2c_writeRegister(I2C_Handle handle,unsigned char slaveAddr,uint16_t regAddr, uint32_t value,I2C_TRANSFER_TYPE transferType) { I2C_Handle i2cChannel1; I2C_Params currI2cParams; uint8_t txBuffer[4]; I2C_Transaction i2cTransaction; i2cTransaction.slaveAddress = slaveAddr; i2cTransaction.writeBuf = txBuffer; switch(transferType) { case IMU_TRANSACTION : //Write to a 8-bit status register i2cTransaction.writeCount = 2; i2cTransaction.readCount = 0; txBuffer[0] = regAddr & 0xFF;//LB Addr txBuffer[1] = value & 0xFF; break; case CURRENT_TRANSACTION : i2cTransaction.writeCount = 3; i2cTransaction.readCount = 0; txBuffer[0] = regAddr & 0xFF;// 8- Bit address txBuffer[1] = value >> 8;// HB Addr txBuffer[2] = value & 0xFF;// LB Addr break; default: //Write to a 16-bit status register i2cTransaction.writeCount = 4; i2cTransaction.readCount = 0; txBuffer[0] = (regAddr >> 8) & 0xFF;//HB Addr txBuffer[1] = regAddr & 0xFF;//LB Addr txBuffer[2] = value & 0xFF; txBuffer[3] = (value >> 8) & 0xFF; break; } if (!I2C_transfer(handle, &i2cTransaction)) { /*GPIO_write(Board_LED_RED, Board_LED_ON);*/ System_abort("Bad I2C transfer!"); } }
Read Register :
/* * This function used for read operation in I2C Transaction of 8 and 16 bit registers * "transferType" need to mention for type of transfer * IMU_TRANSACTION - 8 Bit * CURRENT_TRANSACTION - 16 Bit */ void CSupport::i2c_readRegister(I2C_Handle handle, unsigned char slaveAddr, uint8_t regAddr, uint16_t *data, size_t length, I2C_TRANSFER_TYPE transferType) { uint8_t txBuffer[2]; I2C_Transaction i2cTransaction; i2cTransaction.slaveAddress = slaveAddr; i2cTransaction.writeBuf = txBuffer; i2cTransaction.readBuf = data; i2cTransaction.readCount = length; switch(transferType) { case IMU_TRANSACTION : //Write to a 8-bit status register i2cTransaction.writeCount = 1; txBuffer[0] = regAddr & 0xFF;//LB Addr break; case CURRENT_TRANSACTION : i2cTransaction.writeCount = 1; txBuffer[0] = regAddr & 0xFF;// 8- Bit address break; default: // 16- Bit address i2cTransaction.writeCount = 2; txBuffer[0] = regAddr >> 8;//HB Addr txBuffer[1] = regAddr & 0xFF;//LB Addr break; } if (!I2C_transfer(handle, &i2cTransaction)) { GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 1); System_abort("Bad I2C transfer!"); } }
I2C Task:
void get_imu() { uint16_t pwr = 0x00; CSupport support; support.i2c_writeRegister(signal.i2c0,MPU6050_I2C_ADDRESS,0x6B,0x80,IMU_TRANSACTION); support.i2c_readRegister(signal.i2c0,MPU6050_I2C_ADDRESS, 0x6B, &pwr, 1, IMU_TRANSACTION); do { support.i2c_readRegister(signal.i2c0,MPU6050_I2C_ADDRESS, 0x6B, &pwr, 1, IMU_TRANSACTION); } while ((pwr & 0x40) != 0x40); // Use PLL with X axis gyroscope reference support.i2c_writeRegister(signal.i2c0,MPU6050_I2C_ADDRESS,0x6B,0x01,IMU_TRANSACTION); // Enable I2C Master mode support.i2c_writeRegister(signal.i2c0,MPU6050_I2C_ADDRESS,0x6A,0x20,IMU_TRANSACTION); // Set sample rate divider support.i2c_writeRegister(signal.i2c0,MPU6050_I2C_ADDRESS,0x19,0x13,IMU_TRANSACTION); support.i2c_writeRegister(signal.i2c0,MPU6050_I2C_ADDRESS,0x67,0x11,IMU_TRANSACTION); while (1) { Semaphore_pend(IMUSem, BIOS_WAIT_FOREVER); support.i2c_readRegister(signal.i2c0,MPU6050_I2C_ADDRESS, 0x3B, (uint16_t *) &signal.imu.mpu6050, 14, IMU_TRANSACTION); signal.imu.AcX = signal.imu.mpu6050.AccelXH << 8 | signal.imu.mpu6050.AccelXL; signal.imu.AcY = signal.imu.mpu6050.AccelYH << 8 | signal.imu.mpu6050.AccelYL; signal.imu.AcZ = signal.imu.mpu6050.AccelZH << 8 | signal.imu.mpu6050.AccelZL; signal.imu.temperature = (((signal.imu.mpu6050.TempH << 8) | signal.imu.mpu6050.TempL) / 340)+36.5; signal.imu.GyX = signal.imu.mpu6050.GyroXH << 8 | signal.imu.mpu6050.GyroXL; signal.imu.GyY = signal.imu.mpu6050.GyroYH << 8 | signal.imu.mpu6050.GyroYL; signal.imu.GyZ = signal.imu.mpu6050.GyroZH << 8 | signal.imu.mpu6050.GyroZL; } I2C_close(signal.i2c0); //Deinitialized I2C System_printf("I2C Channel 0 closed!\n"); System_flush(); }
SPI Pin configuration:
// Configure the GPIO Pin Mux for PA2 - SSI0CLK GPIOPinConfigure(GPIO_PA2_SSI0CLK); GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_2); // Configure the GPIO Pin Mux for PA3 - SSI0FSS GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_0); // To pull the Chip select line low . As the driver CS is not giving desired result GPIOPinConfigure(GPIO_PA3_SSI0FSS); GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_3); // Configure the GPIO Pin Mux for PA4 - SSI0RX GPIOPinConfigure(GPIO_PA4_SSI0RX); GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_4); // Configure the GPIO Pin Mux for PA5 - SSI0TX GPIOPinConfigure(GPIO_PA5_SSI0TX); GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5);
SPI channel Opening:
SPI_Params_init(&rightSpiParams); rightSpi = SPI_open(RIGHT_DIAGONAL_SPI0, &rightSpiParams); if (rightSpi == NULL) System_abort("Error initializing Right SPI\n"); else System_printf("Right SPI initialized\n");
#define SPI_RIGHT_DIAGONALS RIGHT_DIAGONAL_SPI0
const SPITivaDMA_HWAttrs spiTivaDMAHWAttrs[SPICOUNT] = { { .baseAddr = SSI0_BASE, .intNum = INT_SSI0, .intPriority = (~0), .scratchBufPtr = &spiTivaDMAscratchBuf[0], .defaultTxBufValue = 0, .rxChannelIndex = UDMA_CHANNEL_SSI0RX, .txChannelIndex = UDMA_CHANNEL_SSI0TX, .channelMappingFxn = uDMAChannelAssign, .rxChannelMappingFxnArg = UDMA_CH10_SSI0RX, .txChannelMappingFxnArg = UDMA_CH11_SSI0TX }, { .baseAddr = SSI1_BASE, .intNum = INT_SSI1, .intPriority = (~0), .scratchBufPtr = &spiTivaDMAscratchBuf[1], .defaultTxBufValue = 0, .rxChannelIndex = UDMA_CHANNEL_SSI1RX, .txChannelIndex = UDMA_CHANNEL_SSI1TX, .channelMappingFxn = uDMAChannelAssign, .rxChannelMappingFxnArg = UDMA_CH10_SSI1RX, .txChannelMappingFxnArg = UDMA_CH11_SSI1TX } }; const SPI_Config SPI_config[] = { { .fxnTablePtr = &SPITivaDMA_fxnTable, .object = &spiTivaDMAObjects[0], .hwAttrs = &spiTivaDMAHWAttrs[0] }, { .fxnTablePtr = &SPITivaDMA_fxnTable, .object = &spiTivaDMAObjects[1], .hwAttrs = &spiTivaDMAHWAttrs[1] }, {NULL,NULL,NULL}, };
SPI Task:
void get_height(){ // Buffers for transactions unsigned char rightRxBuffer[8] = {0}; unsigned char rightTxBuffer[] = {0x00,0x01,0x87,0x00,0x00,0x00,0x00,0x00,0x00};// For 2 counters - 24 bit SPI_Handle rightSpi,leftSpi,frontSpi; SPI_Params rightSpiParams,leftSpiParams,frontSpiParams; SPI_Transaction rightSpiTrans,leftSpiTrans,frontSpiTrans; bool rightConfigure,leftConfigure,frontConfigure; bool rightReceive,leftReceive,frontReceive; SPI_Params_init(&rightSpiParams); rightSpi = SPI_open(RIGHT_DIAGONAL_SPI0, &rightSpiParams); if (rightSpi == NULL) System_abort("Error initializing Right SPI\n"); else System_printf("Right SPI initialized\n"); /* Initialize right SPI transaction structure */ rightSpiTrans.count = sizeof(rightTxBuffer); rightSpiTrans.txBuf = (Ptr)rightTxBuffer; rightSpiTrans.rxBuf = NULL; /* Configure Encoder*/ GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 1); GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 0); rightConfigure = SPI_transfer(rightSpi, &rightSpiTrans); GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 1); if (rightConfigure) System_printf("succesfully configured Right SPI\n"); else System_abort("Unsuccessful configuration of Right SPI\n"); System_flush(); rightTxBuffer[0] = {0x30}; // To reset counters before counting rightTxBuffer[1] = {0x03}; rightSpiTrans.rxBuf = (Ptr)rightRxBuffer; rightSpiTrans.count = 2; GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 0); rightConfigure = SPI_transfer(rightSpi, &rightSpiTrans); GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 1); rightTxBuffer[0] = {0x88}; // To read counter values rightSpiTrans.rxBuf = (Ptr)rightRxBuffer; rightSpiTrans.count = 7; counter_48bit rightEncoder; while (1){ Semaphore_pend(ENCSem, BIOS_WAIT_FOREVER); GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 0); // Suggested to use 2:1 MUX for Chip select between different SPI Slaves rightReceive = SPI_transfer(rightSpi, &rightSpiTrans); GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 1); if(!rightReceive) System_abort("Right SPI Receive failed :("); signal.rightEncoder.counter1 = (rightRxBuffer[1])<<16|(rightRxBuffer[2]<<8)|(rightRxBuffer[3]); signal.rightEncoder.counter0 = (rightRxBuffer[4])<<16|(rightRxBuffer[5]<<8)|(rightRxBuffer[6]); } }
Hello Charles,
Answer for the questions as :
Charles Tsai said:
0. Which line of System_abort are you calling? You have System_abort("Error Initializing I2C channel0\n") and System_abort("Bad I2C transfer!").
System_abort("Bad I2C transfer!") in readRegister, writeRegister It happening randomly (Mostly in i2c_readRegister()).
Charles Tsai said:1. When you connect the MISO and MOSI pins, does the SPI transaction continue to work or you don't know since you already took the abort due to the I2C?
I feel SPI works as I'm able to see few jump of waves in oscilloscope . But Didn't saw very clearly.
Charles Tsai said:2. What happened if only SPI is enabled but not I2C? Will the SPI work by itself?
Yeah. SPI is working well If enable only SPI task. ( and vice versa i.e., I2C also works if enable only I2C task).
Charles Tsai said:3. With a slower SPI clock, will it make a difference to the I2C abort? Try with a much slower SPI clock so the interrupt comes slower.
I tried with 500 ms configuration but didn't have any postive result.\
Charles Tsai said:4. Can you use the ROV to find out if you have any stack issue?
I'm giving 2048 as stacksize Hope its not be a problem
Charles Tsai said:5. Are you using HWI? Is it a interrupt priority issue as the SSI0 has default priority than I2C0? What if you manually change
No I'm not using any HWI in the system. So Hope no need to change anything?
Majorly system fails when I try to connect the MISO and MOSI of the SPI channel . The system is not failing even both tasks are enabled. So any problem with connections?( I haven't connect any pull up resistors in any of the communicaiton channels(SPI,I2C).
Thanks for taking and analysis the problem and framing questions in structured.
Best Regards,
Yashwanth Kumar Gandeti.
HI,
Yashwanth Gandeti said:Majorly system fails when I try to connect the MISO and MOSI of the SPI channel . The system is not failing even both tasks are enabled. So any problem with connections?( I haven't connect any pull up resistors in any of the communicaiton channels(SPI,I2C).
For proper I2C operation you must have proper pull up resistors on the I2C_SCL and I2C_SDA bus. No need of pullups on the SPI. I will suggest you first add correct pullup to the bus first and see if of any different results.