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

How can I get continuous clock signal from SPI / dsPIC33f

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



Joined: 14 May 2010
Posts: 20

View user's profile Send private message

How can I get continuous clock signal from SPI / dsPIC33f
PostPosted: Fri May 14, 2010 8:36 am     Reply with quote

Hi,

dsPic33f have a fantastic PLL, to create nearly every clock frequency from a given clock signal.

So I want:
(a) A dsPIC33fFJ32GP running with 21,855 Mhz
(b) A Pin of the PIC toggeling constant and exactly with 21,855 div 2 = 10,925 Mhz as clock source for a RF-circuit.

(a) Was no Problem by configurating the PLL: 10 Mhz TCXO div 2 * 35 div 8 = 21,875 Mhz
(b) Did not work: My idea was: Using the CLOCK(SCKx) output from the IDE Module in Framed configuration, as described in http://ww1.microchip.com/downloads/en/DeviceDoc/70206C.pdf Page 17...20
There you can read:
Note:
The SCKx signal clock is not free running for normal SPI modes.
It only runs for 8 or 16 pulses when the SPIxBUF is loaded with data;
However, it is continuous for Framed mode.


The problem is, I cant get that continuous clock output. If I select FRMEN=1 in SPI1CON2 register to enter the Framed Mode, the SPI-Block seems to be dead.

I have done nothing with SPI before and informations are rare for dsPIC33f.
So I don´t know what to do anymore. And I am not a great expert, eaven If I like to experiment with dsPIC....

Code:

#include <33FJ64GP802.h>

#FUSES NoWDT                    // Watch Dog Timer
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES CKSFSM                     //Clock Switching is enbled
#FUSES PR_PLL                   //Primary Oscillator with PLL

#word SPI1STAT=0x0240
#word SPI1CON1=0x0242
#word SPI1CON2=0x0244

#use delay (clock=10000000)
//#use FAST_IO (B)   

#Pin_select SCK1OUT=PIN_B8 // CLK
#Pin_select    SDO1=PIN_B9 // DATA
#Pin_select  SS1OUT=PIN_B7 // Slave Select

int a;      long aa;   

void Main(){
set_Tris_B(0b1100000000000000);
setup_oscillator(OSC_CRYSTAL,21855000,10000000);

       //5432109876543210
SPI1STAT=0b1000000000000000;
SPI1CON2=0b1000000000100000;
SPI1CON1=0b0000000000100000;
spi_write(0x80);


}


Ttelmah



Joined: 11 Mar 2010
Posts: 19328

View user's profile Send private message

PostPosted: Fri May 14, 2010 10:19 am     Reply with quote

Don't know for the PIC33, but for some of the lesser PICs with this ability, three bits would need to be set, and one cleared:
Master mode needs to be selected (MSTEN=1).
Frames SPI would need to be enabled (you mention this).
The SPI itself needs to be enabled (SPIEN=1).
The framed operation also needs to be selected as 'master' (SPIFSD=0)
You shouldn't need to write a byte to the SPI, the clock runs continuously in this mode.
Obviously the corresponding TRIS bits also need to be setup, and since most of these PIC support pin remapping, the peripheral has to be selected to the required pins.
Now, you seem to show most of this.
So I''d triple check your settings. Start simpler, and actually set the SPI to a 'standard' mode, and repeatedly send bytes, and see if you then get clock and data. Only once you have this working, switch to trying for the framed mode.

Best Wishes
buchtsucht



Joined: 14 May 2010
Posts: 20

View user's profile Send private message

PostPosted: Fri May 14, 2010 10:55 am     Reply with quote

Thank you, it is a little bit late, but I will try tomorrw your advised sequence.
Quote:

Start simpler, and actually set the SPI to a 'standard' mode, and repeatedly send bytes, and see if you then get clock and data. Only once you have this working, switch to trying for the framed mode.


