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.
Hi.
My name Dung.
I have project with MSP430i2041 EVM 1 Voltage (990K-2.4K - 220VAC max 250V), 3 Current (CT 1000.1, R = 6.8R max 80A), my design the same TIDM-3OUTSMTSTRP and use CT, not include Relay.
I have some question. On the EMDC when creat project why TI calculator approximately real value.
When I calib for MSP430i2041 by EMDC use KIT MSP430F5529LP, if only connect 3 CT to EVM, can read result to EMDC, when I connect 1V 3C to EVM it cannot connect to EMDC. I don't know why (I don't use MSP-ISO).
Dung,
Did you review my feedback to your questions in your previous thread?
MSP430I2041: Error when I use on Uniflash load image file
Regards,
James
Hi James. I have view your feedback. I will comback, thread. I thing that error when use Uniflash to load Image. I thing it have complete. If it continouos thread MSP430I2041: Error when I use on Uniflash load image file , this thread is close.
Hi Dung,
If you haven't marked the other thread resolved, please do so. You can copy your EMDC-related questions and my answers into this thread, and then we can continue here.
Regards,
James
Hi James.
Other thread I don't have question. This thread I have error when I connect HID to calibration value on KIT MSP430i2041 (EVM).
EVM 1 Voltage (990K-2.4K - 220VAC max 250V), 3 Current (CT 1000.1, Rshunt = 6.8R max 80A), my design the same TIDM-3OUTSMTSTRP and use CT, not include Relay.
When I calibration for MSP430i2041 by EMDC use KIT MSP430F5529LP, if only connect 3 CT (have current thought CT) to EVM, can read result to EMDC (have data result) and add Voltage to EVM it cannot connect to EMDC (no receiver data result on EMDC). I don't know why it can't read data. I don't use MSP-ISO.
Regards.
When I calibration for MSP430i2041 by EMDC use KIT MSP430F5529LP, if only connect 3 CT (have current thought CT) to EVM, can read result to EMDC (have data result) and add Voltage to EVM it cannot connect to EMDC (no receiver data result on EMDC). I don't know why it can't read data. I don't use MSP-ISO.
Be careful not using the MSP-ISO. If AC line gets connected to the board ground rather than AC neutral, and you're not using MSP-ISO, your PC could get damaged and you could get shocked.
You're saying that when you connect AC voltage to your board, the communication stops? This could be a power supply issue. How's the board powered? Battery? AC-to-DC power? F5529 LP? Make sure there's no power supply conflicts.
Make sure your board is powered before or while you are apply voltages to any pins (e.g. connecting sensors, connecting UART pins).
EVM 1 Voltage (990K-2.4K - 220VAC max 250V), 3 Current (CT 1000.1, Rshunt = 6.8R max 80A), my design the same TIDM-3OUTSMTSTRP and use CT, not include Relay.
I created this same project in EMDC and had no trouble connecting to the i20xx to view results or calibrate the board.
Here are some screenshots from my side.
Regards,
James
Your project run as the same my project .
You're saying that when you connect AC voltage to your board, the communication stops? This could be a power supply issue. How's the board powered? Battery? AC-to-DC power? F5529 LP? Make sure there's no power supply conflicts.
I have test with power from 5529LP and AC-to-DC Power, AC-to-DC module the same TIDM-3OUTSMTSTRP. I have carefully connect Neutral to 0V of EVM. Can you test calibration help me on TIDM-3OUTSMTSTRP. What is your connect?
When I calibration, I connect TX, RX, GND to P3.4, P3.3 and GND of 5529LP board. Data result when not apply Voltage.
And if I apply Voltage to EVM, I wait 5 min data not update.
I would divide and conquer this issue. I don't think it's an EMDC issue but a power supply issue. Without hooking anything up to AC, use the F5529 LP or a bench supply to power your board. The EMDC communication should work, and you should be able to enter the calibration mode. If that works, it indicates that your power supply is causing the device to stop communicating when AC is connected and you can start debugging that rather than the communication.
Now, I can't work on the i2041 for my project, because I don't understand why it can't be calibration. I switched to another IC for EVM, because i don't have time for test. If in future I have time maybe I can test and use it. MSP430i2401 and msp430F67791 I am sorry it don't work for my project. I have more time for it but it is not as expected.
Thank you so much, James.
Hi James.
The TI have solution for customer to design EVM. Why TI don't integration example calib value calculator in Code flow value of customer designed.
Hi Dung,
The manual calibration process is complex and requires an accurate test source to apply precise voltages, currents and phase angles to the board. The EMDC GUI still requires a test source but will easily perform the calibration process. Then, you can use the applied calibration factors in your final design by either updating those factors in your CCS project or sending them over UART from a host MCU or processor in the system.
For more details about the calibration calculations, refer to the following thread.
MSP430i2041: Need EMDC calibration factor calculation details
Regards,
James
Hi, Jame.
I thing when read full result Voltage mode Common ( 1V 3 CT), in EMDC mcu is >80%, but real when apply Voltage i thing MCU is overload => I can't read result and calibration it. Then i readl Vrms, Irms, V Peak, I Peak, Active Power, Active Energy. I can calibration it.
Now a read result over I2C, but it not read data. i use esp8266 on arduino.
Start i write 55 AA 06 04 01 01 01 07 00, when read i write 55 AA 06 04 80 00 01 0D 00 ( VRMS PHASE A). result is 0189040E, when i change read Irms PhaseA and V, I of other Phase the same result.
I don't understand. maybe wrong write I2C? I Read mode Device 0x0A is '0' => IDLE in evm_start()
byte evm_config(uint8_t device,uint8_t cmdRW, uint8_t cmdValue) { // 55 AA 06 04 CMD_CONFIG_MODE cmdRW cmdValue crcl crch byte byte_in,error; prepare_evm_write(CMD_CONFIG_MODE,cmdRW,cmdValue,6); Wire.beginTransmission(device); Serial.print(" Device: "); Serial.print(device,HEX); Serial.print(" "); for(byte i=0;i<9;i++) { Wire.write(evm_write_message[i]); if(cmdRW==CMD_WRITE)Serial.print(evm_write_message[i],HEX); } error = Wire.endTransmission();//Wire.endTransmission(); if(cmdRW==CMD_READ){ Wire.requestFrom(device, 1); byte_in = Wire.read(); Serial.print(byte_in,HEX); } Serial.println(" "); return error; } void evm_start(){ if(evm_config(i2041a,CMD_WRITE,CMD_MODE_ACTIVE)==0) Serial.println("Start Phase A - Ok. "); else Serial.println("Start Phase A - error. "); if(evm_config(i2041b,CMD_WRITE,CMD_MODE_ACTIVE)==0) Serial.println("Start Phase B - Ok. "); else Serial.println("Start Phase B - error. "); if(evm_config(i2041c,CMD_WRITE,CMD_MODE_ACTIVE)==0) Serial.println("Start Phase C - Ok. "); else Serial.println("Start Phase C - error. "); Serial.print("Read mode Device A"); evm_config(i2041a,CMD_READ,CMD_READ); Serial.print("Read mode Device B"); evm_config(i2041b,CMD_READ,CMD_READ); Serial.print("Read mode Device C"); evm_config(i2041c,CMD_READ,CMD_READ); }
Hi Dung,
I thing when read full result Voltage mode Common ( 1V 3 CT), in EMDC mcu is >80%, but real when apply Voltage i thing MCU is overload => I can't read result and calibration it. Then i readl Vrms, Irms, V Peak, I Peak, Active Power, Active Energy. I can calibration it.
I'm sorry, but I don't understand this. Are you saying that you can read the values when no voltage is applied but you cannot read values when voltage is applied? That shouldn't matter unless there's a power supply conflict. If you're using the MSP-ISO, make sure you're not using the isolated power supply for 3V3 if your board already has an AC/DC to 3V3 supply.
Start i write 55 AA 06 04 01 01 01 07 00, when read i write 55 AA 06 04 80 00 01 0D 00 ( VRMS PHASE A). result is 0189040E, when i change read Irms PhaseA and V, I of other Phase the same result.
For these commands, you can check the protocol in the latest EMDC Technology Guide (v1.40 as of today). Make sure you're changing the Phase ID byte in the command.
I don't understand. maybe wrong write I2C? I Read mode Device 0x0A is '0' => IDLE in evm_start()
I'm not sure about the Arduino code. Perhaps you could post that on an Arduino forum. I would also recommend just using one of our I2C code examples from TI Resource Explorer on the i20xx with dummy data to get the I2C communication working separately from the EMDC project. Then, you can work on integrating the I2C code into your EMDC project when it's working.
Hi James.
I'm sorry, but I don't understand this.
When I creat new project EVM with all parameter (0x80-0x8B) in mode 1V 3 CT, data result can connect with EMDC when AC voltage don't connect. When I connect AC Voltage to EVM => can't read result to calibration by EMDC.
If I creat project with VRMS, IRMS, Vpeak, Ipeak, Active power, Energy Power mode 1V 3 CT, I can calibration EVM over EMDC.
I'm not sure about the Arduino code. Perhaps you could post that on an Arduino forum. I would also recommend just using one of our I2C code examples from TI Resource Explorer on the i20xx with dummy data to get the I2C communication working separately from the EMDC project. Then, you can work on integrating the I2C code into your EMDC project when it's working.
Can you send to me example project Communication I2C between MSP430F5529LP with EVM MSP430i2041. After read result over I2C 5529LP send data debug to PC by UART. I want test I2C read data is Ok with MSP430Fxx. Please help me.
My project need send data to Server over Wifi Internet.
Thank you so much.
When I creat new project EVM with all parameter (0x80-0x8B) in mode 1V 3 CT, data result can connect with EMDC when AC voltage don't connect. When I connect AC Voltage to EVM => can't read result to calibration by EMDC.
If I creat project with VRMS, IRMS, Vpeak, Ipeak, Active power, Energy Power mode 1V 3 CT, I can calibration EVM over EMDC.
The EMDC code programmed on the EVM must match the EMDC project. If they don't the communication may not work correctly.
Can you send to me example project Communication I2C between MSP430F5529LP with EVM MSP430i2041. After read result over I2C 5529LP send data debug to PC by UART. I want test I2C read data is Ok with MSP430Fxx. Please help me.
Check out my earlier comments. I'd recommend starting with the I2C code examples in TI Resource Explorer (inside CCS or at dev.ti.com). Like I mentioned earlier, you'll want to split this effort up and make incremental progress.
You did the I2C communication in measurement with the i2041. Structure to write read data with i2041 like. Can you write a sample code to initialize the i2041 to operate and read measured voltage or current data?
Can you send to me example code to read data from i2041 in this application.
What is address of VRMS, IRMS, and other data when i want read?
Usually, i read and write to Eeprom, form for write (SlaveAdd, Address & read or write, data write or data to read).
You did the I2C communication in measurement with the i2041.
I'm not sure what you mean.
Can you send to me example code to read data from i2041 in this application.
You can find i20xx I2C example code in TI Resource explorer inside CCS or at dev.ti.com.
What is address of VRMS, IRMS, and other data when i want read?
These are just variables stored in RAM that you can use with I2C to send the data to a host.
Hi James Evans.
I use I2C to read result EVM from i2041. I write on MSP430G2553. MSP430G2553 is mater I2C will read data evm of multi device i2041 (add 0x0A). but my code read result only 00 FF FF FF FF FF FF FF FF FF FF . Please check for me, i have send I2C_Master_Write(SLAVE_ADDR, MasterType0, TYPE_0_LENGTH); // {0x55,0xAA,0x06,0x04,0x01,0x01,0x01,0x07,0x00}; before read data {0x55,0xAA,0x07,0x04,0x80,0x00,0x00,0x00,0x84,0x00};
//****************************************************************************** // MSP430G2xx3 Demo - USCI_B0, I2C Master multiple byte TX/RX // // Description: I2C master communicates to I2C slave sending and receiving // 3 different messages of different length. I2C master will enter LPM0 mode // while waiting for the messages to be sent/receiving using I2C interrupt. // ACLK = NA, MCLK = SMCLK = DCO 16MHz. // // // MSP430G2553 // ----------------- // /|\ | P2.6|--- XIN // | | | | // ---|RST | 32kHz // | | | // | P2.7|--- XOUT // | P1.1|<------- Receive Data (UCA0RXD) // | P1.2|-------> Transmit Data (UCA0TXD) // | P1.6|<------- Receive Data (UCB0SCL) // | P1.7|-------> Transmit Data (UCB0SDA) // // Nima Eskandari // Texas Instruments Inc. // April 2017 // Built with CCS V7.0 //****************************************************************************** #include <msp430.h> #include <stdint.h> #include <stdbool.h> //****************************************************************************** // UART Initialization ********************************************************* //****************************************************************************** #define SMCLK_11500 0 #define SMCLK_9600 1 #define ACLK_9600 2 #define UART_MODE SMCLK_11500 //****************************************************************************** // I2C Initialization ********************************************************** //****************************************************************************** #define SLAVE_ADDR 0x0A /* CMD_TYPE_X_SLAVE are example commands the master sends to the slave. * The slave will send example SlaveTypeX buffers in response. * * CMD_TYPE_X_MASTER are example commands the master sends to the slave. * The slave will initialize itself to receive MasterTypeX example buffers. * */ #define SLAVE_ADDR 0x0A #define TYPE_0_LENGTH 9 #define TYPE_1_LENGTH 10 #define TYPE_2_LENGTH 10 #define MAX_BUFFER_SIZE 20 // 00010100 0 0 01010101 10101010 uint8_t MasterType0 [TYPE_0_LENGTH] = {0x55,0xAA,0x06,0x04,0x01,0x01,0x01,0x07,0x00}; uint8_t MasterType1 [TYPE_1_LENGTH] = {0x55,0xAA,0x07,0x04,0x80,0x00,0x00,0x00,0x84,0x00}; uint8_t MasterType2 [TYPE_2_LENGTH] = {0x55,0xAA,0x07,0x04,0x80,0x00,0x01,0x00,0x85,0x00}; #define SLAVE_READ0 11 #define SLAVE_READ1 15 uint8_t SlaveRead0 [SLAVE_READ0] = {0}; //****************************************************************************** // General I2C State Machine *************************************************** //****************************************************************************** typedef enum I2C_ModeEnum{ IDLE_MODE, NACK_MODE, TX_REG_ADDRESS_MODE, RX_REG_ADDRESS_MODE, TX_DATA_MODE, RX_DATA_MODE, SWITCH_TO_RX_MODE, SWITCH_TO_TX_MODE, TIMEOUT_MODE } I2C_Mode; /* Used to track the state of the software state machine*/ I2C_Mode MasterMode = IDLE_MODE; /* The Register Address/Command to use*/ uint8_t TransmitRegAddr = 0; /* ReceiveBuffer: Buffer used to receive data in the ISR * RXByteCtr: Number of bytes left to receive * ReceiveIndex: The index of the next byte to be received in ReceiveBuffer * TransmitBuffer: Buffer used to transmit data in the ISR * TXByteCtr: Number of bytes left to transfer * TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer * */ uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0}; uint8_t RXByteCtr = 0; uint8_t ReceiveIndex = 0; uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0}; uint8_t TXByteCtr = 0; uint8_t TransmitIndex = 0; /* I2C Write and Read Functions */ /* For slave device with dev_addr, writes the data specified in *reg_data * * dev_addr: The slave device address. * Example: SLAVE_ADDR * reg_addr: The register or command to send to the slave. * Example: CMD_TYPE_0_MASTER * *reg_data: The buffer to write * Example: MasterType0 * count: The length of *reg_data * Example: TYPE_0_LENGTH * */ I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count); /* For slave device with dev_addr, read the data specified in slaves reg_addr. * The received data is available in ReceiveBuffer * * dev_addr: The slave device address. * Example: SLAVE_ADDR * reg_addr: The register or command to send to the slave. * Example: CMD_TYPE_0_SLAVE * count: The length of data to read * Example: TYPE_0_LENGTH * */ I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count); void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count); I2C_Mode I2C_Master_Read(uint8_t dev_addr, uint8_t count) { /* Initialize state machine */ MasterMode = RX_DATA_MODE; // TransmitRegAddr = reg_addr; RXByteCtr = count; TXByteCtr = 0; ReceiveIndex = 0; TransmitIndex = 0; /* Initialize slave address and interrupts */ UCB0I2CSA = dev_addr; IE2 |= UCB0RXIE; // Enable RX interrupt IE2 &= ~UCB0TXIE; // Disable TX interrupt UCB0CTL1 &= ~UCTR; // Switch to receiver MasterMode = RX_DATA_MODE; // State state is to receive data UCB0CTL1 |= UCTXSTT; // Send repeated start // IFG2 &= ~(UCB0TXIFG + UCB0RXIFG); // Clear any pending interrupts // IE2 &= ~UCB0RXIE; // Disable RX interrupt // IE2 |= UCB0TXIE; // Enable TX interrupt // UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition // __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts __bis_SR_register( GIE); // Enter LPM0 w/ interrupts return MasterMode; } I2C_Mode I2C_Master_Write(uint8_t dev_addr, uint8_t *reg_data, uint8_t count) { /* Initialize state machine */ MasterMode = TX_DATA_MODE; // TransmitRegAddr = reg_addr; //Copy register data to TransmitBuffer CopyArray(reg_data, TransmitBuffer, count); TXByteCtr = count; RXByteCtr = 0; ReceiveIndex = 0; TransmitIndex = 0; /* Initialize slave address and interrupts */ UCB0I2CSA = dev_addr; IFG2 &= ~(UCB0TXIFG + UCB0RXIFG); // Clear any pending interrupts IE2 &= ~UCB0RXIE; // Disable RX interrupt IE2 |= UCB0TXIE; // Enable TX interrupt UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(GIE); // Enter LPM0 w/ interrupts // __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts return MasterMode; } I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count) { /* Initialize state machine */ MasterMode = TX_REG_ADDRESS_MODE; TransmitRegAddr = reg_addr; RXByteCtr = count; TXByteCtr = 0; ReceiveIndex = 0; TransmitIndex = 0; /* Initialize slave address and interrupts */ UCB0I2CSA = dev_addr; IFG2 &= ~(UCB0TXIFG + UCB0RXIFG); // Clear any pending interrupts IE2 &= ~UCB0RXIE; // Disable RX interrupt IE2 |= UCB0TXIE; // Enable TX interrupt UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts return MasterMode; } I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count) { /* Initialize state machine */ MasterMode = TX_REG_ADDRESS_MODE; TransmitRegAddr = reg_addr; //Copy register data to TransmitBuffer CopyArray(reg_data, TransmitBuffer, count); TXByteCtr = count; RXByteCtr = 0; ReceiveIndex = 0; TransmitIndex = 0; /* Initialize slave address and interrupts */ UCB0I2CSA = dev_addr; IFG2 &= ~(UCB0TXIFG + UCB0RXIFG); // Clear any pending interrupts IE2 &= ~UCB0RXIE; // Disable RX interrupt IE2 |= UCB0TXIE; // Enable TX interrupt UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts return MasterMode; } void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count) { uint8_t copyIndex = 0; for (copyIndex = 0; copyIndex < count; copyIndex++) { dest[copyIndex] = source[copyIndex]; } } //****************************************************************************** // UART Configtion ************************************************************* //****************************************************************************** void putcUART(uint8_t data) { while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = data; } void putsUART(uint8_t *data) { while (*data) { putcUART(*data); data++; } } void initUART() { #if UART_MODE == SMCLK_11500 UCA0CTL1 |= UCSSEL_2; // SMCLK UCA0BR0 = 138; // 16MHz 115200 UCA0BR1 = 0; // 16MHz 115200 UCA0MCTL = UCBRS_7; // Modulation UCBRSx = 7 UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** IFG2 &= ~(UCA0RXIFG); IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt #elif UART_MODE == SMCLK_9600 UCA0CTL1 |= UCSSEL_2; // SMCLK UCA0BR0 = 104; // 16MHz 9600 UCA0BR1 = 0; // 16MHz 9600 UCA0MCTL = UCBRS_0 + UCOS16 + UCBRF_3; // Modulation UCBRSx = 0 UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** IFG2 &= ~(UCA0RXIFG); IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt #elif UART_MODE == ACLK_9600 UCA0CTL1 |= UCSSEL_1; // ACLK UCA0BR0 = 3; // 32768Hz 9600 UCA0BR1 = 0; // 32768Hz 9600 UCA0MCTL = UCBRS_3; // Modulation UCBRSx = 3 UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** IFG2 &= ~(UCA0RXIFG); IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt #else #error "Select UART Baud Rate of 115200 or 9600" #endif } //****************************************************************************** // Device Initialization ******************************************************* //****************************************************************************** void initClockTo16MHz() { if (CALBC1_16MHZ==0xFF) // If calibration constant erased { while(1); // do not load, trap CPU!! } DCOCTL = 0; // Select lowest DCOx and MODx settings BCSCTL1 = CALBC1_16MHZ; // Set DCO DCOCTL = CALDCO_16MHZ; } void initGPIO() { // P1DIR |= BIT0 + BIT1 + BIT2 + BIT3 + BIT4; // P1OUT &= ~(BIT0 + BIT1 + BIT2 + BIT3 + BIT4); // // P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0 // P1SEL2|= BIT6 + BIT7; // Assign I2C pins to USCI_B0 P1DIR |= BIT0;// + BIT3 + BIT4; P1OUT &= ~(BIT0);// + BIT3 + BIT4); // P1.1 = RXD, P1.2=TXD, P1.6 = SCL, P1.7 = SDA; P1SEL |= BIT1 + BIT2 + BIT6 + BIT7; // Assign I2C pins to USCI_B0 P1SEL2|= BIT1 + BIT2 + BIT6 + BIT7; // Assign I2C pins to USCI_B0 } void initI2C() { UCB0CTL1 |= UCSWRST; // Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset UCB0BR0 = 40; // fSCL = SMCLK/40 = ~400kHz UCB0BR1 = 0; UCB0I2CSA = SLAVE_ADDR; // Slave Address UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation UCB0I2CIE |= UCNACKIE; } //****************************************************************************** // Main ************************************************************************ // Send and receive three messages containing the example commands ************* //****************************************************************************** int main(void) { long i; WDTCTL = WDTPW + WDTHOLD; // Stop WDT initClockTo16MHz(); initGPIO(); initUART(); initI2C(); //putcUART('A'); //putsUART("Hello A"); I2C_Master_Write(SLAVE_ADDR, MasterType0, TYPE_0_LENGTH); I2C_Master_Write(SLAVE_ADDR, MasterType0, TYPE_0_LENGTH); I2C_Master_Write(SLAVE_ADDR, MasterType0, TYPE_0_LENGTH); //putsUART(" 1 "); I2C_Master_Write(SLAVE_ADDR, MasterType2, TYPE_1_LENGTH); // putsUART(" 2 "); I2C_Master_Read(SLAVE_ADDR, SLAVE_READ0); CopyArray(ReceiveBuffer, SlaveRead0, SLAVE_READ0); //uint8_t SlaveRead0 [SALVE_READ0] = {0}; //putsUART("\n Send Data:"); for(i=0;i<11;i++){ putcUART(ReceiveBuffer[i]); } // I2C_Master_WriteReg(SLAVE_ADDR, CMD_TYPE_0_MASTER, MasterType0, TYPE_0_LENGTH); // I2C_Master_WriteReg(SLAVE_ADDR, CMD_TYPE_1_MASTER, MasterType1, TYPE_1_LENGTH); // I2C_Master_WriteReg(SLAVE_ADDR, CMD_TYPE_2_MASTER, MasterType2, TYPE_2_LENGTH); // // I2C_Master_ReadReg(SLAVE_ADDR, CMD_TYPE_0_SLAVE, TYPE_0_LENGTH); // CopyArray(ReceiveBuffer, SlaveType0, TYPE_0_LENGTH); // // I2C_Master_ReadReg(SLAVE_ADDR, CMD_TYPE_1_SLAVE, TYPE_1_LENGTH); // CopyArray(ReceiveBuffer, SlaveType1, TYPE_1_LENGTH); // // I2C_Master_ReadReg(SLAVE_ADDR, CMD_TYPE_2_SLAVE, TYPE_2_LENGTH); // CopyArray(ReceiveBuffer, SlaveType2, TYPE_2_LENGTH); //__bis_SR_register(LPM0_bits + GIE); while(1) { //putsUART(" 1 "); I2C_Master_Write(SLAVE_ADDR, MasterType1, TYPE_1_LENGTH); // putsUART(" 2 "); I2C_Master_Read(SLAVE_ADDR, SLAVE_READ0); CopyArray(ReceiveBuffer, SlaveRead0, SLAVE_READ0); //uint8_t SlaveRead0 [SALVE_READ0] = {0}; //putsUART("\n Send Data:"); for(i=0;i<11;i++){ putcUART(ReceiveBuffer[i]); } // for(i=0;i<100000;i++){ // // } } } //****************************************************************************** // I2C Interrupt For Received and Transmitted Data****************************** //****************************************************************************** #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = USCIAB0TX_VECTOR __interrupt void USCIAB0TX_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_ISR (void) #else #error Compiler not supported! #endif { if (IFG2 & UCB0RXIFG) // Receive Data Interrupt { //Must read from UCB0RXBUF uint8_t rx_val = UCB0RXBUF; if (RXByteCtr) { ReceiveBuffer[ReceiveIndex++] = rx_val; RXByteCtr--; } if (RXByteCtr == 1) { UCB0CTL1 |= UCTXSTP+UCTXNACK; } else if (RXByteCtr == 0) { IE2 &= ~UCB0RXIE; MasterMode = IDLE_MODE; __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 } } else if (IFG2 & UCB0TXIFG) // Transmit Data Interrupt { switch (MasterMode) { case TX_REG_ADDRESS_MODE: UCB0TXBUF = TransmitRegAddr; if (RXByteCtr) MasterMode = SWITCH_TO_RX_MODE; // Need to start receiving now else MasterMode = TX_DATA_MODE; // Continue to transmision with the data in Transmit Buffer break; case SWITCH_TO_RX_MODE: IE2 |= UCB0RXIE; // Enable RX interrupt IE2 &= ~UCB0TXIE; // Disable TX interrupt UCB0CTL1 &= ~UCTR; // Switch to receiver MasterMode = RX_DATA_MODE; // State state is to receive data UCB0CTL1 |= UCTXSTT; // Send repeated start if (RXByteCtr == 1) { //Must send stop since this is the N-1 byte while((UCB0CTL1 & UCTXSTT)); UCB0CTL1 |= UCTXSTP; // Send stop condition } break; case TX_DATA_MODE: if (TXByteCtr) { UCB0TXBUF = TransmitBuffer[TransmitIndex++]; TXByteCtr--; } else { //Done with transmission UCB0CTL1 |= UCTXSTP; // Send stop condition MasterMode = IDLE_MODE; IE2 &= ~UCB0TXIE; // disable TX interrupt //__bic_SR_register_on_exit(CPUOFF); // Exit LPM0 } break; default: __no_operation(); break; } } } //****************************************************************************** // I2C Interrupt For Start, Restart, Nack, Stop ******************************** //****************************************************************************** #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = USCIAB0RX_VECTOR // USCIAB0TX_VECTOR __interrupt void USCIAB0RX_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCIAB0RX_VECTOR))) USCIAB0RX_ISR (void) #else #error Compiler not supported! #endif { if (IFG2 & UCA0RXIFG) { uint8_t rx_val = UCA0RXBUF; //Must read UCxxRXBUF to clear the flag putcUART(rx_val); } if (UCB0STAT & UCNACKIFG) { UCB0STAT &= ~UCNACKIFG; // Clear NACK Flags } if (UCB0STAT & UCSTPIFG) //Stop or NACK Interrupt { UCB0STAT &= ~(UCSTTIFG + UCSTPIFG + UCNACKIFG); //Clear START/STOP/NACK Flags } if (UCB0STAT & UCSTTIFG) { UCB0STAT &= ~(UCSTTIFG); //Clear START Flags } }
I have read your write on https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/844030/ccs-msp430i2040-emdc-i2c-communication-with-evm430-i2040s/3121142?tisearch=e2e-sitesearch&keymatch=msp430i2041%2520i2c#3121142 18/10/2019 4:32 PM. Please you can send to me project you write read data over i2c ok.
Thank so much.
This thread should contain details about making changes to use I2C.
MSP430I2040: Interfacing the MSP430i2040S Sub metering EVM on I2C
Hi James.
I write code with f5529. My project read evmi2041 (multi device) over I2C and send to PC by UART, now i have connect one device EVM, but data result not true. Please check for me
//****************************************************************************** // MSP430F552x Demo - USCI_B0, I2C Master multiple byte TX/RX // // Description: I2C master communicates to I2C slave sending and receiving // messages of different length. I2C master will enter LPM0 mode // while waiting for the messages to be sent/receiving using I2C interrupt. // ACLK = NA, MCLK = SMCLK = DCO 16MHz. // // /|\ /|\ // MSP430F5529 4.7k | // ----------------- | 4.7k // /|\ | P3.1|---+---|-- I2C Clock (UCB0SCL) // | | | | // ---|RST P3.0|-------+-- I2C Data (UCB0SDA) // | | // | P3.3|-------+-- UART TX (UCA0 TXD) // | | // | P3.4|-------+-- UART RX (UCA0 RXD) // | | // | | // // Texas Instruments Inc. // June 2019 // Built with CCS V9.x //****************************************************************************** #include <msp430.h> #include <stdint.h> #include <stdbool.h> char update; //****************************************************************************** // UART Initialization ********************************************************* //****************************************************************************** #define SMCLK_11500 0 #define SMCLK_9600 1 #define ACLK_9600 2 #define UART_MODE SMCLK_115200 const char hex_digits[] = "0123456789ABCDEF"; void initUART() { // Configure USCI_A0 for UART mode UCA0CTLW0 = UCSWRST; // Put eUSCI in reset #if UART_MODE == SMCLK_115200 UCA0CTLW0 |= UCSSEL__SMCLK; // CLK = SMCLK // Baud Rate calculation // 16000000/(16*115200) = 8.6805 // Fractional portion = 0.6805 // Use Table 24-5 in Family User Guide UCA0BR0 = 8; // 16000000/16/9600 UCA0BR1 = 0x00; UCA0MCTL |= UCOS16 | UCBRF_11 | UCBRS_0; #elif UART_MODE == SMCLK_9600 UCA0CTLW0 |= UCSSEL__SMCLK; // CLK = SMCLK // Baud Rate calculation // 16000000/(16*9600) = 104.1667 // Fractional portion = 0.1667 // Use Table 24-5 in Family User Guide UCA0BR0 = 104; // 16000000/16/9600 UCA0BR1 = 0x00; UCA0MCTL |= UCOS16 | UCBRF_3 | UCBRS_0; #elif UART_MODE == ACLK_9600 UCA0CTLW0 |= UCSSEL__ACLK; // CLK = ACLK // Baud Rate calculation // 32768/(9600) = 3.4133 // Fractional portion = 0.4133 // Use Table 24-5 in Family User Guide UCA0BR0 = 3; // 32768/9600 UCA0BR1 = 0x00; UCA0MCTL |= UCBRS_3; //0x0300 is UCBRSx = 0x03 #else # error "Please specify baud rate to 115200 or 9600" #endif UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt } //****************************************************************************** // Device Initialization ******************************************************* //****************************************************************************** void putcUART(uint8_t data) { while (!(UCA0IFG & UCTXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = data; // TX -> RXed character } void putsUART(uint8_t *data) { while (*data) { putcUART(*data); data++; } } void putHexUART(uint8_t c) { //uint8_t c; putcUART(hex_digits[c >> 4]); putcUART(hex_digits[c & 15]); } void putsHexPC(uint8_t *buff, uint8_t len) { uint8_t i; for(i=0;i<len;i++) { putHexUART(buff[i]); putcUART(' '); } } //****************************************************************************** // Example Commands ************************************************************ //****************************************************************************** #define SLAVE_ADDR 0x0A #define MAX_BUFFER_SIZE 50 // CMD 0x01 = Configure Mode #define CMD_01_MASTER 0x01 // send 2 bytes of payload #define CMD_01_LENGTH 2 // Payload[0] = 0x01: Write, [1] = 0x01: Active uint8_t MasterCMD01Payload [CMD_01_LENGTH] = { 0x01, 0x01}; #define RESPONSE_SLAVE_LENGTH 15 //****************************************************************************** // General I2C State Machine *************************************************** //****************************************************************************** typedef enum I2C_ModeEnum{ IDLE_MODE, NACK_MODE, TX_DATA_MODE, RX_DATA_MODE, TIMEOUT_MODE, ERROR_MODE } I2C_Mode; /* Used to track the state of the software state machine*/ I2C_Mode MasterMode = IDLE_MODE; /* ReceiveBuffer: Buffer used to receive data in the ISR * RXByteCtr: Number of bytes left to receive * ReceiveIndex: The index of the next byte to be received in ReceiveBuffer * TransmitBuffer: Buffer used to transmit data in the ISR * TXByteCtr: Number of bytes left to transfer * TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer * */ uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0}; uint8_t RXByteCtr = 0; uint8_t ReceiveIndex = 0; uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0}; uint8_t TXByteCtr = 0; uint8_t TransmitIndex = 0; /* I2C Write and Read Functions */ I2C_Mode I2C_Master_ReadDataBlocking(uint8_t dev_addr, uint8_t count); void CopyArray_wCRC(uint8_t *source, uint8_t *dest, uint8_t count, uint16_t *CRC); I2C_Mode I2C_Master_WriteCmdBlocking(uint8_t dev_addr, uint8_t cmd, uint8_t *payload, uint8_t count); I2C_Mode I2C_Master_ReadDataBlocking(uint8_t dev_addr, uint8_t count) { if (count > MAX_BUFFER_SIZE) { return ERROR_MODE; } /* Initialize state machine */ RXByteCtr = count; TXByteCtr = 0; ReceiveIndex = 0; TransmitIndex = 0; /* Initialize slave address and interrupts */ UCB0I2CSA = dev_addr; UCB0IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts UCB0IE |= UCRXIE; // Enable RX interrupt UCB0IE &= ~UCTXIE; // Disable TX interrupt __disable_interrupt(); MasterMode = RX_DATA_MODE; UCB0CTL1 &= ~UCTR; UCB0CTL1 |= UCTXSTT; // I2C RX, start condition while (MasterMode == RX_DATA_MODE) { __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts __disable_interrupt(); } return MasterMode; } I2C_Mode I2C_Master_Write_cmd(uint8_t dev_addr,uint8_t command) { uint16_t total_count=10; uint8_t CRC_Calc = command+4; // If size is OK, fill buffer TransmitBuffer[0] = 0x55; // header TransmitBuffer[1] = 0xAA; // header TransmitBuffer[2] = 0x07; // packet length (ID, CMD, payload, checksum) TransmitBuffer[3] = 0x04; // Design Center ID TransmitBuffer[4] = command; // command TransmitBuffer[5] = 0x00; // TransmitBuffer[6] = 0x00; // TransmitBuffer[7] = 0x00; // TransmitBuffer[8] = CRC_Calc; // CRC TransmitBuffer[9] = 0x00; // CRC putsHexPC(TransmitBuffer,total_count); TXByteCtr = total_count; RXByteCtr = 0; ReceiveIndex = 0; TransmitIndex = 0; /* Initialize slave address and interrupts */ UCB0I2CSA = dev_addr; UCB0IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts UCB0IE &= ~UCRXIE; // Disable RX interrupt UCB0IE |= UCTXIE; // Enable TX interrupt __disable_interrupt(); /* Initialize state machine */ MasterMode = TX_DATA_MODE; UCB0CTL1 |= UCTR | UCTXSTT; // I2C RX, start condition while(MasterMode == TX_DATA_MODE) { __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts __disable_interrupt(); } return MasterMode; } I2C_Mode I2C_Master_Write_Config(uint8_t dev_addr) { uint16_t total_count=9; // If size is OK, fill buffer TransmitBuffer[0] = 0x55; // header TransmitBuffer[1] = 0xAA; // header TransmitBuffer[2] = 0x06; // packet length (ID, CMD, payload, checksum) TransmitBuffer[3] = 0x04; // Design Center ID TransmitBuffer[4] = 0x01; // command TransmitBuffer[5] = 0x01; // Write TransmitBuffer[6] = 0x01; // Active TransmitBuffer[7] = 0x07; // CRC TransmitBuffer[8] = 0x00; // CRC putsHexPC(TransmitBuffer,total_count); TXByteCtr = total_count; RXByteCtr = 0; ReceiveIndex = 0; TransmitIndex = 0; /* Initialize slave address and interrupts */ UCB0I2CSA = dev_addr; UCB0IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts UCB0IE &= ~UCRXIE; // Disable RX interrupt UCB0IE |= UCTXIE; // Enable TX interrupt __disable_interrupt(); /* Initialize state machine */ MasterMode = TX_DATA_MODE; UCB0CTL1 |= UCTR | UCTXSTT; // I2C RX, start condition while(MasterMode == TX_DATA_MODE) { __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts __disable_interrupt(); } return MasterMode; } I2C_Mode I2C_Master_WriteCmdBlocking(uint8_t dev_addr, uint8_t cmd, uint8_t *payload, uint8_t count) { uint16_t total_count; uint16_t CRC_Calc = 0x00; //Total count is header (2 bytes) + length (1 byte) + DC ID (1 Byte) + CMD (1 byte) + payload (count) + checksum (2 bytes) total_count = 7 + count; if (total_count > MAX_BUFFER_SIZE) { return ERROR_MODE; } // If size is OK, fill buffer TransmitBuffer[0] = 0x55; // header TransmitBuffer[1] = 0xAA; // header TransmitBuffer[2] = count+4; // packet length (ID, CMD, payload, checksum) TransmitBuffer[3] = 0x04; // Design Center ID TransmitBuffer[4] = cmd; // command CRC_Calc = TransmitBuffer[3] + TransmitBuffer[4]; //Copy register data to TransmitBuffer CopyArray_wCRC(payload, &TransmitBuffer[5], count, &CRC_Calc); putsHexPC(TransmitBuffer,total_count); TXByteCtr = total_count; RXByteCtr = 0; ReceiveIndex = 0; TransmitIndex = 0; /* Initialize slave address and interrupts */ UCB0I2CSA = dev_addr; UCB0IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts UCB0IE &= ~UCRXIE; // Disable RX interrupt UCB0IE |= UCTXIE; // Enable TX interrupt __disable_interrupt(); /* Initialize state machine */ MasterMode = TX_DATA_MODE; UCB0CTL1 |= UCTR | UCTXSTT; // I2C RX, start condition while(MasterMode == TX_DATA_MODE) { __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts __disable_interrupt(); } return MasterMode; } void CopyArray_wCRC(uint8_t *source, uint8_t *dest, uint8_t count, uint16_t *CRC) { uint8_t copyIndex = 0; for (copyIndex = 0; copyIndex < count; copyIndex++) { dest[copyIndex] = source[copyIndex]; *CRC += source[copyIndex]; } dest[copyIndex++] = (*CRC & 0xFF); // Store LSB CRC dest[copyIndex] = (*CRC >> 8); // Store MSB CRC } //****************************************************************************** // Device Initialization ******************************************************* //****************************************************************************** void initClockTo16MHz() { UCSCTL3 |= SELREF_2; // Set DCO FLL reference = REFO UCSCTL4 |= SELA_2; // Set ACLK = REFO __bis_SR_register(SCG0); // Disable the FLL control loop UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx UCSCTL1 = DCORSEL_5; // Select DCO range 16MHz operation UCSCTL2 = FLLD_0 + 487; // Set DCO Multiplier for 16MHz // (N + 1) * FLLRef = Fdco // (487 + 1) * 32768 = 16MHz // Set FLL Div = fDCOCLK __bic_SR_register(SCG0); // Enable the FLL control loop // Worst-case settling time for the DCO when the DCO range bits have been // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx // UG for optimization. // 32 x 32 x 16 MHz / 32,768 Hz = 500000 = MCLK cycles for DCO to settle __delay_cycles(500000);// // Loop until XT1,XT2 & DCO fault flag is cleared do { UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags }while (SFRIFG1&OFIFG); // Test oscillator fault flag } uint16_t setVCoreUp(uint8_t level){ uint32_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup; //The code flow for increasing the Vcore has been altered to work around //the erratum FLASH37. //Please refer to the Errata sheet to know if a specific device is affected //DO NOT ALTER THIS FUNCTION //Open PMM registers for write access PMMCTL0_H = 0xA5; //Disable dedicated Interrupts //Backup all registers PMMRIE_backup = PMMRIE; PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE | SVSLPE | SVMHVLRIE | SVMHIE | SVSMHDLYIE | SVMLVLRIE | SVMLIE | SVSMLDLYIE ); SVSMHCTL_backup = SVSMHCTL; SVSMLCTL_backup = SVSMLCTL; //Clear flags PMMIFG = 0; //Set SVM highside to new level and check if a VCore increase is possible SVSMHCTL = SVMHE | SVSHE | (SVSMHRRL0 * level); //Wait until SVM highside is settled while((PMMIFG & SVSMHDLYIFG) == 0) { ; } //Clear flag PMMIFG &= ~SVSMHDLYIFG; //Check if a VCore increase is possible if((PMMIFG & SVMHIFG) == SVMHIFG) { //-> Vcc is too low for a Vcore increase //recover the previous settings PMMIFG &= ~SVSMHDLYIFG; SVSMHCTL = SVSMHCTL_backup; //Wait until SVM highside is settled while((PMMIFG & SVSMHDLYIFG) == 0) { ; } //Clear all Flags PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG ); //Restore PMM interrupt enable register PMMRIE = PMMRIE_backup; //Lock PMM registers for write access PMMCTL0_H = 0x00; //return: voltage not set return false; } //Set also SVS highside to new level //Vcc is high enough for a Vcore increase SVSMHCTL |= (SVSHRVL0 * level); //Wait until SVM highside is settled while((PMMIFG & SVSMHDLYIFG) == 0) { ; } //Clear flag PMMIFG &= ~SVSMHDLYIFG; //Set VCore to new level PMMCTL0_L = PMMCOREV0 * level; //Set SVM, SVS low side to new level SVSMLCTL = SVMLE | (SVSMLRRL0 * level) | SVSLE | (SVSLRVL0 * level); //Wait until SVM, SVS low side is settled while((PMMIFG & SVSMLDLYIFG) == 0) { ; } //Clear flag PMMIFG &= ~SVSMLDLYIFG; //SVS, SVM core and high side are now set to protect for the new core level //Restore Low side settings //Clear all other bits _except_ level settings SVSMLCTL &= (SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2 ); //Clear level settings in the backup register,keep all other bits SVSMLCTL_backup &= ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2); //Restore low-side SVS monitor settings SVSMLCTL |= SVSMLCTL_backup; //Restore High side settings //Clear all other bits except level settings SVSMHCTL &= (SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2 ); //Clear level settings in the backup register,keep all other bits SVSMHCTL_backup &= ~(SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2); //Restore backup SVSMHCTL |= SVSMHCTL_backup; //Wait until high side, low side settled while(((PMMIFG & SVSMLDLYIFG) == 0) && ((PMMIFG & SVSMHDLYIFG) == 0)) { ; } //Clear all Flags PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG ); //Restore PMM interrupt enable register PMMRIE = PMMRIE_backup; //Lock PMM registers for write access PMMCTL0_H = 0x00; return true; } bool increaseVCoreToLevel2() { uint8_t level = 2; uint8_t actlevel; bool status = true; //Set Mask for Max. level level &= PMMCOREV_3; //Get actual VCore actlevel = PMMCTL0 & PMMCOREV_3; //step by step increase or decrease while((level != actlevel) && (status == true)) { if(level > actlevel) { status = setVCoreUp(++actlevel); } else { status = false; } } return (status); } void initGPIO() { //LEDs P1OUT = 0x00; // P1 setup for LED & reset output P1DIR |= BIT0; P4DIR |= BIT7; P4OUT &= ~(BIT7); //I2C Pins P3SEL |= BIT0 + BIT1 + BIT3 + BIT4; // P3.0,1 option select // P3.4,5 = USCI_A0 TXD/RXD } void initGPIO_UART() { // P3SEL = BIT3 + BIT4; // P3.4,5 = USCI_A0 TXD/RXD // P5SEL |= BIT4+BIT5; // Select XT1 } void initI2C() { UCB0CTL1 |= UCSWRST; // Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset UCB0BR0 = 160; // fSCL = SMCLK/160 = ~100kHz UCB0BR1 = 0; UCB0I2CSA = SLAVE_ADDR; // Slave Address is 048h UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation UCB0IE |= UCNACKIE; } //****************************************************************************** // Main ************************************************************************ // Send and receive three messages containing the example commands ************* //****************************************************************************** int main(void) { uint8_t i,cnt; WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer increaseVCoreToLevel2(); initClockTo16MHz(); initGPIO();initGPIO_UART(); initI2C(); initUART(); putsUART("Hello "); putsUART("\nConfig: "); // __bis_SR_register(LPM0_bits + GIE); // Since SMCLK is source, enter LPM0, interrupts enabled // I2C_Master_WriteCmdBlocking(SLAVE_ADDR, CMD_01_MASTER, MasterCMD01Payload, CMD_01_LENGTH); I2C_Master_Write_Config(SLAVE_ADDR); while (1) { cnt++; if(cnt>4)cnt=0; putsUART("\nCmd Read: "); I2C_Master_Write_cmd(SLAVE_ADDR,0x80+cnt); __delay_cycles(1000000); I2C_Master_ReadDataBlocking(SLAVE_ADDR, RESPONSE_SLAVE_LENGTH); putsUART("\nData Read: "); for(i=0;i<15;i++) { putHexUART(ReceiveBuffer[i]); putcUART(' '); } // Check response in Receive buffer } } //****************************************************************************** // I2C Interrupt *************************************************************** //****************************************************************************** #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=USCI_B0_VECTOR __interrupt void USCI_B0_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void) #else #error Compiler not supported! #endif { //Must read from UCB0RXBUF uint8_t rx_val = 0; switch(__even_in_range(UCB0IV,0xC)) { case USCI_NONE:break; // Vector 0 - no interrupt case USCI_I2C_UCALIFG:break; // Interrupt Vector: I2C Mode: UCALIFG case USCI_I2C_UCNACKIFG:break; // Interrupt Vector: I2C Mode: UCNACKIFG case USCI_I2C_UCSTTIFG:break; // Interrupt Vector: I2C Mode: UCSTTIFG case USCI_I2C_UCSTPIFG:break; // Interrupt Vector: I2C Mode: UCSTPIFG case USCI_I2C_UCRXIFG: rx_val = UCB0RXBUF; if (RXByteCtr) { ReceiveBuffer[ReceiveIndex++] = rx_val; RXByteCtr--; } if (RXByteCtr == 1) { UCB0CTL1 |= UCTXSTP; } else if (RXByteCtr == 0) { UCB0IE &= ~UCRXIE; MasterMode = IDLE_MODE; update=1; __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 } break; // Interrupt Vector: I2C Mode: UCRXIFG case USCI_I2C_UCTXIFG: if (TXByteCtr) { UCB0TXBUF = TransmitBuffer[TransmitIndex++]; TXByteCtr--; } else { //Done with transmission UCB0CTL1 |= UCTXSTP; // Send stop condition MasterMode = IDLE_MODE; UCB0IE &= ~UCTXIE; // disable TX interrupt __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 } break; // Interrupt Vector: I2C Mode: UCTXIFG default: break; } } //****************************************************************************** // UART RX Interrupt *********************************************************** //****************************************************************************** #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=USCI_A0_VECTOR __interrupt void USCI_A0_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void) #else #error Compiler not supported! #endif { switch(__even_in_range(UCA0IV,4)) { case 0:break; // Vector 0 - no interrupt case 2: // Vector 2 - RXIFG while (!(UCA0IFG & UCTXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = UCA0RXBUF; // TX -> RXed character break; case 4:break; // Vector 4 - TXIFG default: break; } }
Data read result.
Are you connected to AC voltage? If you're not, that could be why the results are zero. Also, check your function in 'emDCCommandHandlers.c'. It should look something like this for VRMS. Your data read packets seem to be longer than necessary.
void CommandHandler_transmitVRMS(Packet_t *packet, uint8_t phaseID, uint8_t *vrms) { packet->length = 8; packet->payload[0] = COMMAND_HANDLER_EM_GUI_ID_BYTE; packet->payload[1] = COMMAND_HANDLER_VRMS_ID; packet->payload[2] = COMMAND_HANDLER_WRITE_CMD; packet->payload[3] = phaseID; packet->payload[4] = vrms[0]; packet->payload[5] = vrms[1]; packet->payload[6] = vrms[2]; packet->payload[7] = vrms[3]; Comm_writePacket(packet); }
I want read VRMS result, i have sent to device command of VRMS, but result i read not VRMS. In command read is 0x89. You can viewer value of command I send to device change from 0x80 - 0x84, but read result comback have command 0x89.
I thing have problem is code or connect. I have connect F5529LP 4 wire (3.3V SDA, SCL, GND). Can you help me check my code in my write 20-05-2021.
How long after write command to slave device, I can read data result. In project EVM need to use Request PIN? Do you have code example read data result from i204x over I2C. Can you send to me by reply or send to email dungnv@lctech.vn.
Thank you so much.
I'd recommend digging into the code and see why the return command is wrong. Perhaps the command that's sent from the F5529 is incorrect.
**Attention** This is a public forum