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  Next
 
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 09, 2009 1:03 pm     Reply with quote

Ok I think I've done whatever there is to do to make this work (at least for a newbie).

I just don't get it.
This code:
Code:
#include "D:\...hardware.h"
#PIN_SELECT SDI1=PIN_G8
#PIN_SELECT SDO1=PIN_G7
#PIN_SELECT SCK1OUT=PIN_G6
#PIN_SELECT U2TX=PIN_F5
#PIN_SELECT U2RTS=PIN_F4

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

#define SPI_CLK_DIV_2    0x001B
#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;

main(){
setup_spi(SPI_MASTER | SPI_MODE_3 |SPI_CLK_DIV_1);

output_low(PIN_B15);

//who_am_i
output_low(cs);
spi_read(id);
dataout=spi_read(0);
putc(dataout);
output_high(cs);

delay_ms(500);
//cfg
output_low(cs);
spi_read(0x20);
spi_read(0xC7); //11000011
output_high(cs);

while (1){
putc (0x80);

output_low(cs);
spi_read(getx);
dataout=spi_read(0);
putc(dataout);
output_high(cs);

output_low(cs);
spi_read (gety);
dataout=spi_read(0);
putc(dataout);
output_high(cs);

output_low(cs);
spi_read (getz);
dataout=spi_read(0);
putc(dataout);
output_high(cs);
}

}


Does not work (sends 80 and 3 zeroes to the serial port)

The same sequence with my software spi:

Code:
#include "C:\...uclboard.h"
#PIN_SELECT U2TX=PIN_F5
#PIN_SELECT U2RTS=PIN_F4

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

#define in PIN_G8
#define out PIN_G7
#define clk PIN_G6
#define cs PIN_B2
#define id 0x8f
#define getx 0xa9
#define gety 0xab
#define getz 0xad

int recVal = 0x00;
int i;


void spisend(sendVal)
{
for (i=7;i>=0;i--){
output_bit(out,BIT_TEST(sendVal,i));
output_low(clk);
output_high(clk);
}
}

void spiread()
{
for (i=7;i>=0;i--){
output_low(clk);
if (input(in)){
    BIT_SET(recVal,i);
}
output_high(clk);
}
putc(recVal);
recVal=0x00;
}

void main()
{
output_low(PIN_B15);

output_high(clk);

//who_am_i
output_low(cs);
spisend(id);
//spiread();
output_high(cs);

delay_ms(500);
//cfg
output_low(cs);
spisend(0x20);
spisend(0xC7); //11000011
output_high(cs);

while (1){
putc (0x80);

output_low(cs);
spisend(getx);
spiread();
output_high(cs);

output_low(cs);
spisend(gety);
spiread();
output_high(cs);

output_low(cs);
spisend(getz);
spiread();
output_high(cs);
}

}


Works perfectly!

both files have the same .h

Code:
#include <24FJ256GB106.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                 
#FUSES PLL12                    //Divide By 12(48MHz oscillator input)
#FUSES RESERVED                 //Used to set the reserved FUSE bits

#use delay(internal=8M)



...and were uploaded to the very same hardware one after the other.
Unfortunately I blew up my Explorer 16 board and can't use the scope any more, but last time I tried I got a good response from the accelerometer (LIS302DL) on h/w spi but the pic wouldn't read it. I can still use the serial though.

If anyone has an idea PLEASE PLEASE post it. This can't be so hard!
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Apr 09, 2009 2:44 pm     Reply with quote

I don't see anything wrong with your hardware SPI usage. Also the #pin_select commands seem to generate correct code.
geokonst



Joined: 04 Apr 2009
Posts: 27

View user's profile Send private message

PostPosted: Thu Apr 09, 2009 3:48 pm     Reply with quote

What's going wrong then? It's driving me mad. Why doesn't it read a perfectly sent response? I really don't want to switch back to C30! I hate c30!
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Apr 09, 2009 4:15 pm     Reply with quote

It's not necessarily a PCD issue. Although hardware SPI should be able to communicate with the ST acceloremeter, there may be a problem with your hardware and the faster HW operation. I would try to trace it at the hardware level. You also could replace the device with a SDO/SDI loopback to verify basic send/receive operation.
geokonst



Joined: 04 Apr 2009
Posts: 27

View user's profile Send private message

PostPosted: Thu Apr 09, 2009 4:35 pm     Reply with quote

