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.
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); } }
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.
**Attention** This is a public forum