View previous topic :: View next topic |
Author |
Message |
John5788
Joined: 08 Apr 2009 Posts: 9
|
PIC24HJ64GP504 RP pins with CAN |
Posted: Tue Jun 09, 2009 5:03 pm |
|
|
I can't seem to enable CAN properly on my PIC24HJ64GP504.
I have CAN TX on RP3 (pin 24) on the PIC and the following code:
Code: |
// before main
#word RPOR1 = 0x06C2 // CAN transmit register
|
Code: |
// at beginning of main
setup_oscillator(OSC_INTERNAL);
#asm
push w0
push w1
push w2
push w3
;OSCCONL (low byte) Unlock Sequence
MOV #0x0742, w1
MOV #0x46, w2
MOV #0x57, w3
MOV.B w2, [w1] ; Write 0x46
MOV.B w3, [w1] ; Write 0x57
; Unlock IOLOCK
MOV #0x80, w0
MOV.B w0, [w1] ; Unlock by clearing IOLOCK bit
pop w3
pop w2
pop w1
pop w0
#endasm
RPOR1 = 0b0001000000000000;
#asm
push w0
push w1
push w2
push w3
;OSCCONL (low byte) Unlock Sequence
MOV #0x0742, w1
MOV #0x46, w2
MOV #0x57, w3
MOV.B w2, [w1] ; Write 0x46
MOV.B w3, [w1] ; Write 0x57
; Lock IOLOCK
MOV #0xC0, w0
MOV.B w0, [w1] ; Lock by setting IOLOCK bit
pop w3
pop w2
pop w1
pop w0
#endasm
|
is this the correct way to set RP3 to C1TX? I am having problems with my code where I am stuck at can_tbe() returning false and not turning true. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Tue Jun 09, 2009 11:03 pm |
|
|
The code seems correct, it can be written much shorter by using C instructions, however. Also, did you check, that the PCD built-in periperal pin select setup does not work for C1TX? It generally does with recent compiler versions.
Obviuosly, there are much more reasons, why the code may fail, possible unrevealed PCD bugs and - last not least - bugs in your code. |
|
|
John5788
Joined: 08 Apr 2009 Posts: 9
|
|
Posted: Tue Jun 09, 2009 11:12 pm |
|
|
Using shorter C instructions, you mean using the preprocessor directives #pin_select ?
Haven't really given them a try yet, just configured it manually.
My code is very basic at this point. All I do is enable CAN, C1TX and C1RX on their pins, RP3 and RP2 respectively, and do a can_init() followed by an attempt to put data out using can_putd() only if can_tbe() succeeds.
can_tbe() never comes true and is stuck false. At this point I am wondering if theres a bug in the can drivers for this specific PIC? |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Wed Jun 10, 2009 11:28 am |
|
|
No, I meant accessing the SFRs in C-code, e.g.
Code: | #bit IOLOCK = 0x742.6
#byte OSCCONL = 0x742
#byte RPINR0H = 0x681
#byte RPINR18L = 0x6A4
OSCCONL = 0x46;
OSCCONL = 0x57;
IOLOCK = 0;
RPINR0H = 11; // External Interrupt 1 = RP11
RPINR18L = 9; // UART1 Receive = RP9 |
#pin_select would be the PCD built-in methode to achieve the same
To check, if the PCD built-in CAN functions or any drivers have errors, you should examine the assembly listing. |
|
|
John5788
Joined: 08 Apr 2009 Posts: 9
|
|
Posted: Wed Jun 10, 2009 4:45 pm |
|
|
The #pin_select method doesnt work
I looked at the disassembly and its not even setting C1RX when I do a #pin_select C1RX = PIN_B2. I compared the code with that line commented out and uncommented, no difference in the assembly.
Similarly, I narrowed the problem with can_tbe() coming false, the second condition in the if statement is always true:
C1TR01CON.txreqm
This condition is never false, so the can_tbe() never comes true. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Wed Jun 10, 2009 5:50 pm |
|
|
Quote: | The #pin_select method doesnt work | Yes, unfortunately.
Can you show an example, how you include and call the can-driver? |
|
|
John5788
Joined: 08 Apr 2009 Posts: 9
|
|
Posted: Thu Jun 11, 2009 2:31 pm |
|
|
I modified my code so now I am using your method to set the C1RX to RP2 and C1TX to RP3
before main:
Code: | #bit IOLOCK = 0x742.6
#byte OSCCONL = 0x742
#word RPINR26 = 0x06B4
#byte RPOR1 = 0x06C3 |
in main:
Code: | OSCCONL = 0x46;
OSCCONL = 0x57;
IOLOCK = 0;
RPOR1 = 0x10;
RPINR26 = 0x02;
OSCCONL = 0x46;
OSCCONL = 0x57;
IOLOCK = 1; |
Here is how I am calling the CAN functions
i first include the c file obviously:
Code: | #include "can-PIC24.c" |
then I do a can_init(); followed by enabling the transmit/receive buffers
Code: | can_init();
can_enable_b_transfer(TRB0);
can_enable_b_receiver(RB8); |
I debugged the code some more and found strange results, im not sure whether this is a problem with the RP pins not being configured right or what.
but when I go to send a message out using can_putd(), C1TX is sending some sort of data (3V signals), but C1RX is also mirroring it at 5V. the message is then repeated over and over again, but I cannot pick it up using any other CAN devices with the proper filters and IDs set.
I cannot receive anything when trying can_kbhit() either, the "data" that I am seeing with the scope does not change when I send different packets around. |
|
|
|