52210DEMO and MMA745xL QSPI Problem

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

52210DEMO and MMA745xL QSPI Problem

2,785 Views
PhilipAsare
Contributor I

Hi,

 

I'm trying to interface the 52210DEMO board with the MMA745xL accelerometer through SPI. I'm trying to read the acceleration values, but it doesn't seem to work right. I've never done this before so there's definitely a chance I'm doing something wrong.

 

Please help

 

Here's the code I'm using:

 

 

#include "support_common.h" /* include peripheral declarations and more */
#if (CONSOLE_IO_SUPPORT || ENABLE_UART_SUPPORT)
/* Standard IO is only possible if Console or UART support is enabled. */
#include <stdio.h>
#endif

/* Initialize SPI module on system */

void spi_init(void)
{
 MCF_QSPI_QMR = 0 |
     MCF_QSPI_QMR_MSTR |   //SPI Mater Mode
     MCF_QSPI_QMR_BAUD(0x0a) | //Baud of 4MHz
     MCF_QSPI_QMR_BITS(0x08); //8 bit data transfer
    
    
 /* set direction of QSPI pins _CLK, _DOUT _CS0 as outputs and _DIN as input */
 MCF_GPIO_DDRQS = 0 |MCF_GPIO_PORTQS_PORTQS0 |MCF_GPIO_PORTQS_PORTQS2 |MCF_GPIO_PORTQS_PORTQS3;

 /* set peripheral access control register to allow read/write access to QPSI module */
 MCF_SCM_PACR4 |= MCF_SCM_PACR_ACCESS_CTRL1(0x04);

 /* set all delays to default and make sure QSPI module is disabled */
 MCF_QSPI_QDLYR = 0;   
 MCF_QSPI_QIR = 0xd00f; //set errors
 printf("QSPI initiated\n");
}


void spi_transfer(void)
{

 #define SPI_READ(reg) (((reg) &0x7F)<<1)
 #define SPI_WRITE(reg) ((((reg) &0x3F)<<1)|0x80)

 int i=0;
 MCF_QSPI_QAR = 0 |MCF_QSPI_QAR_ADDR(0x20);
 for(i=0;i<5;i++)
 {
 /* set command ram for active low and chip select 0 */
  MCF_QSPI_QDR = 0 | MCF_QSPI_QDR_BITSE | MCF_QSPI_QDR_QSPI_CS0;
 }

 MCF_QSPI_QAR = 0 |MCF_QSPI_QAR_ADDR(0x00);

 /* write transmit RAM of QDR */
 MCF_QSPI_QDR = MCF_QSPI_QDR_DATA(SPI_WRITE(0x16)); //send write request register $16
 MCF_QSPI_QDR = MCF_QSPI_QDR_DATA(0x05); //send 0x05 as data to register $16
 MCF_QSPI_QDR = MCF_QSPI_QDR_DATA(SPI_READ(0x06)); //read data from register $06
 MCF_QSPI_QDR = MCF_QSPI_QDR_DATA(SPI_READ(0x07)); //read data from register $07
 MCF_QSPI_QDR = MCF_QSPI_QDR_DATA(SPI_READ(0x08)); //read data from register $08
 MCF_QSPI_QWR = 0x1400; //set begin and end point of transmt RAM
 MCF_QSPI_QDLYR = 0 | MCF_QSPI_QDLYR_SPE; //initiate transfer
 printf("Initiating Trasnfer\n");
 while (!(MCF_QSPI_QIR & MCF_QSPI_QIR_SPIF)) //wait for tranfer to finish
 {
 
 }
 printf("Transfer Complete\n");
 MCF_QSPI_QIR |= MCF_QSPI_QIR_SPIF; //clear SPIF flag
 MCF_QSPI_QAR = 0 |MCF_QSPI_QAR_ADDR(0x10); // set QAR register to Receive RAM
}

int main(void)
{
vuint16 accX;
vuint16 accY;
vuint16 accZ;
spi_init();


 while( 1 )
 {
        // spin forever
        spi_transfer();
        accX = MCF_QSPI_QDR; //read X value
        accY = MCF_QSPI_QDR; //read Y value
        accZ = MCF_QSPI_QDR; //read Z value
        printf("Ax = %d | Ay = %d | Az = %d\n", accX, accY, accZ);
 }
}

Labels (1)
0 Kudos
10 Replies

651 Views
RichTestardi
Senior Contributor II

Do you have a scope or logic analyzer you can use on the qspi pins?  That makes all the difference, I think.

 