=> Standard mode works fine, only framed did not work.
buchtsucht



Joined: 14 May 2010
Posts: 20

View user's profile Send private message

PostPosted: Fri May 14, 2010 11:53 pm     Reply with quote

I tried again, exactly using your settings - no success!!
And I checked my settings 20 times - I can´t find anything!
I wrote a program, that tests all possible settings of the three registers and let it run with oscilloscope on the SPI clock PIN => not only one short signal appeared at all settings!
Rolling Eyes

I found a small mistake: I used only 3 Pins, but frame needs 4 Pins. But it did not help too.

If I add SPI_write(255); the Processor seems to stop operating !??!
(PIN B13 rises four times from low to high and then stays high for ever / MPLAB 8.50 and PCWHD 4.106)
Adding SPI_read(0); is the same.

Code:

#include <33FJ64GP802.h>

#FUSES NoWDT                    // Watch Dog Timer
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES CKSFSM                     //Clock Switching is enbled
#FUSES PR_PLL                   //Primary Oscillator with PLL

#word SPI1STAT=0x0240
#word SPI1CON1=0x0242
#word SPI1CON2=0x0244

#use delay (clock=10000000)
#use FAST_IO (B)
//#USE STANDARD_IO (B)

#Pin_select SCK1OUT=PIN_B8 // CLK
#Pin_select    SDO1=PIN_B9 // DATA output
#Pin_select  SS1OUT=PIN_B7 // Slave Select OUTPUT
//#Pin_select SS1IN=PIN_B7 // Slave Select INPUT
#Pin_select    SDI1=PIN_B10 //Data Input

int a;      long aa;   

void Main(){
setup_oscillator(OSC_CRYSTAL,21855000,10000000);

         //5432109876543210
set_Tris_B(0b1100000000000000);
SPI1STAT  =0b1000000000000000 ;
SPI1CON1  =0b0000000000100010 ;
SPI1CON2  =0b1000000000000000 ;

 
while(1)
   {
   output_low (PIN_B13);output_high(PIN_B13);
   output_low (PIN_B13);output_high(PIN_B13);
   output_low (PIN_B13);output_high(PIN_B13);
   output_low (PIN_B13);output_high(PIN_B13);
SPI_write(255);

   }
}
====================================================
1:                 #include <33FJ64GP802.h>
  0000  040200     goto 0x000200
