Shop OBEX P1 Docs P2 Docs Learn Events
C learning SPI example with MMA7455 only gives values with all bits set?? — Parallax Forums

C learning SPI example with MMA7455 only gives values with all bits set??

twm47099twm47099 Posts: 867
edited 2014-10-07 19:47 in Learn with BlocklyProp
Today,
I tried duplicating the SPI Example using the spiasm library (other thread), It seemed to work, but I only printed values of 3,7,15, 31, 63.127 and -1. so i tried running the unmodified Learn SPI Example. (from the Learn, Examples, Protocols folder. It gave the same results. (the example says that the result should be z = 64 when the board is set flat and -64 when inverted. My results were 127 when flat and =-1 when inverted. When printing in binary format it was clear that no bits in the number (except leading bits were zero.

This is the first time using the MAA7455 so , I'm not sure if it is working correctly.

I also tried reading the x and y axies, they gave the same type of results.

thanks
tom

See the code below (C Learning example code).
/*   MMA7455 Test Z Axis with SPI.c
   
   Demonstrates using SPI communication to configure and then monitor a 
   Parallax MMA7455 3-Axis Accelerometer Module.
 

   http://learn.parallax.com/propeller-c-simple-protocols/spi-example
 */
 

 #include "simpletools.h"                          // Include simpletools lib
 

 signed char z;                                    // Z-axis value
 

 int main()                                        // Main function
 {
   high(6);                                        // CS line high (inactive)
   low(8);                                         // CLK line low
   low(6);                                         // CS -> low start SPI
 

   shift_out(7, 8, MSBFIRST, 7, 0b1010110);        // Write MCTL register
   shift_out(7, 8, MSBFIRST, 1, 0b0);              // Send don't-care bit
   shift_out(7, 8, MSBFIRST, 8, 0b01100101);       // Value for MCTL register
 pause(5);
 

   high(6);                                        // CS -> high stop SPI
   pause(1);
 

   while(1)                                        // Main loop
   {
     low(6);                                       // CS low selects chip
     shift_out(7, 8, MSBFIRST, 7, 0b0001000);      // Send read register address
     shift_out(7, 8, MSBFIRST, 1, 0b0);            // Send don't-care value
 

     z = shift_in(7, 8, MSBPRE, 8);                // Get value from register
   pause(5);
     high(6);                                      // De-select chip
     print("%c z = %b%c", HOME, z, CLREOL);        // Display measurement
     pause(500);                                   // Wait 0.5 s before repeat
   }
 }



Comments

  • twm47099twm47099 Posts: 867
    edited 2014-10-05 21:06
    I also tried the Spin demo program on the product page. I got the same result. The value returned is the correct high bit, but then all subsequent bits are ones. So the value that should be 64 (ob1000000) is actually 0b1111111 (decimal 127).

    Tom
  • edited 2014-10-06 10:21
    Since known good code examples are not working, check wiring. Careful too, different code examples may be using different I/O pins.
  • twm47099twm47099 Posts: 867
    edited 2014-10-06 11:55
    Since known good code examples are not working, check wiring. Careful too, different code examples may be using different I/O pins.

    I did check and second time through I changed my wiring to match the pin numbers in each code example. (First time through I changed pin numbers in code to match my wiring.)

    I got the same results. The strange thing is that the leading binary digits are correct, but after the highest bit that is "1" all of the lower order bits are also 1 as opposed to mix of 1's and 0's. So 64 shows up as 127, -64 shows up as -1 (all bits set), etc.

    I can't find anything in the data sheets that say the device has a mode that would do that, and I can't visualize a mis-wiring that would give those results (correct except all lower order bits set.) So I'm wondering if the part might be defective?

    Thanks
    Tom
  • edited 2014-10-06 13:10
    Is this with the Spin or simpletools example? There was a simpletools bug reported a while back that might account for that type of behavior. It was fixed, but I'm not sure if it has been posted yet. Here is a link to the latest: https://propsideworkspace.googlecode.com/archive/d213cf6924e3dacc67b7f98007d9b960d837eca8.zip

    Andy
  • twm47099twm47099 Posts: 867
    edited 2014-10-06 14:47
    Is this with the Spin or simpletools example? There was a simpletools bug reported a while back that might account for that type of behavior. It was fixed, but I'm not sure if it has been posted yet. Here is a link to the latest: https://propsideworkspace.googlecode.com/archive/d213cf6924e3dacc67b7f98007d9b960d837eca8.zip

    Andy

    Andy,
    I got the same results with all three methods: the Spin example on the product page, the C program in the tutorial, and my spiasm library.

    I'll check the link you posted above.

    Tom
  • Hal AlbachHal Albach Posts: 747
    edited 2014-10-06 15:44
    Something to look into...

    On page 16 of the Freescale document is a strong recommendation to disable I2C when using SPI because of a possible interference from the I2C interface while using SPI. The CS pin is the only determinant as to which protocol is used, and when CS is high the chip is in I2C mode .

    from page 16:
    Note: It is recommended to disable I2C during SPI communication to avoid communication errors between devices using a different
    SPI communication protocol. To disable I2C, set the I2CDIS bit in I2C Device Address register using SPI.
  • twm47099twm47099 Posts: 867
    edited 2014-10-06 16:57
    Hal Albach wrote: »
    Something to look into...

    On page 16 of the Freescale document is a strong recommendation to disable I2C when using SPI because of a possible interference from the I2C interface while using SPI. The CS pin is the only determinant as to which protocol is used, and when CS is high the chip is in I2C mode .

    from page 16:
    Note: It is recommended to disable I2C during SPI communication to avoid communication errors between devices using a different
    SPI communication protocol. To disable I2C, set the I2CDIS bit in I2C Device Address register using SPI.

    Hal,
    Thanks for the suggestion. Unfortunately, I got the same results.

    Tom
  • twm47099twm47099 Posts: 867
    edited 2014-10-06 17:07
    twm47099 wrote: »
    Andy,
    I got the same results with all three methods: the Spin example on the product page, the C program in the tutorial, and my spiasm library.

    I'll check the link you posted above.

    Tom

    Andy,
    I tried the SPI Example tutorial with the simpletools library from the link you posted, but I got the same results.

    Tom
  • Hal AlbachHal Albach Posts: 747
    edited 2014-10-06 17:53
    Can you post a picture showing the hookup along with the latest code you loaded?
  • twm47099twm47099 Posts: 867
    edited 2014-10-06 20:18
    Hal Albach wrote: »
    Can you post a picture showing the hookup along with the latest code you loaded?
    Hal,
    It will take me some time to get a picture and post it. I'm also not at my computer that has the code with the i2cdis modification. I'll post everything tomorrow.

    I appreciate your help. .
    Tom
  • twm47099twm47099 Posts: 867
    edited 2014-10-06 21:43
    Progress or just confusion. -- at the beginning of the SPI Example in the C learning tutorial, there is a box that says if you just want to get a quick start with the device, just go to the simple devices tutorial, and run the MMA7455 example. I had not done that.

    Ok so I ran the simple devices code (after I rewired the device to match its directions and changed all the pin definitions in the other programs to match.) But first I reran my program and the SPI example from the protocols tutorial.

    Those 2 programs gave me the same bad results. Then I tried the simple devices version (this uses a special MMA7455 library and simplifies all the calls).

    Well, the simple version worked (so it's not a bad device.)

    Then I tried my library version - it worked, almost -- I got the correct values divided by 4 (64 showed up as 16).

    Then I tried the SPI example from the simple protocols tutorial. It gave the correct readings (64 = 64). Then I retried my code and it gave the correct values.?!?

    If I disconnected the prop board (I'm using a quickstart board) from power, when I reconnected, the problems started again, but were resolved in the same way.

    So now I need To figure out what the simple devices library is doing, how the simple protocol code is affected by that, and what's going in my code. (I also have to figure out if version 0.98.1 of Simpletools library has anything to do with it.)

    It is progress.

    Tom
  • twm47099twm47099 Posts: 867
    edited 2014-10-07 19:47
    It works. I found a few things that needed to be fixed. The post above made me realize that my attempts to write to MCTL and to the XOUT8, YOUT8, and ZOUT8 registers were not working. The "simple device" code set the MCTL configuration and _OUT10 registers configuration (which didn't change when I tried writing to them). My program just read them as 8 bit variables. When I ran the Simple Protocols code, that changed the output of the MMa7455 to 8 bit, which my program read correctly. When I disconnected the power, that stopped the transfers, so when I tried to read after a repower up, it didn't work until I reran the other programs.

    What was wrong - I thought I had fixed the MSBFIRST routine in the assembly language o the SPI driver, but I didn't save it properly. Also in the C program, I had to add some pauses after the write commands and before the "high(CS);" command. As little as pause(1) was sufficient.

    Here's the program listing that works along with a zip of the library.

    Thanks for all the help
    Tom

    /* spi-MMA7455.c       Accelerometer interface using spiasm library
      Based on C-Learning SPI tutorial by Andy Lindsay
       
      Uses pasm in xspiasm.spin, modified from SPI_Asm.spin propeller tool library object.
       T Montemarano  (MIT License)
       
       The SPI device called in main() is a MMA7455 Accelerometer.    
     */
     
    
     #include "simpletools.h"                      // Library includes
     #include "spiasm.h"
       
     /* ******************************************************
        Uses MMA7455 Accelerometer as SPI device
     
    
         MMA7455 pin              Prop pin 
     
    
              CS                 <-    Prop P6  low starts transfer, high terminates
              DATA in/out   <->  Prop P7. Prop out (MFIRST), Prop in (MPRE)
              Clock             <-    Prop P8  rise then fall  State = 0
     
    
     */
     
    
     #define cstate 0               // 0 = start clock low, 1 = start clock high
     #define clockd_ns 1000   // Actual delay in nanoseconds (1000ns = 1 usec), not less than 300ns
                                           // ClockDelay, actual clock delay = 300ns + (cdelay-1) * 50ns
                                           // e.g. cdelay of 15 gives actual clock delay = 1 usec
                                           // cdelay = ((clockd_ns) - 250ns)) / 50ns
                                           // e.g. for 2 usec (i.e. 2000 ns): cdelay = 35
     //  ** Propeller pins 
     #define CS 6
     #define IOPIN 7
     #define CLKPIN 8
     
    
     spia_t *spia; 
     signed char xval, yval, zval;
       
     int main()                                    // Main function
     { 
     // ** MMA7455 commands
       int wmctl = 0x16 | 0x40;   // Write MCTL register. address 0x16 | (bit 7 WRITE) = 0b1010110
       int mctlval = 0x65;   // Value for MCTL register = 0b01100101;
             // D7=0, DRPD=1, SPI3W=1, STON=0, GLVL[1]=0, GLVL[0]=1, MOD[1]=0, MOD[0]=1
             // Don't care, no interupt, SPI 3 wire, no self test, GLVL 2g, MOD measurement on
     
    
       int i2cad =0x0D | 0x40;   // address of I2CAD register (write set)
       int i2cdis = 0x80;              // high in 8th bit disables i2c
     
    
       int rzout = 0x08;    // Command to Read ZOUT register  0x08 (bit 7 is READ)
       int rxout = 0x06;
       int ryout = 0x07;
     
    
       high(CS);                                        // disable MMA7455 data transfer
       spia = spi_start(clockd_ns, cstate);    // Launch, get handles, set ClockDelay & ClockState
       low(CS);                                         // enable MMA7455 data transfer
     
    
               // first disable i2c
                 // void spi_out(spia_t *device, int DQ, int CLK, int MD, int BIT, int VLU);
       spi_out(spia, IOPIN, CLKPIN, MFIRST, 7, i2cad);            // request i2cad write
       spi_out(spia, IOPIN, CLKPIN, MFIRST, 1, 0);                 //  send don't care bit
       spi_out(spia, IOPIN, CLKPIN, MFIRST, 8, i2cdis);           // disable I2C
       pause(1);               // needed before disable data transfer is sent
       high(CS);                // release MMA7455
     
    
       low(CS);
               // set configuration register MCTL
       spi_out(spia, IOPIN, CLKPIN, MFIRST, 7, wmctl);   // request Confguration write
       spi_out(spia, IOPIN, CLKPIN, MFIRST, 1, 0);   //  send don't care bit
       spi_out(spia, IOPIN, CLKPIN, MFIRST, 8, mctlval);    // Send value for MCTL
       pause(1);              
       high(CS);                // release MMA7455
       pause(1);                // may not need 
     
    
       while(1)  
       {
         low(CS);
         spi_out(spia, IOPIN, CLKPIN, MFIRST, 7, rxout);    // request to Read the X acceleration
         spi_out(spia, IOPIN, CLKPIN, MFIRST, 1, 0);         //  send don't care bit
         xval = spi_in(spia, IOPIN, CLKPIN, MPRE, 8);        // read X axis acceleration
         pause(1);       
         high(CS);                // release MMA7455
     
    
         low(CS);
         spi_out(spia, IOPIN, CLKPIN, MFIRST, 7, ryout);     // request to Read the y acceleration
         spi_out(spia, IOPIN, CLKPIN, MFIRST, 1, 0);          //  send don't care bit
         yval = spi_in(spia, IOPIN, CLKPIN, MPRE, 8);        // read y axis acceleration  
         pause(1);
         high(CS);                // release MMA7455
     
    
         low(CS);
         spi_out(spia, IOPIN, CLKPIN, MFIRST, 7, rzout);    // request to Read the Z acceleration
         spi_out(spia, IOPIN, CLKPIN, MFIRST, 1, 0);         //  send don't care bit
         zval = spi_in(spia, IOPIN, CLKPIN, MPRE, 8);       // read Z axis acceleration
         pause(1);               
         high(CS);                // release MMA7455
     
    
         printi(" %c x = %d%c\n", HOME, xval, CLREOL);
         printi("  y = %d%c\n",  yval, CLREOL);
         printi("  z = %d%c\n",  zval, CLREOL);
     
    
         pause(500);
       }
     }   // end main
     
    
    
    
    
    
Sign In or Register to comment.