Other Parts Discussed in Thread: SYSCONFIG
I have a single MSPM0G3507 evaluation board with two configured I2C modules as SMBus modules, one acts as a controller and the other acts a target, I connected both of the SDA and SCL lines with external pull up resistors. I'm also using the SMBus library provided with the MSPM0 SDK.
I have tried sending write commands from the controller to the target using the SMBus_controllerSendByte() and it works with no issues, whoever when attempting a read request, such as SMBus_controllerReadBlock(), the target doesn't receive any interrupts. My code is based on the SMBus controller and target examples provided by the SDK.
#include <stdint.h> #include "ti_msp_dl_config.h" #include <ti/smbus/smbus.h> #include <string.h> static SMBus SMBControllerInst; static SMBus SMBTargetInst; static SMBus_State currentBusState; static uint8_t targetRxBuff[SMB_MAX_PACKET_SIZE]; static uint8_t targetTxBuff[SMB_MAX_PACKET_SIZE]; static uint8_t controllerRxBuff[SMB_MAX_PACKET_SIZE + 4]; int main(void) { bool RXExpected; int8_t ret; SYSCFG_DL_init(); NVIC_ClearPendingIRQ(SMB_I2C_CONTROLLER_INST_INT_IRQN); NVIC_EnableIRQ(SMB_I2C_CONTROLLER_INST_INT_IRQN); NVIC_ClearPendingIRQ(SMB_I2C_TARGET_INST_INT_IRQN); NVIC_EnableIRQ(SMB_I2C_TARGET_INST_INT_IRQN); SMBus_controllerInit(&SMBControllerInst, SMB_I2C_CONTROLLER_INST, 32000000); SMBus_targetInit(&SMBTargetInst, SMB_I2C_TARGET_INST); SMBus_targetSetAddress(&SMBTargetInst, SMB_I2C_TARGET_TARGET_OWN_ADDR); SMBus_targetSetRxBuffer(&SMBTargetInst, targetRxBuff, sizeof(targetRxBuff)); SMBus_targetSetTxBuffer(&SMBTargetInst, targetTxBuff, sizeof(targetTxBuff)); SMBus_targetEnableInt(&SMBTargetInst); while(1) { ret = SMBus_controllerReadBlock(&SMBControllerInst, SMB_I2C_TARGET_TARGET_OWN_ADDR, 0x3, controllerRxBuff); if(ret == SMBUS_RET_OK) { if(SMBus_controllerWaitUntilDone(&SMBControllerInst, 100000) != SMBUS_RET_OK) { ret = SMBus_State_TimeOutError; SMBus_controllerReset(&SMBControllerInst); } else { ret = currentBusState; } if(ret == SMBus_State_OK) { int controllerRxLen = SMBus_getRxPayloadAvailable(&SMBControllerInst); if(controllerRxLen >= 1) { if(controllerRxBuff[1] == 'b') { DL_GPIO_togglePins(LED_GROUP_PORT, LED_GROUP_LED_0_PIN); } else { DL_GPIO_togglePins(LED_GROUP_PORT, LED_GROUP_LED_1_PIN); } } else { ret = SMBus_State_Target_Error; } } } SMBControllerInst.status.u8byte = 0x00; delay_cycles(20000000); } } void SMB_I2C_CONTROLLER_INST_IRQHandler(void) { currentBusState = SMBus_controllerProcessInt(&SMBControllerInst); } static uint8_t rxCmd = 1; void SMB_I2C_TARGET_INST_IRQHandler(void) { const SMBus_State currentState = SMBus_targetProcessInt(&SMBTargetInst); switch(currentState) { case SMBus_State_Target_FirstByte: rxCmd = SMBus_targetGetCommand(&SMBTargetInst); break; case SMBus_State_Target_CmdComplete: { char dataToSend[5]; uint32_t len = 0; if(rxCmd == 0x3) { strcpy(dataToSend, "bbbb"); len = 4; } else { strcpy(dataToSend, "rrr"); len = 3; } SMBTargetInst.nwk.txBuffPtr[0] = len; uint32_t i = 0; for(i = 0 ; i < len ; i++) { SMBTargetInst.nwk.txBuffPtr[i+1] = dataToSend[i]; } SMBTargetInst.nwk.txLen = len + 1; break; } default: break; } SMBus_processDone(&SMBTargetInst); }
The code is supposed to read a block of data from the target every 20M cycles, I'm always sending a command code 0x3 which commands the target to send a block of data of 4 bytes "bbbb", once the controller receives the block of data, it will check if the 1st byte of the RX buffer is 'b' then toggles the blue LED, however nothing happens, and it never reaches a breakpoint assigned to the top of target interrupt handler. I don't know what could be wrong here, I'm attaching the sample project file in case it is needed.
All help is appreciated. Thanks.