I have an MSP430FR2675 that is communicating with an Ambarella CV25 MPU via I2C. The CV25 is the master and the MSP430 is the slave. I have set up my MSP430 to be able to handle I2C slave communication with a master. I have tested the MSP430 I2C functionality using an Aardvark I2C/SPI controller as the master and found that the I2C communication was working. However, the I2C communication is not working with the CV25 when using the i2c-dev Linux module. I send an i2cdetect command and find that the MSP430 address is not acknowledging the detect. I also do an i2cset command and the response from Linux is that an error occurred and the MSP430 does not recognize that a command was sent to it.
The command I am sending is "i2cset -y 0 0x0a 0x01 0x10 0x27 s" (i2c bus is 0, the MSP430 address is 0x0a, the MSP430 register is 0x01, and the command is 0x1027). Below are images of how that command looks when the Aardvark is sending the command and when the CV25 is sending the command. As can be seen, the command from both the Aardvark and CV25 seems to be sending properly to the MSP430. However, the MSP430 is only acknowledging properly from the Aardvark.
Aardvark
CV25
Below is my code to handle calls from the master device. The I2CSlave functions being called were generated from the CapTIvate application.
void HostInterface_Initialize(void) { // Set the host interrupt pin as an output GPIO_setAsOutputPin(CONFIG_HOST_IRQ_PORT, CONFIG_HOST_IRQ_PIN); // Open & Initialize the I2C Slave port I2CSlave_openPort(&HostInterface_handle); I2CSlave_setTransmitBuffer( (HostInterface_i2cDataBuffer + HOST_INTERFACE_OVRHD_LENGTH), (HOST_INTERFACE_BUFFER_SIZE - HOST_INTERFACE_OVRHD_LENGTH) ); } static bool HostInterface_ReceiveCallback(uint16_t count) { // If there is no data sent, don't do anything if (count == 0) { return false; } // Register read command else if (count == 1) { // TODO: Add any read commands to this section } // Register write command else { uint8_t *buffer = &HostInterface_i2cDataBuffer[HOST_INTERFACE_CMD_OFFSET]; // Do the specific command based on register switch (HostInterface_i2cDataBuffer[HOST_INTERFACE_REG_OFFSET]) { case I2C_CERBERUS_LED_SET_FREQUENCY_REG: HostInterfaceLEDs_FrequencyHandler(buffer); break; case I2C_CERBERUS_LED_KEY_DUTY_CYCLE_REG: HostInterfaceLEDs_KeyDutyCycleHandler(buffer); break; case I2C_CERBERUS_LED_STATUS_RED_DUTY_CYCLE_REG: HostInterfaceLEDs_StatusRedDutyCycleHandler(buffer); break; case I2C_CERBERUS_LED_STATUS_GREEN_DUTY_CYCLE_REG: HostInterfaceLEDs_StatusGreenDutyCycleHandler(buffer); break; case I2C_CERBERUS_LED_STATUS_BLUE_DUTY_CYCLE_REG: HostInterfaceLEDs_StatusBlueDutyCycleHandler(buffer); break; case I2C_CERBERUS_LED_STATUS_WHITE_DUTY_CYCLE_REG: HostInterfaceLEDs_StatusWhiteDutyCycleHandler(buffer); break; case I2C_CERBERUS_LED_POWER_STATUS_REG: HostInterfaceLEDs_PowerStatusHandler(buffer); break; // TODO: Add in other registers later default: break; } } // Return false to exit with the CPU in its previous state. // Since the response packet generation was handled immediately here, // there is no need to exit active. return false; }
Do you see any issues that I have with my setup or measurements? Is there a setting that I am missing to have it run properly in Linux? Let me know if you need any more details or information.
Thanks for your help!