View previous topic :: View next topic |
Author |
Message |
geokonst
Joined: 04 Apr 2009 Posts: 27
|
|
Posted: Thu Apr 16, 2009 6:05 pm |
|
|
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
|
|
Posted: Fri Apr 17, 2009 12:33 am |
|
|
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
|
|
Posted: Fri Apr 17, 2009 9:29 am |
|
|
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
|
|
Posted: Fri Apr 17, 2009 5:05 pm |
|
|
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
|
|
Posted: Fri Apr 17, 2009 7:10 pm |
|
|
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
|
|
Posted: Sat Apr 18, 2009 3:35 am |
|
|
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
|
|
Posted: Mon Sep 14, 2009 2:34 pm |
|
|
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 |
|
|
|
|