View previous topic :: View next topic |
Author |
Message |
geokonst
Joined: 04 Apr 2009 Posts: 27
|
|
Posted: Thu Apr 09, 2009 1:03 pm |
|
|
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
|
|
Posted: Thu Apr 09, 2009 2:44 pm |
|
|
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
|
|
Posted: Thu Apr 09, 2009 3:48 pm |
|
|
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
|
|
Posted: Thu Apr 09, 2009 4:15 pm |
|
|
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
|
|
Posted: Thu Apr 09, 2009 4:35 pm |
|
|
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
|
|
Posted: Thu Apr 09, 2009 6:41 pm |
|
|
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
|
|
Posted: Fri Apr 10, 2009 2:59 am |
|
|
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
|
|
Posted: Fri Apr 10, 2009 7:05 am |
|
|
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
|
|
Posted: Sat Apr 11, 2009 9:11 am |
|
|
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
|
|
Posted: Sat Apr 11, 2009 11:15 am |
|
|
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
|
|
Posted: Sat Apr 11, 2009 5:32 pm |
|
|
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
|
|
Posted: Sat Apr 11, 2009 6:08 pm |
|
|
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
|
|
Posted: Sat Apr 11, 2009 6:28 pm |
|
|
Lol of course not . 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
|
|
Posted: Wed Apr 15, 2009 6:12 pm |
|
|
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
|
|
Posted: Thu Apr 16, 2009 4:08 am |
|
|
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. |
|
|
|