CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

SPI issues with 18F2420 and AS5048A rotary encoder

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
victor_constantin



Joined: 14 Dec 2010
Posts: 10

View user's profile Send private message

SPI issues with 18F2420 and AS5048A rotary encoder
PostPosted: Mon Jul 30, 2012 1:25 am     Reply with quote

Hello all,

Setup is: PIC18F2420@8Mhz, AS5048A SPI-enabled transducer, CCS PIC 4.114.

I'm using 4-wire single slave SPI, all signals are OK, they modify with the magnetic field, checked with oscilloscope. SPI is 16 bit, got around that by using software SPI:

Code:
#use spi(Master,Enable=PIN_C2,ENABLE_ACTIVE=0, BITS=16, DI=PIN_C4, DO=PIN_C5, CLK=PIN_C3, SAMPLE_FALL, IDLE=0, MSB_FIRST)


What I am however having some issues with is actually outputting those signals into something useful. What I'm getting with Realterm for the code below(citit is a 16bit integer):


Code:

output_high(CS);          //Idle state for rotary encoder
citit=spi_xfer(0x0001);  //Clear any errors, as per transducer datasheet


    while(true){
   
      citit=spi_xfer(0xFFFF);    //Read command for device
      printf("%ld", citit);printf(" "); //Output read value over RS232 FTDI cable
    }

}


Is:

Code:
2896      0    128    128  32768      0      0      0  32896    128  32768     
0  32768      0      0      0  32896    128    128  32768      0  32768      0 
  128      0      0      0  32768    128      0    128      0      0      0     
 0  32896  32768      0  32768      0      0      0      0  32896  32768      0
 32768      0      0      0      0      0    128  32768      0      0      0   
  0  32768      0      0      0      0      0      0      0  32896  32768      0
  32768      0      0      0      0    128  32768      0  32768      0      0   
   0      0      0    128      0      0      0  32896    128    128  32768     
0    128      0      0      0      0      0  32896  32768  32896      0    128 
    0  32896    128  32768      0  32768    128  32768      0      0      0     
 0      0  32896  32768  32896      0      0      0      0      0      0  32896
   128      0      0      0  32768    128    128      0      0      0      0 


I've tried long long for the citit variable, no luck.

I believe the issue is with the signal the transducer is outputting, meaning that out of the 16bits, the first two are MSB and Error flag, followed by the actual 14 bits of angle data I need.

Should I get rid of MSB and the Error flag bits? If so, how do I do that? Typecasting an int into something else(byte array) has not worked for me.


Last edited by victor_constantin on Mon Jul 30, 2012 2:42 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19260

View user's profile Send private message

PostPosted: Mon Jul 30, 2012 1:48 am     Reply with quote

citit &= 0x3FFF;

Removes the top two bits.

Long, is 16bit. Exactly the same.

Now, on what you show, several of the values do not involve these bits. 128 (for example), is 0b00000.....10000000. The 2896 you show for the first value, is 0000.....101101010000. Again no involvement of the high bits. The two high bits will give you the 32768. The 32896, is 128+32768. So you seem to be getting data on bit 7 quite repeatedly. So is this legitimate?.

As some further comments. Being 16bit, doesn't stop you using the hardware SPI. Just do two 8bit transfers.

You have the device wired for 5v operation, with the separate capacitor on the 3.3v regulator output?.

Best Wishes
victor_constantin



Joined: 14 Dec 2010
Posts: 10

View user's profile Send private message

PostPosted: Mon Jul 30, 2012 2:29 am     Reply with quote

Thanks for the answer. I am powering it at 5V so yes, the capacitor is in place. Never really got the bitwise operator part, so from what I'm getting the code you sent really just does an AND between what I'm reading and a 3FFF, giving me the last 14 bits of what I got from the transducer. I replaced thus my code to:

Code:
output_high(CS);
spi_xfer(0x0001);

    while(true){
   
      citit=spi_xfer(0xFFFF);   
      citit&=0x3FFF;
      printf("%ld", citit);printf(" ");
      }
}


But I'm getting the exact same rubbish. What I'm currently seeing as an issue is that even though my signal is pretty random, I'm only getting those exact same values. So maybe it's a conversion issue?
victor_constantin



Joined: 14 Dec 2010
Posts: 10

View user's profile Send private message

PostPosted: Mon Jul 30, 2012 2:41 am     Reply with quote

Changing to #use delay(clock=2000000) from #use delay(clock=8000000) outputs:

Code:
  3864    3936  -26490    6368   -2048    3846    3864    3870  -26490 
   798    -464    3846    3864    3942    3846    6278   -2048    3846 
  3864    3936    3960    3960   -2048    3846    3864    3870    3936 
-30976   -2048    3846    3864    3870    6278    6348   -2048    3846 
  3864    3936  -30976    6272   -2048    3846    3864    3936  -30976 
  3966   -2048    3846    3864    3936    3966    6272   -2048    3846 
  3864    3936  -30976    3942   -2048    3846    3864    3936    3960 
  3864   -2048    3846    3864    3936  -26496    6374   -2048    3846 
  3864    3870    6278    6351   -2048    3846    3864    3942    3864


And if i change it to clock=32000000, i get only 0.

Main.h is :

Code:
#include <18F2420.h>

#FUSES NOWDT                    //No Watch Dog Timer

#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES NOPUT                    //No Power Up Timer
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected

#use delay(clock=2000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1)
#define LED PIN_A0
#define DELAY 10
#define CS PIN_C2


