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.

Question of interface to a SSI / SPI ADC question

Hi All,

I'm pretty new at the LM chips, and I am trying to get the LM4F232H5QD to interface to a SPI ADC. I've been through many of the examples and by scoping my SSICk output, I can see the 16 pulses when I transmit something. And I'm trying to send data from LM chip to ADC (the input in AD7887 datasheet). The data I input are eight '0', and the data will send into ADC by CLK. However, when I use oscilloscope to see the Tx waveform, I can't see the eight '0'. The Tx waveform is no rules. I don't know if I may have something configured wrong?

The ADC i'm using is AD7887 datasheet available at 

http://www.analog.com/static/imported-files/data_sheets/AD7887.pdf

This is the code i'm using

Code:

int main(void)
{
unsigned long ulDataTx[NUM_SSI_DATA]=0;
unsigned long ulDataRx[NUM_SSI_DATA];
unsigned long ulindex;
unsigned long i;
tContext sContext;
char cText[16];

SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);

// display in LCD
CFAL96x64x16Init();
GrContextInit(&sContext, &g_sCFAL96x64x16);
GrContextForegroundSet(&sContext, ClrWhite);
GrContextFontSet(&sContext, &g_sFontFixed6x8);

GrStringDraw(&sContext,"SSI3 ->", -1,1, 5, 0);
GrStringDraw(&sContext,"Mode: SPI", -1,1, 15, 0);
GrStringDraw(&sContext,"Data: 16-bit", -1,1, 25, 0);

// show the initial data (16 bits)

for(i=0;i<NUM_SSI_DATA;i++)
{
usprintf(cText, "%d ", ulDataRx[i]);   //show output
GrStringDraw(&sContext, cText, -1,i*5, 40, 1);
}

SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI3);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH);

// Configure the pin muxing for SSI3 functions on port H
GPIOPinConfigure(GPIO_PH0_SSI3CLK);
GPIOPinConfigure(GPIO_PH2_SSI3RX);
GPIOPinConfigure(GPIO_PH3_SSI3TX);
GPIOPinTypeGPIOOutput(GPIO_PORTH_BASE, GPIO_PIN_1);//sherry

GPIOPinTypeSSI(GPIO_PORTH_BASE, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3); //sherry GPIO_PIN_1 |
GPIOPinWrite(GPIO_PORTH_BASE,GPIO_PIN_1,GPIO_PIN_1); //禁用功能,禁用片選FLASH,向指定腳寫入值

SSIClockSourceSet(SSI3_BASE,SSI_CLOCK_SYSTEM);
SSIConfigSetExpClk(SSI3_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,
SSI_MODE_MASTER, 2000000, 16); //2MHz,16bits

SSIEnable(SSI3_BASE);

//GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_1,GPIO_PIN_1);

//
// Read any residual data from the SSI port. This makes sure the receive
// FIFOs are empty, so we don't read any unwanted junk. This is done here
// because the SPI SSI mode is full-duplex, which allows you to send and
// receive at the same time. The SSIDataGetNonBlocking function returns
// "true" when data was returned, and "false" when no data was returned.
// The "non-blocking" function checks if there is any data in the receive
// FIFO and does not "hang" if there isn't.

while(1)

{
unsigned long get_data;
GPIOPinWrite(GPIO_PORTH_BASE,GPIO_PIN_1,0); //ENABLE ADC
SSIDataPut(SSI3_BASE,0x00);
SSIDataGet(SSI3_BASE,&get_data);
//send_byte(0x00);
//SSIDataPut(SSI3_BASE, 0x00); //PUT OUT RANDOM DATA
while((1 == HWREGBITW(GPIO_PORTH_BASE + SSI_O_SR,4))); //WAIT FOR SSI TO BE IDLE
GPIOPinWrite(GPIO_PORTH_BASE,GPIO_PIN_1,GPIO_PIN_1); //DISABLE ADC

for(i=0;i<NUM_SSI_DATA;i++)
{
SSIDataPut(SSI3_BASE,0xFF);
SSIDataGet(SSI3_BASE,&get_data);
ulDataRx[i] = get_data;
usprintf(cText, "%d ", ulDataRx[i]);//show output
GrStringDraw(&sContext, cText, -1,i*5, 50, 1);

}

}

// Determine if the SSI is busy.

return((HWREG(SSI3_BASE + SSI_O_SR) & SSI_SR_BSY) ? true : false);
}


Any help would be greatly appreciated!

-Unis

  • Hi,

    First I don't know why - maybe you can explain - you decided to use an external 2 channel 12 bits ADC and don't use the micocontroller's internal ADC - has also 12 bits (and a maximum 24 channels).

    Second, related to your code: you must read carefully the data sheet - page 10, Table 5 and 6 - from that table results you must always send 0x0100 - 16 bits, not 0x00, not 0xFF which is really 0x00FF - first byte is the command one, must have the last bit set to 1 to activate the ADC and the second one is dummy (don't care). 0x00 as command byte stops the ADC. Also, don't use external GPIO pin to generate SSIFSS, configure and use internal SSIFSS, since you have only one word to transfer.

    Petrei 

    EDIT: Yes you can use 0x00FF, but send it as a single word, not as two separate bytes. But at lest for the beginning start with 0x01FF. One single command is enough.

  • Poster/asset Petrei makes his normal - thoughtful points. 

    Quick scan of your code reveals: "GPIOPinConfigure()" for all but SSIF pin.  As Petrei suggests - this should be added.

    Note further no use of: "GPIOPinTypeSSI()."   We've always used "both" PinConfigure & PinType in setting up our SSI.  (PinType can operate on multiple bits, PinConfigure upon only one bit at a time.)

    Such code dumps as you/other provide - with no description of your logical framework or design - tend to "overwhelm" would-be helpers - who may not have the time/energy to "dig" for such guidance.  A written plan - before one starts writing code - most always yields both faster and improved results...