But, you see the accelerometer is responding, so if it's a hardware issue it must be PIC's

The loopback is a very good idea!
geokonst



Joined: 04 Apr 2009
Posts: 27

View user's profile Send private message

PostPosted: Thu Apr 09, 2009 6:41 pm     Reply with quote

The loopback test failed as well. I still get zeros. And I've tried different pins too. :(

FvM could the fact that I'm using the internal osc have anything to do with it? Doesn't sound likely but I'm running out of ideas.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Apr 10, 2009 2:59 am     Reply with quote

As previously reported, hardware SPI is basically working with PIC24F chips, at least using the read_spi() instruction. I tested with V4.084 and most recent V4.090. Of course, I had to check with my hardware, that is using different pins, so it must not necessarily work with your configuration. I also can't see, if there's something in your hardware.h include file that disturbs SPI operation. Generally I would proceed like this:

- check the code operation at the assembly/register level with MPLAB debugger (requires e.g. ICD2 or PICkit ICSP adapter).
- check the hardware operation with an oscilloscope or other hardware debug tools

I don't expect problems related to internal oscillator.
Ken Johnson



Joined: 23 Mar 2006
Posts: 197
Location: Lewisburg, WV

View user's profile Send private message

PostPosted: Fri Apr 10, 2009 7:05 am     Reply with quote

I'm using SPI on 24H for 2 different devices (ADC and FRAM) at 2 different clock speeds, using (sorry) Microchip's C30. Here are some code snippets:

Code:

    SPI2STAT = 0;               //  Disable the SPI2 module for setup;
    SPI2CON1bits.CKP    = 0;    //  Clock idles lo;
    SPI2CON1bits.CKE    = 1;    //  Read data on rising edge of SCK;
    SPI2CON1bits.MSTEN  = 1;    //  PIC is the master;
    SPI2CON1bits.PPRE   = 2;


and

Code:

void    SaveFRAM (ushort offset, const void *pRAM, ushort nBytes)
//  Writes nBytes from pRAM into STORAGE at offset:
{
    const   dbyte   *p;
    ushort  nWords;

    nWords = nBytes / 2;        //  16-bit transfers;
    p = (dbyte*) pRAM;          //  Pointer to 16-bit items;
    TaskBlock (ProcessTask);    //  Shares the SPI Port;
    SPI2CON1bits.MODE16 = 0;    //  8-bit transfers on SPI2;
    SPI2CON1bits.SPRE   = 7;    //  10MHz (max SCLK);
    SPI2STATbits.SPIEN  = 1;    //  Enable the SPI module;
    SelectFRAM (0);             //  Chip Select;
    SPI2BUF = WREN;             //  Write the command and wait:
    while ( !SPI2STATbits.SPIRBF );
    SPI2BUF;                    //  Read buffer to clear SPIRBF;
    SelectFRAM (1);             //  Toggle Chip Select;
    SelectFRAM (0);             //  Write the next command:
    SPI2BUF = WRITE;
    while ( !SPI2STATbits.SPIRBF );
    SPI2BUF;                    //  Read buffer to clear SPIRBF;
    SPI2STAT = 0;               //  Disable the SPI, and change mode:
    SPI2CON1bits.MODE16 = 1;    //  Now do 16-bit transfers;
    SPI2STATbits.SPIEN  = 1;    //  Enable the SPI module;
    SPI2BUF = offset;           //  Write the address;
    while ( !SPI2STATbits.SPIRBF );
    SPI2BUF;                    //  Read buffer to clear SPIRBF;
    while ( nWords-- ) {        //  Now write all the data:
        SPI2BUF = *p++;
        while ( !SPI2STATbits.SPIRBF );
        SPI2BUF;
    }
    SelectFRAM (1);
    SPI2STAT = 0;               //  Disable PIC SPI, and clear the read overrun flag;
    TaskUnBlock (ProcessTask);
}


Maybe comparing this with the CCS generated asm code will show something?

Best of luck!
Ken
Guest








PostPosted: Sat Apr 11, 2009 9:11 am     Reply with quote

geokonst-

I've made some progress over the last day or so, however I've done so using software SPI similar to what you've posted. Still nothing with the hardware (and still waiting for a response from Microchip). I was attempting to use port D on the PIC, of which one of the pins I was using apparently didn't work. However I tried port G like you were using and still didn't get a response. I'll keep you posted if I hear back from Microchip or get the hardware to work.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sat Apr 11, 2009 11:15 am     Reply with quote

