Wednesday, 20 February 2019

microcontroller - I2C setting MCU as both slave and master at the same time


Hello everyone I'm working on a new project with the TI MSP432P401R microcontroller. I want to have 2 separate I2C buses. I2C bus 1 will set the MCU as the master, whereas the DAC and the pressure sensor as slaves. Then I2C bus 2 will set the same MCU as the slave, and the SmartPort as the master (more specifically a device that we connect to the SmartPort will be the master). I'm not sure how can I make the MCU both a slave and a master at the same time. What I tried to do was, I defined 2 different eUSCI_b modules


void I2C_init(void)
{
/* Initialize USCI_B3 and I2C Master to communicate with slave devices*/
I2C_initMaster(EUSCI_B3_BASE, &i2cConfig);

/* Disable I2C module to make changes */
I2C_disableModule(EUSCI_B3_BASE);


/* Enable I2C Module to start operations */
I2C_enableModule(EUSCI_B3_BASE);

/* Initialize USCI_B3 and I2C Master to communicate with slave devices*/
I2C_initMaster(EUSCI_B0_BASE, &i2cConfig);

/* Disable I2C module to make changes */
I2C_disableModule(EUSCI_B0_BASE);


/* Enable I2C Module to start operations */
I2C_enableModule(EUSCI_B0_BASE);

return;
}

where i2cConfig is


const eUSCI_I2C_MasterConfig i2cConfig =
{
EUSCI_B_I2C_CLOCKSOURCE_SMCLK, // SMCLK Clock Source

48000000, // SMCLK = 48MHz
EUSCI_B_I2C_SET_DATA_RATE_400KBPS, // Desired I2C Clock of 100khz
0, // No byte counter threshold
EUSCI_B_I2C_NO_AUTO_STOP // No Autostop
};

and then tried to use this function for each module I defined to add slaves. But the thing is, the function only allows me to enter one slave address, but for my I2C bus1, I have 2 slaves: DAC and the pressure sensor.


extern void I2C_initSlave(uint32_t moduleInstance, uint_fast16_t slaveAddress,
uint_fast8_t slaveAddressOffset, uint32_t slaveOwnAddressEnable);


I would be very grateful if someone can help me with this problem or show me a better way to implement the same MCU as both a slave and a master at the same time. I'm new to programming with the I2C protocol and I'd appreciate any help. Thank you and have a great day.



Answer



You are not thinking about the problem quite right. You are not setting the MCU to be a slave, you are setting one I2C interface module (one eUSCI) to be a master and another eUSCI to be a slave. The MSP432 itself is neither master nor slave, it just talks to the two eUSCI blocks.


There are two notions of slave address. One is the slave address that the master (you) uses to communicate with some other device, like a temperature sensor. That slave address is used just for the duration of the communication with the particular slave, and then is loaded with a different value when you want to talk to some other sensor or peripheral device. There is no need to store the addresses of all slave devices in eUSCI registers.


The other notion of a slave address is used when your eUSCI is acting as a slave device and some other gadget will be the master. In this case the slave address is more or less permanent and must be defined as part of the initialization, so that the eUSCI can recognize when the external master is sending a message to it.


So, you can treat the two eUSCI modules as being completely independent. Their SCL and SDA signals are independent, and the operation of the two I2C busses can be completely different.


No comments:

Post a Comment

arduino - Can I use TI's cc2541 BLE as micro controller to perform operations/ processing instead of ATmega328P AU to save cost?

I am using arduino pro mini (which contains Atmega328p AU ) along with cc2541(HM-10) to process and transfer data over BLE to smartphone. I...