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.

MSP430F2274 and AD7190 spi miscommunication

Other Parts Discussed in Thread: MSP430F2274

Hi,

I am using a MSP430F2274 with a AD7190 24 bit ADC. In 4 wire SPI mode, with CS tied low.

I am having issues capturing the correct data when running from battery without the UIF programmer, but with programmer and no battery connected and running from CCSv4 the data is correct. The procedure is as follows:

in readData()

1. Wait for RDY line to go low
2. Write 0x58 to TXBUF and wait until clear
3. Write dummy 0xFF and read in RXBUF for first 8 bits of 24 bit reg from ADC, wait for BUFFERS to clear
4. Repeat step 3 for the rest of the 16 bits.

It appears that the second set of 8 bits is not transferred from the ADC and get all 0's.  Ex. 10001011 00000000 11101010

What effect does the mspFET430UIF have on the msp430f2274 that would cause different results? I have changed the system clock and the UCBOBR registers, but without any success. Any ideas, and suggestions would be greatly appreciated.

Thanks for you time,

Code Below:

void spiInitialize()
{
    __disable_interrupt();


     P3SEL |= 0x0E;                                                                        // P3.1,2,3 USCI_B0 option select
     UCB0CTL1 |= UCSWRST;                                                       // **Put state machine in reset**
     UCB0CTL0 |= UCCKPL + UCMSB + UCMST + UCSYNC;     //UCCKPH +   Clk-phase-sel + Clk-polarity-sel + MSB_first + Mster_mode + Sync 3-pin, 8-bit SPI master
     UCB0CTL1 |= UCSSEL_2;                                                     // SMCLK
     UCB0BR0 |= 0x00;                                                                  // LSB: SMCLK / 2
     UCB0BR1 = 0x00;                                                                   // MSB:
                       
     IE1 &= ~0x80; // disable interrupts
     IE1 &= ~0x40;

      UCB0CTL1 &= ~UCSWRST;                                               // **Initialize USCI state machine**
     IFG2 &= ~UCB0RXIFG;  

      __enable_interrupt();
}

unsigned long int readData()
{
   
    __disable_interrupt();
    value = 0;
    unsigned int waitForReset = 0;
    unsigned int updateRDY;
   
    while (P3IN&4);  //wait for DOUT/RDY to go low   

    UCB0TXBUF = 0x58;                   //write from TI, Sets comm reg to read mode and selects data reg    0x58
    while (!(IFG2 & UCB0TXIFG));
    /**WRITE TO COMM REG**/

    UCB0TXBUF = 0x00 +                   //Write Enable
                0x40 +                                //Read = 0x40, Write 0x00
                0x00 ;                                 //sets address of status reg if read is set
    while (!(IFG2 & UCB0TXIFG));      //Wait for bits to transfer
   

    updateRDY = UCB0RXBUF;
    while (!(IFG2 & UCB0TXIFG));
   
    while (!((updateRDY & BIT7) == 0))
    {
        updateRDY = UCB0RXBUF;
        while (!(IFG2 & UCB0TXIFG));
       
        UCB0TXBUF = 0x00 +                //Write Enable
                0x40 +                                  //Read = 0x40, Write 0x00
                0x00 ;                                  //sets address of status reg if read is set
    while (!(IFG2 & UCB0TXIFG));      //Wait for bits to transfer
   
    updateRDY = UCB0RXBUF;
        while (!(IFG2 & UCB0TXIFG));
    }

/*Capture sampled ADC */
    while (!(IFG2 & UCB0TXIFG));
    UCB0TXBUF = 0xFF;
    while (!(IFG2 & UCB0RXIFG));
    value = UCB0RXBUF;
    value =  value << 16;
   
    while (!(IFG2 & UCB0TXIFG));
    UCB0TXBUF = 0xFF;
    while (!(IFG2 & UCB0RXIFG));
    value2 = UCB0RXBUF;                                //Seems to miss this value when running on battery
    value |= value2 << 8;
   
    while (!(IFG2 & UCB0TXIFG));
    UCB0TXBUF = 0xFF;
    while (!(IFG2 & UCB0RXIFG));
    value3 = UCB0RXBUF;
    value = value + value3;

/*End sample capture*/

/*Validate data channel*/
    UCB0TXBUF = 0x00 +                //Write Enable
                0x40 +                             //Read = 0x40, Write 0x00
                0x00 ;                              //sets address of status reg if read is set
    while (!(IFG2 & UCB0TXIFG));    //Wait for bits to transfer
   
    while (!(IFG2 & UCB0TXIFG));
    UCB0TXBUF = 0xFF;
    while (!(IFG2 & UCB0RXIFG));
    updateRDY = UCB0RXBUF;
   
    if(!(updateRDY & 0x07) == 0x01)   
    {
        spiInitialize();
    }
   
        __enable_interrupt();
        return value;
}

  • If the program works as expected with FET but not without FET, I suspect a hardware problem rather than a software problem. First guess was a missing GND connection between the battery and the voltage you're measuring. But then, you are getting something from the ADC, and not knowing what you expect, I have to believe that the result is only partially wrong. With a missing GND, it would be completely wrong.

    So another try:

    cody lohse said:
    UCB0BR0 |= 0x00;                                                                  // LSB: SMCLK / 2

    Well, that's wrong. First, the maximum clock is BRCLK, not BRCLK/2 (which it was on the old USART modules). So you're running the SPI on SMCLK/1 and not SMCLK/2.
    And second, you shouldn't use 0. Use 1 instead. Or 2 for BRCLK/2.

    So you're clocking the SPI with full SMCLK speed which might be too fast for the slave.

    So why does it work with the FET but not without? What is the supply voltage from the FET and what is the battery voltage? It is possible that the battery voltage is lower and then the slave fails to work porperly at this high speed.

    That's just a possible explanation in case that the supply voltages are indeed different. If not, the speed probably is not the reason.

**Attention** This is a public forum