The intrinsic chip select logic is definitely complicated.  I recently changed my code to just use a gpio pin for chip select just to make the code simpler (and more portable)...  My old (complicated) code is attached if it helps to have another example...  My new (simpler) code is in the skeleton.zip archive at the bottom of this page: http://www.cpustick.com/downloads.htm

 

The other thing you can do to get a feel for if your code and hardware are basically working is disconnect the peripheral and use a pull-up and then pull-down resistor on the qspi_din pin, and make sure you're reading back both all 1's and then all 0's, respectively, in those cases.

 

-- Rich

0 Kudos

651 Views
PhilipAsare
Contributor I

Hi Rich.

 

I think I found the/one problem. I tried using the code below to debug my program, and it turns out the for some reason, the device is not writing anything the the QSPI RAM. Could you check it out yourself and let me know if this is the case? When I try reading what is in the transmit RAM, I get zero everytime even though other values were supposed to be written to it.

 

Here's the code:

 

 

/* * main implementation: use this sample to create your own application * */#include "support_common.h" /* include peripheral declarations and more */#if (CONSOLE_IO_SUPPORT || ENABLE_UART_SUPPORT) /* Standard IO is only possible if Console or UART support is enabled. */#include <stdio.h>#endif#define RAMlength 4#include <assert.h>int main(void){int16 i = 0;uint16 qmr;uint16 qdr;uint16 qar;uint16 qwr;uint16 tx[RAMlength];uint16 Xdata;uint16 Zdata;MCF_GPIO_DDRAN = 0xff; // set PORTAN as output portMCF_GPIO_PORTAN = 0x00; // set all values to zero (activate CS)MCF_GPIO_PQSPAR = 0x0015; // set PORTQS to primary function/* set peripheral access control register to allow read/write access to QPSI module */MCF_SCM_PACR4 = 0 | 0x04;// set QMRMCF_QSPI_QMR = 0    | MCF_QSPI_QMR_MSTR //set master mode    | MCF_QSPI_QMR_BITS(0x08) //8-bit data transfer    | MCF_QSPI_QMR_CPHA    | MCF_QSPI_QMR_BAUD(0x10); // _CLK = 2.5MHzqmr = MCF_QSPI_QMR;printf("QMR = %d\n", qmr);// set QDLYR    MCF_QSPI_QDLYR = 0; // default delays // set QIRMCF_QSPI_QIR = 0xd00f;// set Command RAMprintf("Setting Command RAM\n");MCF_QSPI_QAR = MCF_QSPI_QAR_CMD;for(i=0; i<RAMlength; i++){  qar = MCF_QSPI_QAR; printf("Current QAR = %d\n", qar); MCF_QSPI_QDR = 0; //qdr = MCF_QSPI_QDR; //printf("Current QDR = %d\n", qdr);}// set Command RAMprintf("Reading Command RAM\n");MCF_QSPI_QAR = MCF_QSPI_QAR_CMD;for(i=0; i<RAMlength; i++){  qar = MCF_QSPI_QAR; printf("Current QAR = %d\n", qar); qdr = MCF_QSPI_QDR; printf("Current QDR = %d\n", qdr);}// set Transmit RAMprintf("Setting Transmit RAM\n");tx[0] = 0x80 | (0x16<<1); //write $16tx[1] = 0x05;     //set to 4 wire modetx[2] = 0 | (0x06<<1);   //read $06tx[3] = 0 | (0x08<<1);   //read $08MCF_QSPI_QAR = MCF_QSPI_QAR_TRANS;for(i=0; i<RAMlength; i++){  qar = MCF_QSPI_QAR; printf("Current QAR = %d\n", qar); MCF_QSPI_QDR = tx[i]; //qdr = MCF_QSPI_QDR; //printf("Current QDR = %d\n", qdr);}// read Transmit RAMprintf("Reading Transmit RAM\n");MCF_QSPI_QAR = MCF_QSPI_QAR_TRANS;for(i=0; i<RAMlength; i++){  qar = MCF_QSPI_QAR; printf("Current QAR = %d\n", qar); qdr = MCF_QSPI_QDR; printf("Current QDR = %d\n", qdr);}// set QWRMCF_QSPI_QWR = 0    | MCF_QSPI_QWR_NEWQP(0) //start execution at 0    | MCF_QSPI_QWR_ENDQP(0x3); //end at point 3qwr = MCF_QSPI_QWR;printf("QWR = %d\n", qwr);MCF_GPIO_PORTAN = 0x02;// initiate transferMCF_QSPI_QDLYR = MCF_QSPI_QDLYR_SPE;// wait for transfers to completeassert(! (MCF_QSPI_QIR & MCF_QSPI_QIR_SPIF));while (! (MCF_QSPI_QIR & MCF_QSPI_QIR_SPIF)) {        }MCF_QSPI_QIR = MCF_QSPI_QIR_SPIF;assert((MCF_QSPI_QWR & 0xf0) >> 4 == RAMlength-1);assert(! (MCF_QSPI_QDLYR & MCF_QSPI_QDLYR_SPE));        // read dataprintf("Receiving Data\n");MCF_QSPI_QAR = MCF_QSPI_QAR_RECV;qar = MCF_QSPI_QAR;printf("Current QAR = %d\n", qar);Xdata = MCF_QSPI_QDR;//MCF_QSPI_QAR = MCF_QSPI_QAR_RECV+1;qar = MCF_QSPI_QAR;printf("Current QAR = %d\n", qar);Zdata = MCF_QSPI_QDR;printf("Ax = %d | Az = %d\n", Xdata, Zdata);MCF_GPIO_PORTAN = 0x00; }

 

