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 CCS Technical Support

H/W SPI on a pic24
Goto page Previous  1, 2, 3
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
geokonst



Joined: 04 Apr 2009
Posts: 27

View user's profile Send private message

PostPosted: Thu Apr 16, 2009 6:05 pm     Reply with quote

The code:

Code:
#include "D:\...hardware.h"
#PIN_SELECT SDI1=PIN_B6
#PIN_SELECT SDO1=PIN_F5
#PIN_SELECT SCK1OUT=PIN_G6
#PIN_SELECT U2TX=PIN_F5
#PIN_SELECT U2RTS=PIN_F4

#use rs232(UART2,baud=19200,parity=N,bits=8)
#use delay(internal=8M)

#define SPI_MODE_3 (SPI_H_TO_L)
#define cs PIN_B2
#define id 0x8f
#define getx 0xa9
#define gety 0xab
#define getz 0xad

int dataout;

void main(){
setup_spi(SPI_MASTER | SPI_MODE_3 |SPI_CLK_DIV_32);

while (1){
   output_low(cs);
   spi_read(id);
   dataout=spi_read(0);
   putc(dataout);
   output_high(cs);
         }
}


Maybe the clock divider was different when I took the pic-I was playing around.

It could be something with the 256gb106 chip. I am using 4.084.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Apr 17, 2009 12:33 am     Reply with quote

Sorry, but the code doesn't compile with V4.084 or V4.090. It has conflicting PIN_SELECT entries and other details, that aren't accepted by the compiler. My idea was to check your original code. If you're still interested to understand why SPI receive apparently isn't working, we need a complete code. Can you please add the necessary parts from hardware.h (also #FUSES) and check first, if the code compiles correctly with V4.084.
geokonst



Joined: 04 Apr 2009
Posts: 27

View user's profile Send private message

PostPosted: Fri Apr 17, 2009 9:29 am     Reply with quote

Sorry I'm an idiot.
Code:
#include "C:\...hw.h"

#PIN_SELECT SDI1=PIN_D1
#PIN_SELECT SDO1=PIN_D2
#PIN_SELECT SCK1OUT=PIN_D3
#PIN_SELECT U2TX=PIN_F5
#PIN_SELECT U2RTS=PIN_F4

#use rs232(UART2,baud=19200,parity=N,bits=8)

#define SPI_MODE_3 (SPI_H_TO_L)
#define cs PIN_B2
#define id 0x8f
#define getx 0xa9
#define gety 0xab
#define getz 0xad

int dataout;

void main(){
setup_spi(SPI_MASTER | SPI_MODE_3 |SPI_CLK_DIV_16);

while (1){
   output_low(cs);
   spi_read(id);
   dataout=spi_read(0);
   putc(dataout);
   output_high(cs);     
         }
}

and
Code:
#include <24FJ256GA106.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOJTAG                   //JTAG disabled
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES ICS3                     //ICD communication channel 3
#FUSES WINDIS                   //Watch Dog Timer in non-Window mode
#FUSES WPRES128                 //Watch Dog Timer PreScalar 1:128
#FUSES WPOSTS16                 //Watch Dog Timer PostScalar 1:32768
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FRC_PS                   //Fast RC Oscillator with Post Scaler
#FUSES NOCKSFSM                 //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES NOOSCIO                  //OSC2 is general purpose output
#FUSES NOPR                     //Pimary oscillaotr disabled
#FUSES IOL1WAY                  //Allows only one reconfiguration of peripheral pins
#FUSES WPEND_LOW           
#FUSES NOWPCFG               
#FUSES NOWPDIS               
#FUSES WPFP0
#use delay(internal=8M)
                         
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Apr 17, 2009 5:05 pm     Reply with quote

Now it compiles correct. However, I found that PCD V4.084 unfortunately uses a wrong pin select register for SDI1. The issue is fixed in most recent V4.090. You can set the pin select manually, but must disable #FUSES IOL1WAY for the code to work.

Code:
#byte RPINR20L = 0x6A8
#bit IOLOCK  = 0x742.6
#byte OSCCONL = 0x742

OSCCONL = 0x46;
OSCCONL = 0x57;
IOLOCK = 0;

RPINR20L = 24; // SPI1 Data Input = RP24 - PIN_D1

OSCCONL = 0x46;
OSCCONL = 0x57;
IOLOCK = 1;


B.T.W., I also found that V4.90 has changed the interpretation of "UART2" in #use rs232 , which is now Microchips UART4. Not really amusing.
geokonst



Joined: 04 Apr 2009
Posts: 27

View user's profile Send private message

PostPosted: Fri Apr 17, 2009 7:10 pm     Reply with quote

OK I really have no words to thank you enough FvM.
I've been pulling my hair trying to make this work for a month now. You did it man!
Oh the joy!!!!

Thank you so much!!!!!!
THANK YOU!
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sat Apr 18, 2009 3:35 am     Reply with quote

I'm glad, that the problem could be solved finally.

Now I have supplement regarding changes in V4.091.

I previously suggested to use spi_read only because of a bug in status bit handling with spi_write().
Code:
SPI_nCS_LAT = 0;
spi_read(0xAB);
spi_read(0);
spi_read(0);
spi_read(0);
bID=spi_read(0);
SPI_nCS_LAT = 1;


In V4.091, SPIxTBF is handled correctly, but my original code is still not working due to another non-obvious issue.
Code:
spi_write(0xAB);
spi_write(0);
spi_write0);
spi_write(0);
bID=spi_read(0);

The code is intended to write 4 bytes (a command and 3 dummy bytes) and then read one byte in the fifth cycle.

Code:
....................    spi_write(0);
05D1C:  CLR.B   248
05D1E:  BTSC.B  240.1
05D20:  BRA     5D1E
05D22:  BCLR.B  240.6
....................    bID=spi_read(0);
05D24:  CLR.B   248
05D26:  BTSS.B  240.0
05D28:  BRA     5D26
05D2A:  MOV.B   248,W0L
05D2C:  BCLR.B  240.6
05D2E:  MOV.B   W0L,17F1


In the above assembly listing of part of the code, bID doesn't return the result of the last SPI cycle as expected.

This happens because spi_write() resets SPIROV (240.6) before the first byte is received, spi_read(0) doesn't wait for the second cycle to finish but returns the read data from previous cycle immediately. The problem can be handled by inserting a dummy spi_read() before the spi_read(0), or by using spi_read(xx) only, as I did before.

I won't say that it's actually a bug, but a problem involved with the status bit handling in PCD built-in SPI functions. But it must be expected to confuse PCD users seriously.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Mon Sep 14, 2009 2:34 pm     Reply with quote

As a late update, I realized that PCD is using the mask value SPI_H_TO_L in a different meaning than the 8-Bit compilers. Thus my above coding of SPI modes isn't correct. What I declared as SPI MODE_3 is actually setting mode 0. It's no problem with SPI flash, that supports both modes. This is a corrected mapping of SPI modes.
Code:
#define SPI_MODE_0_0 0x0100
#define SPI_MODE_0_1 0x0000
#define SPI_MODE_1_0 0x0140
#define SPI_MODE_1_1 0x0040   
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3
Page 3 of 3

 
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