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.

Cannot read sampled data from ADS7844

Other Parts Discussed in Thread: ADS7844, LM3S6965, LM3S3748

Hi all

I Am using ADS7844 spi ADC with LM3s6965 but i am not getting proper converted data on spi receive fifo of stellaris.

I m giving analog i/p to channel _0.

ssiclk is 2mhz 

crystal clk is 16mhz.

API used is

SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,
                       SSI_MODE_MASTER, 4000000, 8);

 

ulDataTx[0] = 0x87

in while loop

 while(1)
    {

        SSIDataPut(SSI0_BASE, ulDataTx[0]);

        SSIDataGetNonBlocking(SSI0_BASE, &ulDataRx[0]);

         SSIDataGetNonBlocking(SSI0_BASE, &ulDataRx[1]);

    }

Delay is not given as data sheet says that no clk delay is required between tx and rx.

clk. Initialisation is done as per spi master sample code.

can u pls tell me where im going wrong.

thank u

 

 

  • Pramod,

    The code you've pasted is missing a lot of initialization for the Stellaris SSI peripheral. I'm sure there is more code not shown here, but you need to go back and make sure the rest of the initialization code is in place. You mention that clk initialization is done "as per spi master sample code" but it would be useful to see to make sure you're doing what you think you're doing. You can look at some of the example code I've posted in our design notes section for the LM3S3748 to get more guidelines for getting everything set-up, in addition to uDMA peripherals to streamline data acquisition.

    You should explicitly set the system clock somewhere in the code, in my examples it looks like the snippet below. I'm using an 8 MHz crystal and setting the system clock to 50 MHz.

    SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ);

    After that you need to initialize all of the relevant components for the SSI peripheral you wish to use. In my examples this is all done in the "enableSSI();" function. Since I always use SSI0 for the examples, the function takes no parameters. This function begins clocking the SSI0 peripheral, enables the peripheral, and configures the associated GPIOs for SSI functionality. Additionally I increase the drive strength of the pins to 8 mA.

        // Enable SSI peripheral Clock, must be enabled for use
        SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
       
        // Enables appropriate pins for SSI peripheral
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        GPIOPinConfigure(GPIO_PA2_SSI0CLK);
        GPIOPinConfigure(GPIO_PA3_SSI0FSS);
        GPIOPinConfigure(GPIO_PA4_SSI0RX);
        GPIOPinConfigure(GPIO_PA5_SSI0TX);
        GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2);
       
        GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 |  GPIO_PIN_5, GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD);
       
        // Check SSE Bit in SSICR1 Reg, make sure it is disabled
        HWREG(SSI0_BASE + SSI_O_CR1) &= ~(SSI_CR1_SSE);  

    Once that is completed you may configure the SSI peripheral, as shown in your code snippet with the SSIConfigSetExpClk function. The examples I've written do more or less the same thing in the function "configSSI();" the source for that function is shown below, in case you wish to implement a direct register access model instead of using StellarisWare.

        // Configure SSI for Master Mode Operation
        HWREG(SSI0_BASE + SSI_O_CR1) = ulSSI_MODE;
        // Configure SSI CPSDVSR
        HWREG(SSI0_BASE + SSI_O_CPSR) = ulCPSR;
        // Configure SSI SCR Field in SSICR0 Reg
        HWREG(SSI0_BASE + SSI_O_CR0) = ( (ulSCR << 8) | (ulSSIPh << 7) | (ulSSIPo << 6) | (ulProtocol << 4) | (ulFrameWidth) );
       
        // Initialize the SSI Peripheral
        HWREG(SSI0_BASE + SSI_O_CR1) |= SSI_CR1_SSE;

     

    Once all the initialization is done you may begin reading/writing to the peripheral. If you want to show the rest of your code here I'll take a look at it. You mention that it's not converting properly, but what does that mean? What conversion results are you seeing? Can you describe your hardware connections? Are you monitoring the BUSY signal?

    The mode you are in is a bidirectional interface, but you can't just read from the peripheral and get data every time. You need to do a dummy write since you are the master and arbitrate the bus for data to be latched into the RX FIFO. So the code inside your while loop should loop more like the snippet below. Also, make sure you've cleared out the contents of the SSI RX FIFO before you begin reading data, as there may be non-valid data in the register.

     while(1)
        {

            SSIDataPut(SSI0_BASE, ulDataTx[0]);

    SSIDataPut(SSI0_BASE, 0x00); // Dummy Write, second set of 8 CLKs in figure 3

    SSIDataPut(SSI0_BASE, 0x00); // Dummy Write, third set of 8 CLKs in figure 3

    // The RX FIFO is 8 positions deep, plenty to collect our data after we've written dummy writes

    SSIDataGetNonBlocking(SSI0_BASE, &ulDataRx[0]); // Read data out of the FIFO, this is not valid conversion data per figure 3 of the ADS7844 datasheet

             SSIDataGetNonBlocking(SSI0_BASE, &ulDataRx[1]);  // Read the top few bits

    SSIDataGetNonBlocking(SSI0_BASE, &ulDataRx[2]); // Read the bottom few bits, keep in mind the zero fill at the end

        }

    Additionally though it would be helpful to see what's actually happening on the peripheral. So if you could get some scope captures of communicating with the device that would be great.