I'll know for sure if the hardware (the QSPI ports) are working once I can be sure that it is executing the instructions.

 

Let me know if you run into the same problem.

 

Thanks,

 

Philip

 

0 Kudos

651 Views
RichTestardi
Senior Contributor II

Hi Philip,

 

I don't have that reference manual downloaded, but for the other ColdFire V2 cores I have, it says something like:

 

  The transmit and command RAM are user write-only. The receive RAM is user read-only. Figure 22-10

  shows the RAM configuration. The RAM contents are undefined immediately after a reset.

 

So I would not expect that to work (I think I even remember trying it once...) -- is your reference manual the same?

 

If you're not using CONT on your commands, are you sure your chip select is doing what you want?

 

-- Rich

 

0 Kudos

651 Views
RichTestardi
Senior Contributor II

And my reference manual gets even more explicit further down:

 

  The user cannot read data in the transmit RAM.

0 Kudos

651 Views
PhilipAsare
Contributor I
I read the manual a couple of times, but I don't know how I overlooked that. Well it looks like I'll have to try the resistors since I won't be able to head into the lab till Wednesday.
0 Kudos

651 Views
RichTestardi
Senior Contributor II
And don't forget to double check CONT in your commands -- I think you want that...
0 Kudos

651 Views
PhilipAsare
Contributor I

re:CONT. I'm using a GPIO port as the Chip Select so I'm not worrying too much about the command RAM.

 

I just tried the pull-up and pull-down resistor method. It works. I'm thinking something is not going right with the MMA745xL then. I'll play around with it some more. For now, I'm reducing the BAUD rate.

 

 

0 Kudos

651 Views
RichTestardi
Senior Contributor II
Oh, good choice!  (I finally did that and life is much simpler.)
0 Kudos

651 Views
PhilipAsare
Contributor I

Hi Rich,

 

Thanks for your reply. I'm working from home this weekend and don't access to a scope or analyzer. I also haven't had a chance to try the pull-up/pull-down resistors. I was wondering, however, how to use your code in the skeleton.zip file. I don't have the "byte" type and some of the other things defined in your files but I do want to take advantage of your qspi functions. Should I just copy them and modify them for my situation? Or should I wait and try the scope and resistors.

 

One thing I did notice though was that I wasn't incrementing the QAR after writing to the QDR. The RM said that it incremented automatically, but from your code, I see I have to do it myself.

 

Also, did you see anything in particular wrong with the code I posted originally?

 

Thanks,

 

Philip

0 Kudos

651 Views
RichTestardi
Senior Contributor II

Hi Philip,

 

Unfortunately, I did not see anything obviously wrong with your code.  But my experience has been even the subtle errors become immediately obvious on the scope, so I always start there.

 

I'm not claiming my code is the simplest possible re: QAR, but it definitely works for lots of different SPI peripherals.  The other thing that will become more obvious with the scope is if you have to set things like CPHA or CPOL differently from their default values -- those depend entirely on the peripheral you choose.

 

As for types like "byte" in my code, you can find them all, I believe, in main.h.  You can actually compile the code for 52221 (or any of the ColdFire V2 ports) and then use Code Warrior's "Go to ... declaration of ..." menu item to find how they are all defined.  "byte", in particular, is typedef'd to "unsigned char".

 

Note that my new code uses gpio-based chip selects -- this is where the scope is particularly useful...  Some peripherals (such as SPI based SD cards, for example) require chip selects to span what the QSPI peripheral sees as more than a single transaction.

 

-- Rich

 

 

0 Kudos