2:                 
3:                 #FUSES NoWDT                    // Watch Dog Timer
4:                 #FUSES IESO                     //Internal External Switch Over mode enabled
5:                 #FUSES CKSFSM                     //Clock Switching is enbled
6:                 #FUSES PR_PLL                   //Primary Oscillator with PLL
7:                 
8:                 #word SPI1STAT=0x0240
9:                 #word SPI1CON1=0x0242
10:                #word SPI1CON2=0x0244
11:               
12:                #use delay (clock=10000000)
13:                #use FAST_IO (B)
14:                //#USE STANDARD_IO (B)
15:               
16:                #Pin_select SCK1OUT=PIN_B8 // CLK
17:                #Pin_select    SDO1=PIN_B9 // DATA output
18:                #Pin_select  SS1OUT=PIN_B7 // Slave Select OUTPUT
19:                //#Pin_select SS1IN=PIN_B7 // Slave Select INPUT
20:                #Pin_select    SDI1=PIN_B10 //Data Input
21:               
22:                int a;      long aa;   
23:               
24:                void Main(){
  0200  A8E081     bset.b 0x0081,#7
  0202  21F0A0     mov.w #0x1f0a,0x0000
  0204  B7A6A8     mov.w 0x0000,0x06a8
  0206  209000     mov.w #0x900,0x0000
  0208  B7A6C6     mov.w 0x0000,0x06c6
  020A  207080     mov.w #0x708,0x0000
  020C  B7A6C8     mov.w 0x0000,0x06c8
  020E  200460     mov.w #0x46,0x0000
  0210  B7E742     mov.b 0x0000,0x0742
  0212  200570     mov.w #0x57,0x0000
  0214  B7E742     mov.b 0x0000,0x0742
  0216  A8C742     bset.b 0x0742,#6
  0218  EFA32C     setm.w 0x032c
  021A  23F80F     mov.w #0x3f80,0x001e
  021C  23FFF0     mov.w #0x3fff,0x0000
  021E  B7A020     mov.w 0x0000,0x0020
  0220  000000     nop
25:                setup_oscillator(OSC_CRYSTAL,21855000,10000000);
  0222  2005D4     mov.w #0x5d,0x0008
  0224  883A24     mov.w 0x0008,0x0744
  0226  2010D4     mov.w #0x10d,0x0008
  0228  883A34     mov.w 0x0008,0x0746
26:               
27:                         //5432109876543210
28:                set_Tris_B(0b1100000000000000);
  022A  2C0004     mov.w #0xc000,0x0008
  022C  881644     mov.w 0x0008,0x02c8
29:                SPI1STAT  =0b1000000000000000 ;
  022E  280004     mov.w #0x8000,0x0008
  0230  881204     mov.w 0x0008,0x0240
30:                SPI1CON1  =0b0000000000100010 ;
  0232  200224     mov.w #0x22,0x0008
  0234  881214     mov.w 0x0008,0x0242
31:                SPI1CON2  =0b1000000000000000 ;
  0236  280004     mov.w #0x8000,0x0008
  0238  881224     mov.w 0x0008,0x0244
32:               
33:               
34:                while(1)
35:                   {
36:                   output_low (PIN_B13);output_high(PIN_B13);
  023A  A9A2CD     bclr.b 0x02cd,#5
  023C  A8A2CD     bset.b 0x02cd,#5
37:                   output_low (PIN_B13);output_high(PIN_B13);
  023E  A9A2CD     bclr.b 0x02cd,#5
  0240  A8A2CD     bset.b 0x02cd,#5
38:                   output_low (PIN_B13);output_high(PIN_B13);
  0242  A9A2CD     bclr.b 0x02cd,#5
  0244  A8A2CD     bset.b 0x02cd,#5
39:                   output_low (PIN_B13);output_high(PIN_B13);
  0246  A9A2CD     bclr.b 0x02cd,#5
  0248  A8A2CD     bset.b 0x02cd,#5
40:                SPI_write(255);
  024A  EFE248     setm.b 0x0248
  024C  AF2240     btsc.b 0x0240,#1
  024E  37FFFE     bra 0x00024c
  0250  A9C240     bclr.b 0x0240,#6
41:               
42:                   }
  0252  37FFF3     bra 0x00023a
43:                }
44:               
45:               
  0254  FE4000     pwrsav #0


ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sat May 15, 2010 8:39 am     Reply with quote

I have no experience with the dsPIC33, but Paragraph 11.6.3.3 'Configuration Bit Pin Select Lock' makes me feel a bit suspicious. Here a mechanism is described preventing accidental port mappings by allowing to write to the port map registers only once. In the default state this IOL1WAY fuse is, restricting users to one write session until the next 'device reset'.

Do you have a debugger or something so that you can stop in the main loop and read back the configured port remapping settings? Do these have the expected contents?
What if you add the IOL1WAY fuse?

Quote:
If I add SPI_write(255); the Processor seems to stop operating !??!
See your posted assembly code: At line 40 the processor waits in a loop for SPI1STAT.1 to become low, indicating the just added byte moved into the transmit buffer and transmission has started.
This indicates a problem with the SPI module. Most likely some SPI error condition is not cleared.
You say the SPI module did work in normal mode, how was the SPI module configured then? Did you write directly to the SPI registers or did you use the CCS functions for SPI setup? The CCS functions will clear the receive and transmit error flags, this is missing in your code.
buchtsucht