LE: sorry about the PIC, i changed it in all of the posts, i'm currently on two projects and i got them mixed.
Ttelmah



Joined: 11 Mar 2010
Posts: 19260

View user's profile Send private message

PostPosted: Mon Jul 30, 2012 3:37 am     Reply with quote

First thing to do, is add ENABLE_ACTIVE=1 to the setup SPI. The default is zero, and the faster you clock the chip, the shorter the actual delay will be. The chip you are talking to, requires a _minimum_ of 350nSec for this. It is possible the code is failing because of this.

Then, there is something very odd about what you are showing. 32768 for example, is an impossible output from %ld, unless citit is not declared as an int16. It should display as -32640. You also can't get any -ve numbers displayed after using the &=3FFF operation (the top bit is the 'sign' bit in an int16, and this is removed).

long long, changes everything, since you are then using an int32. Pointless, but would give the numbers you are showing in your original post. Suspect this is what you are doing, but this doesn't then agree with what you _say_.

Key is that you _must_ make what you show as as an output, agree with the code actually used. Otherwise you are wasting _our time, and yours_.


Now, I don't think you are talking to the chip completely correctly. Your _first_ read, when you start, _will_ be effectively garbage, containing the contents of the error register. You need to do an extra write after clearing this. Also, the clear error flag command is not correct. Look at table 12. Needs bit 14 set.
So the sequence needs to be:
Code:

    spi_xfer(0x4001); //Clear error flag
    spi_xfer(0xFFFF); //select read angle as next command
    while(true){
   
      citit=spi_xfer(0xFFFF);   
      citit&=0x3FFF;
      printf("%5ud ", citit); //Will make output tidier
      }
   }


Best Wishes
victor_constantin



Joined: 14 Dec 2010
Posts: 10

View user's profile Send private message

PostPosted: Mon Jul 30, 2012 3:53 am     Reply with quote

Thank you for the response, however, no luck yet. I know output does not seem linked to the results, it's not making any sense for me either.


Ok, so my code is currently(i changed it as per your indications):

Code:
#include <main.h>
//!#USE SPI (MASTER, FORCE_HW, SPI1, MODE=0, BITS=16, STREAM=SPI_1, MSB_FIRST)
#use spi(Master,Enable=PIN_C2,ENABLE_ACTIVE=1, BITS=16, DI=PIN_C4, DO=PIN_C5, CLK=PIN_C3, SAMPLE_FALL, IDLE=0, MSB_FIRST)

long long citit;

void main()
{

  spi_xfer(0x4001); //Clear error flag
    spi_xfer(0xFFFF); //select read angle as next command
    while(true){
   
      citit=spi_xfer(0xFFFF);   
      citit&=0x3FFF;
      printf("%5ud ", citit); //Will make output tidier
      }
   }


With:

Code:
#use delay(clock=1000000)


Output is:

Code:
 
  25648    8224    8224   12320    8292    8224    8224   25648    8224
   8224   12320    8292    8224    8224   25648    8224    8224   12320
   8292    8224    8224   25648    8224    8224   12320    8292    8224
   8224   25648    8224    8224   12320    8292    8224    8224   25648
   8224    8224   12320    8292    8224    8224   25648    8224    8224
  12320    8292    8224    8224   25648    8224    8224   12320    8292
   8224    8224   25648    8224    8224   12320    8292    8224         


============

Using:


Code:
#use delay(clock=8000000)


Output becomes:


Code:
 
      0     128       0       0       0       0       0       0  -32768
      0       0       0       0       0       0       0     128       0
      0       0       0       0       0  -32768       0       0       0
      0       0       0       0     128       0       0       0       0
      0       0  -32768       0       0       0       0       0       0
      0     128       0       0       0       0       0       0  -32768
      0       0       0       0       0       0       0     128       0
      0       0       0       0       0  -32768       0       0       0
      0       0       0       0     128       0       0       0       0
      0       0  -32768       0       0       0       0       0       0


For any higher frequency, output is all 0.
Ttelmah



Joined: 11 Mar 2010
Posts: 19260

View user's profile Send private message

PostPosted: Mon Jul 30, 2012 4:31 am     Reply with quote

long long in not wanted/needed. This prevents the code from working properly, since it allows -ve results randomly to happen in the print. I've said this before. Just use int16. It is _always_ better/safer to use the intxx forms, since 'long', or 'long long', have different meanings on different compilers, which is asking for problems....

Use %5lu for the format. I meant to remove the 'd', but accidentally left it. Ugh.

Now, seriously, are you actually changing the crystal, when you switch clock rates?. The only time you can change rates without changing a crystal, is using the internal oscillator, and only then when using rates this supports. It doesn't support 20MHz, or 10MHz. So what are you actually doing here?. The rate in this, _must_ match exactly what the chip is actually clocked at.

Switch to using SPI mode numbers. Much more reliable than trying to set stuff up yourself. The chip uses MODE1.
Specify a baud rate. This will at least attempt to keep the bus rate constant as you change clock rates, ruling out another possible problem.

Code:

use spi(Master, FORCE_HW, Enable=PIN_C2, ENABLE_DELAY=1,
BITS=16, MODE=1, BAUD=500000)


Best Wishes
victor_constantin



Joined: 14 Dec 2010
Posts: 10

View user's profile Send private message

PostPosted: Mon Jul 30, 2012 4:50 am     Reply with quote

Again, thanks for the response. I will try this tomorrow and get back to you.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group