I would be suprized, if there's a hardware problem with certain pins, but can be, of course. Anyway, it's interesting to know, which part of the SPI function is apparently failing: SCK, SDO or SDI/receive.
geokonst



Joined: 04 Apr 2009
Posts: 27

View user's profile Send private message

PostPosted: Sat Apr 11, 2009 5:32 pm     Reply with quote

I have too tried pins D1, D2, D3, G8, G7 with no luck (no compiler errors). I don't believe its a pin problem as pps works fine with the serial port. Also I've tried manually setting I/O direction.

The customer support sent me the following code which they say compiles:


Code:
#include <24fj256ga110.h>
#use delay(clock=40mhz)

#PIN_SELECT SDI1=PIN_G8
#PIN_SELECT SDO1=PIN_G7
#PIN_SELECT SCK1OUT=PIN_G6
#PIN_SELECT SS1OUT=PIN_B1

#PIN_SELECT U2TX=PIN_F5
#PIN_SELECT U2RTS=PIN_F4

#use rs232(UART1,baud=19200,parity=N,bits=8)
#use spi(SPI1, BITS=16, MODE=3)

int dataout;

void main(){
while (1){
output_low (PIN_B2);
dataout=SPI_XFER(0x8f);
output_a(dataout);
delay_us(50);
output_high (PIN_B2);
delay_ms(3);
}
}


It doesn't compile for me and the problem is the option "SPI1" in use spi. I have no idea why. Could you please try it and let me know if it compiles on your machine?

I have also tried the registers approach:
Code:
#include "D:\...24FJ256GB106_registers.h"

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

#use rs232(UART2,baud=19200,parity=N,bits=8)
#define SPI_MASTER 0x0120 // select 8-bit master mode, CKE=1, CKP=0
#define SPI_ENABLE 0x8000 // enable SPI port, clear status

#define cs PIN_B2

int i;
int writeSPI2( int data)
{
SPI2BUF = data;
delay_ms(500);
return SPI2BUF; // read the received value
}
main()
{

output_high (cs);
SPI2CON1 = SPI_MASTER; // select mode
SPI2STAT = SPI_ENABLE; // enable the peripheral

while (1){
set_tris_d(0xfc);
output_low(cs);
writeSPI2( 0x8F); // send a READ STATUS COMMAND
i = writeSPI2( 0); // send dummy, read data
putc(i);
delay_ms(10);
output_high(cs);

delay_ms(10);
}
}
[/quote]
But I am really inexperienced so I probably have done something wrong.



So what is failing for me is reading the response (or putting the value in a variable). While I had access to an oscilloscope I could see that the communication was perfect. And I have also tried sorting sdi + sdo and still nothing. So SDI seems to be the problem.

Unfortunately I need hardware spi, so if you have any ideas please post them here. Thanks
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sat Apr 11, 2009 6:08 pm     Reply with quote

I didn't try #use spi with V4.090. As said, it didn't work with V4.084, at least for PIC24FJ128GA106 (and similar GA10x and GB10x chips). As a possible problem, CCS seems not to test built-in functions with the full choice of chips, so a lot of bugs related to chip specific features, register mappings etc. isn't detected.

I don't understand your "register approach", that uses #pin_select for SPI1 but accesses SPI2 registers. This can't work.
geokonst



Joined: 04 Apr 2009
Posts: 27

View user's profile Send private message

PostPosted: Sat Apr 11, 2009 6:28 pm     Reply with quote

Lol of course not Smile. I've done so many changes trying to make this work that it's hard to find a file with correct code any more. Sorry for that. I don't even remember the reason why I switched to spi2 after some point.

Thanks Fvm.
Guest have you given up on H/W spi?
geokonst



Joined: 04 Apr 2009
Posts: 27

View user's profile Send private message

PostPosted: Wed Apr 15, 2009 6:12 pm     Reply with quote

And here's some proof that the comms are fine (although I can't read the response)




I've also learned that #use spi won't work with versions <4.084 (unfortunately mine) and apparently I can't make setup_spi work either so no h/w spi for me.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Apr 16, 2009 4:08 am     Reply with quote

Can you please show the code, that is producing the shown waveform (and fails on recepetion). I see, that it can't be the code you posted most recently. And also tell the compiler version (you possibly did before).

As previously said, I have no problems with hardware SPI, using V4.084 and V4.090.
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  Next
Page 2 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