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.

CCS/MSP430FR6989: I2C Scanner not working as expected

Part Number: MSP430FR6989

Tool/software: Code Composer Studio

I was using the following program as i2c scanner, but the problem is that when I connect a device via i2c, the program detects it every 3 iterations but not in everyone; while a friend of mine is running the same code and it detects it every single one of them. Could it be a CCS problem? Any idea of what could be happening?

#include <msp430.h>
#include <msp430fr6989.h>
#include "utils.h"
#include "uart.h"
#include "pins.h"
#include "driverlib/driverlib.h"
#include <stdint.h>
#include <stdio.h>

int main(void){
    char buff[100];

    WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

    // Configure clock
    CSCTL0 = 0xA500; // "Password" to access clock calibration registers
    CSCTL1 = DCOFSEL_0 | DCORSEL; // Frequency of the main DCOCLK clock 8 MHz
    CSCTL2 = SELS_3 |  SELA_1;//DCOCLK as input CLK for SMCLK
    CSCTL3 = 0x0000; // No prescalers

    //Set UART and I2C pins
    GPIO_setAsPeripheralModuleFunctionInputPin(OV_SDA, GPIO_SECONDARY_MODULE_FUNCTION);
    GPIO_setAsPeripheralModuleFunctionInputPin(OV_SCL, GPIO_SECONDARY_MODULE_FUNCTION);
    GPIO_setAsPeripheralModuleFunctionInputPin(UART_RX,GPIO_PRIMARY_MODULE_FUNCTION);
    GPIO_setAsPeripheralModuleFunctionInputPin(UART_TX,GPIO_PRIMARY_MODULE_FUNCTION);
    PMM_unlockLPM5();


    // UART configuration
    unsigned long divider =(1000000U <<4)/9600; //Do the division and with decimals (that's why we shift left)
    unsigned long mod = divider&0xFFF0; // UCBRFx = INT([(N/16) -INT(N/16)] - 16) (you can check that the operation in the code corresponds to the bit stuff
    divider>>=8; // remove decimals
    UCA0CTLW0 = UCSWRST; // Put UART into SoftWare ReSeT
    UCA0CTLW0 = UCA0CTLW0 | UCSSEL_2; // Specifies clock source for UART // aclk
    UCA0BR0 = divider;
    UCA0BR1 = divider>>8;
    UCA0MCTLW = (unsigned char)( UCOS16 ) | mod; //use oversampling (divider > 16)
    UCA0CTLW0 = UCA0CTLW0 & (~UCSWRST); // Takes UART out of SoftWare ReSeT

    puts_uart0("Start!\r\n");

    // i2c configuration
    EUSCI_B_I2C_initMasterParam i2cConf = {0};
    i2cConf.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
    i2cConf.i2cClk= CS_getSMCLK();
    i2cConf.dataRate=EUSCI_B_I2C_SET_DATA_RATE_400KBPS;
    i2cConf.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
    EUSCI_B_I2C_initMaster(EUSCI_B1_BASE, &i2cConf);
    EUSCI_B_I2C_enable(EUSCI_B1_BASE);

    uint8_t addr=0;
    while(1){
        EUSCI_B_I2C_setSlaveAddress(EUSCI_B1_BASE, addr);
        EUSCI_B_I2C_setMode(EUSCI_B1_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
        if(EUSCI_B_I2C_masterSendSingleByteWithTimeout(EUSCI_B1_BASE, 0x00, 10)){
            sprintf(buff, "DEV FOUND AT 0x%02X\r\n",addr);
            puts_uart0(buff);
        };
        addr++;
        if(addr==0x8F){
            addr=0;
            puts_uart0("Round complete!\r\n");
        }
        __delay_cycles(100);
    }
}

  • Juan,

    Could you please give a little more detail about your test setup in regards to what hardware you are using? If your friend has a working hardware and software setup I would try interchanging different parts of your setups until you are able to isolate what the culprit is.


    Best regards,

    Matt
  • Hello Matt,

    thanks for your answer. I just realized that the problem was related with the "I2C" slave, that was not I2C at all, and that was the problem. The master was waiting for an ACK from the slave to set UCTXIFG to high and transmit the next byte, but the slave was running SCCB. Despite the similarities this other protocol uses the 9th bit as a don't care and not as an ACK, causing the program to get stuck at this line:

    //Poll for transmit interrupt flag.
    while (!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)) ;

    Do you think it is possible to modify driverlib so that the master ignores this ACKs?

    Thanks and best,

    Juan.

  • Juan,

    You have access to modify the driverlib code in any way you see fit. You can comment out or modify the part of the I2C driverlib implementation that acknowledges the ACK response coming from the slave

    Best regards,

    Matt

**Attention** This is a public forum