Page 1 of 2

Strange SPI Behavior

Posted: Thu Mar 28, 2013 1:18 pm
by formica
I observe a strange behavior traying to use the SPI on my custom board:

Code: Select all

          cRPY_16bit[0] = 128;
          cRPY_16bit[1] = 128;
          cRPY_16bit[2] = 128;
          cRPY_16bit[3] = 128;
          cRPY_16bit[4] = 128;

          spiAcquireBus(&SPID2);                                             /* Acquire ownership of the bus.    */
          spiStart(&SPID2, &ls_spicfg);                                      /* Setup transfer parameters.       */
          spiSelect(&SPID2);                                                      /* Slave Select assertion.          */
          spiExchange(&SPID2,10,cRPY_16bit,rxbuf_16bit);         /* Atomic transfer operations.      */
          spiUnselect(&SPID2);                                          /* Slave Select de-assertion.       */
          spiReleaseBus(&SPID2);                                        /* Ownership release.               */



Watching the SPI Line with an oscilloscope I see the traffic IF the code above is compiled INSIDE an external thread, conversely it doesn't work IF the code is compiled in the MAIN THREAD (main function).
All the variable used are in the global scope.

Any ideas? Maybe it's a stupid things... in this case SORRY IN ADVANCE!

Re: Strange SPI Behavior

Posted: Thu Mar 28, 2013 3:16 pm
by Giovanni
The parameter "n" in spiExchange() is not the number of bytes but the number of frames, 5 in your case. I don't know if the resulting stack corruption is the cause of your problem.

Giovanni

Re: Strange SPI Behavior

Posted: Fri Mar 29, 2013 1:00 pm
by formica
Thanks giovanni for your quick response. Also using your correction I obtain the same behavioe. The main thread doesn't communicate through spi. I'm chechking with the oscilloscope everytime.

Re: Strange SPI Behavior

Posted: Fri Mar 29, 2013 1:13 pm
by Giovanni
Hi,

It must be something specific in your setup, I tested SPI functions from the main function and found no obvious problems.

Giovanni

Re: Strange SPI Behavior

Posted: Sun Mar 31, 2013 2:15 am
by formica
I discovered that the problem exists when, in the main thread, I use the serial-usb. It seems that SPI and SerialUsb cannot co-exist. If I move the spi in another thread... everything is ok. It sounds really strange! :|

Re: Strange SPI Behavior

Posted: Sun Mar 31, 2013 2:17 am
by Tectu
No idea, but check the IRQ and the DMA priorites of both peripheral drivers. Maybe a problem source?


~ Tectu

Re: Strange SPI Behavior

Posted: Sun Mar 31, 2013 7:52 am
by Giovanni
The thread makes no difference unless there is a stack overflow in the main thread.

Are you using CCM memory? if so make sure buffers are in a DMA-reachable area.

Giovanni

Re: Strange SPI Behavior

Posted: Sun Mar 31, 2013 4:37 pm
by barthess
formica
What MCU you use? Did you enable all debug options in chconf.h?

Re: Strange SPI Behavior

Posted: Tue Apr 02, 2013 6:59 pm
by formica
I'm using an STM32F103RBT6!
I don't know what is a CCM memory (maybe an external ram). In this case... no, I'm just using a raw stm32f103rbt6 with some sensors on the I2C bus (gyro,acc,magn).
I attach the main file (with a lot of comments inside... It's a very dirty piece of code, sorry).
Now usb_write() and spi_write() are both in the main thread.

If you can, just take a look to the main function.

I observe that, if I read from the usb-serial ('sudo screen /dev/ttyACM0') the SPI works properly and I see the digital signal on the spi test_point. If I don't read from the usb-serial, randomly, it happens that the usb AND the SPI hangs up... while the led blink thread go on running properly.

Thanks in advance

Roberto

Re: Strange SPI Behavior

Posted: Wed Apr 03, 2013 8:24 am
by formica
My last version: I added a control on the USB_STATE.
As before, sometimes, when I don't read the USB from the terminal, the SPI hangs up.

Any idea?

Code: Select all

systime_t time = chTimeNow();     // T0
  while (TRUE) {
 
   time += MS2ST(25);            // Next deadline
//   bmp085_read_temp();
//       bmp085_read_press(BMP_MODE_PR0);
   lsm303dlh_read_acceleration();
       lsm303dlh_read_magfield();
   l3g4200d_gyro_burst();
   complementary_filter();

   Roll_s=sign(Roll);
   Roll_e=exponent(Roll);
   Roll_m=mantissa(Roll);
   Pitch_s=sign(Pitch);
   Pitch_e=exponent(Pitch);
   Pitch_m=mantissa(Pitch);
   Yaw_s=sign(Yaw);
   Yaw_e=exponent(Yaw);
   Yaw_m=mantissa(Yaw);
   
cRPY_16bit[0] = (uint16_t)Roll_m;
cRPY_16bit[1] = (uint16_t)Pitch_m;
cRPY_16bit[2] = (uint16_t)Yaw_m;
cRPY_16bit[3] = (uint16_t)Roll_m;
cRPY_16bit[4] = (uint16_t)Pitch_m;

   spiAcquireBus(&SPID2);                                        /* Acquire ownership of the bus.    */
   spiStart(&SPID2, &ls_spicfg);                    /* Setup transfer parameters.       */
   spiSelect(&SPID2);                                            /* Slave Select assertion.          */
   spiExchange(&SPID2,5,cRPY_16bit,rxbuf_16bit);                 /* Atomic transfer operations.      */
   //spiSend(&SPID2,6,cRPY);
   spiUnselect(&SPID2);                                          /* Slave Select de-assertion.       */
   spiReleaseBus(&SPID2);                                        /* Ownership release.               */


   if(SDU1.config->usbp->state==USB_ACTIVE)
   {
      chprintf((BaseChannel *)&SDU1, "S:%6d:%6d:%6d:%6d:%6d:%6d:%6d:%6d:%6d:%6U:%6U:%6U:%6U:%6U:%6U:%6U:%6U:%6U:E\r\n",gyroX,gyroY,gyroZ,accelX,accelY,accelZ,magnX,magnY,magnZ,Roll_s,Roll_e,Roll_m,Pitch_s,Pitch_e,Pitch_m,Yaw_s,Yaw_e,Yaw_m);
   }
   chThdSleepUntil(time);        

  }