Joined: 14 May 2010
Posts: 20

View user's profile Send private message

PostPosted: Tue May 18, 2010 4:02 am     Reply with quote

Thanks for your answers, I read them several times.

@ckielstra
You was right: <<clearing SPI error flags>> helped me to find the solution!

Now everything is working perfect! Yeaaaaa!!!!

You can use your dsPIC as "low jitter fractional n frequency divider/multiplier" (or blink a LED up to 20.000.000 times per second) without any CPU-resources, if you do it like this:

Example:
10,000000 MHz Input Frequency at OSC1 from TCXO
28,000000 MHz Processor clock
14,000000 MHz at PIN 8

Wish you all fun with programming PICs!


Code:

#include <33FJ64GP802.h>

#FUSES NoWDT                    // Watch Dog Timer
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES CKSFSM                     //Clock Switching is enbled
#FUSES PR_PLL                   //Primary Oscillator with PLL
//uses NoIOL1WAY

#word SPI1STAT=0x0240      // SPI Status and control register
#bit  SPIEN  =SPI1STAT.15   // 1=Enable SPI module
#bit  SPISIDL=SPI1STAT.13   // 1=Stop SPI in IDLE mode
#bit  SPIROV =SPI1STAT.6    // 1=receive overflow has occured   
#bit  SPITBF =SPI1STAT.1   // 1=transmit not started    SPI1TXB is full
#bit  SPIRBF =SPI1STAT.1   // 1=Receive is not complete SPI1RXB is impty

#word SPI1CON1=0x0242
#bit  DISSCK  =SPI1CON1.12      // 1=Disable SCK-PIN / PIN is I/O
#bit  DISDO   =SPI1CON1.11      // 1=Disable SDO-PIN / PIN is I/O
#bit  MODE16  =SPI1CON1.10      // 1=Communication is 16 Bit wide
#bit  SMP     =SPI1CON1.9       // 1=Input data sampled at end of data output time
#bit  CKE     =SPI1CON1.8       // Clock edge select
#bit  SSEN    =SPI1CON1.7       // 1=SSx PIN used for slave modus
#bit  CKP     =SPI1CON1.6       // Clock polarity select
#bit  MSTEN   =SPI1CON1.5       // 1=Master mode
#bit  SPRE0   =SPI1CON1.4       // divide clock frequncy div 1..8
#bit  SPRE1   =SPI1CON1.3       // divide clock frequncy div 1..8
#bit  SPRE2   =SPI1CON1.2       // divide clock frequncy div 1..8
#bit  PPRE0   =SPI1CON1.1       // 0=divide clock frequncy additional div 16
#bit  PPRE1   =SPI1CON1.0       // 0=divide clock frequncy additional div 4

#word SPI1CON2=0x0244
#bit  FRMEN  =SPI1CON2.15      // 1=Enable Framed mode
#bit  SPIFSD =SPI1CON2.15      // 1=Frame sync input slave
#bit  FRMPOL =SPI1CON2.15      // 1=Frame sync input is active low
#bit  FRMDLY =SPI1CON2.15      // 1=Frame sync pulse with first bit


#use delay (clock=10000000)
#use FAST_IO (B)
//#USE STANDARD_IO (B)

#Pin_select SCK1OUT=PIN_B8 // CLK
//#Pin_select    SDO1=PIN_B9 // DATA output
//#Pin_select  SS1OUT=PIN_B7 // Slave Select OUTPUT
//#Pin_select    SDI1=PIN_B10 //Data Input

int a;      long aa;   

void Main(){
setup_oscillator(OSC_CRYSTAL,28000000,10000000);

         //5432109876543210
set_Tris_B(0b1100010000000000);

SSEN=0;
SPIROV=0;
         //5432109876543210
SPI1CON1  =0b0000000000111111; 
FRMEN=1;   // 1=Enable Framed mode
SPIEN=1;

while(1)
   {   }
}


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