|
|
View previous topic :: View next topic |
Author |
Message |
rsappia
Joined: 22 Dec 2010 Posts: 12
|
[HELP!!] Change UART RX/TX pin dynamically using PPS |
Posted: Thu Dec 23, 2010 7:06 am |
|
|
Hello, I'm currently writing a piece of code that should be able to change the output and input pin of the UART using the PPS feature. I need to do this while the program is running. So far I have tried several things.. but I still cannot get it to work properly.
Here is a simple piece of code I wrote, could you tell me what I'm doing wrong here? This code is supposed to change the output of the UART1 between RB0 and RB15 and writes a message saying on which port UART1 is writing.
Here is the .h
Code: |
#include <24FJ64GA004.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 ICSP1 //ICD uses PGC1/PGD1 pins
#FUSES NOIOL1WAY //Allows multiple reconfigurations of peripheral pins
#FUSES NOWINDIS //Watch Dog Timer in Window mode
#FUSES WPOSTS16 //Watch Dog Timer PostScalar 1:32768
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES PR //Primary Oscillator
#FUSES NOCKSFSM //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES NOOSCIO //OSC2 is clock output
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES I2C1SELD
#FUSES SOSC_SEC
#FUSES WUT_DEFAULT
#word RPOR0=0x6C0
#word RPOR7=0x6CE
#word RPINR18L = 0x6A4
#bit IOLOCK = 0x742.6
#word OSCCON = 0x742
#use delay(clock=20000000)
#pin_select U1TX =PIN_B15 //busco
#pin_select U1RX=PIN_B1
#use rs232(baud=4800, UART1, ERRORS)
|
Main Code: infinite loop transmitting text using UART1
Code: |
...
unlockIO();
RPOR0 = 0x0000;
RPOR7 = 0x0300; // UART1 TXD1 ---> RP15 RB15
lockIO();
printf ("\n \r Now I use RB15");
delay_ms(50);
unlockIO();
RPOR7 = 0x0000;
RPOR0 = 0x0003; // UART1 TXD1 ---> RP0 RB0
lockIO() ;
delay_ms(1);
printf ("\n \r Now I use RB0");
|
And the Lock an UnLock for OSCCON
Code: |
void lockIO(){
#asm
mov OSCCON,w1 //OSCCON defined in .h
mov #0x0046, w2
mov #0x0057, w3
mov.b w2,w1 //Here!! I think this could be wrong...
mov.b w3,w1 //How should I write to a memory position using asm????
bset os, #6
#endasm
}
void unlockIO(){
#asm
mov OSCCON,w1
mov #0x0046, w2
mov #0x0057, w3
mov.b w2,w1
mov.b w3,w1
bclr 0x0742, #6
#endasm
}
|
I run this on Proteus and I see that both pins transmit
"\n \r Now I use RB0" and "\n \r Now I use RB15" .
I have also noticed that I'm not writing properly the OSCCON register. I have simulated this code step by step and Proteus says "Word-write to OSCCON register not supported. Use byte-write with correct enable sequence".... Does it mean that Proteus does not support this PPS feature?
I would really appreciate any kind of advice on this!! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9228 Location: Greensville,Ontario
|
|
Posted: Thu Dec 23, 2010 7:47 am |
|
|
What does your program do in the _real_ world? IE, a real PIC programmed with your code?
Gee...Proteus doesn't seem to work ???
I'm amazed at how many have blind faith in that 'simulator'.
I can think of 22 reasons why your 'program' failed,NONE have anything to do with the CCS C compiler for your PIC.
I'm sure there's a forum for Proteus, which is the first and best place to ask your question.
This forum is designed for programmers that burn real programs into real PICs and test/work/play in the real world.
Simulations are NOT the real thing ! |
|
|
rsappia
Joined: 22 Dec 2010 Posts: 12
|
|
Posted: Thu Dec 23, 2010 8:23 am |
|
|
temtronic wrote: | What does your program do in the _real_ world? IE, a real PIC programmed with your code?
Gee...Proteus doesn't seem to work ???
I'm amazed at how many have blind faith in that 'simulator'.
I can think of 22 reasons why your 'program' failed,NONE have anything to do with the CCS C compiler for your PIC.
I'm sure there's a forum for Proteus, which is the first and best place to ask your question.
This forum is designed for programmers that burn real programs into real PICs and test/work/play in the real world.
Simulations are NOT the real thing ! |
why do you attack me?
Instead of giving a helpful answer you waste your time criticising me...
First at all, I DO burn real PIC...
Just because it didnt work well i decided to try some simulation.
I was asking for help and your reply is not helpfull at all. For sure Im not doing something well in the code... and I sure you didnt read it... so please, if you have something good to say, you are welcome.
Have a great day.
Last edited by rsappia on Thu Dec 23, 2010 9:28 am; edited 1 time in total |
|
|
rsappia
Joined: 22 Dec 2010 Posts: 12
|
|
Posted: Thu Dec 23, 2010 9:24 am |
|
|
I will ask in other way so no one get offended...
I guess in this part of code im not doing well..
Code: |
void lockIO(){
#asm
mov OSCCON,w1 //OSCCON defined in .h
mov #0x0046, w2
mov #0x0057, w3
mov.b w2,w1 //Here!! I think this could be wrong...
mov.b w3,w1 //How should I write to a memory position using asm????
bset os, #6
#endasm
}
void unlockIO(){
#asm
mov OSCCON,w1
mov #0x0046, w2
mov #0x0057, w3
mov.b w2,w1
mov.b w3,w1
bclr 0x0742, #6
#endasm
}
|
How should I proceed to write a memory position using assembler senteces?
I see in microchip they use something like:
Code: |
mov.b w2,[w1] .
mov.b w3,[w1]
|
but CCS does not compile if I do so... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9228 Location: Greensville,Ontario
|
|
Posted: Thu Dec 23, 2010 10:04 am |
|
|
My answer was not an attack on you, rather that this forum is for real PICs, and NOT a Proteus simulator forum.
Simulator's are NOT reliable and are FULL of 'hidden' problems that cannot easily be diagnosed.
I'm not surprised Proteus does not work right, never seen one yet be 100% reliable in 45 years of cutting code.
However if you have real code in a real PIC, give a short, complete version of your program that can be compiled, along with the compiler version you're using and the PIC chip/die number.
This is necessary as a newer version of the PIC might have an 'errata' that the compile version you have does not correct for.
There are lots of codecutters on this site that can help with real code inside real hardware but it's beyond the scope of all of us to peer inside Proteus to see what is screwed up this time.
With respect to your error..do you have the proper RS232 drivers on both pins connected to 2 serial ports on a PC. Have you verified that the PC will accept data correctly on both ports.
Have you tried a simple loopback program that accepts data from PC on one comport to the PIC, then have the PIC loopback that data to the other comport on the PC? This will quickly show that the PIC hardware is functioning as well as the PC software.
hth |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Thu Dec 23, 2010 10:07 am |
|
|
The data sheet, simply says that IOLOCK, must be cleared or set in one operation after the 46/57 sequence.
Why not just try doing this in C?.
Code: |
#byte OSCCON=0x742
#bit IOLOCK=OSCCON.6
void unlock_io(void) {
OSCCON=0x46;
OSCCON=0x57;
IOLOCK=0;
}
void lock_io(void) {
OSCCON=0x46;
OSCCON=0x57;
IOLOCK=1;
}
|
I don't see that what they are doing, actually complies with the data sheet statement...
Best Wishes |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Thu Dec 23, 2010 10:26 am |
|
|
Ttelmah wrote: |
I don't see that what they are doing, actually complies with the data sheet statement...
Best Wishes |
As long as the C compiles to exactly the right sequence...
As for the original poster,
What PIC are you using? You need to post a short working example with your compiler version for us. it looks like you're using a 16bit PIC.
cheers,
Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Thu Dec 23, 2010 10:32 am |
|
|
Here: Directly from the datasheet for PIC24's...
Why don't people bother to read the datasheet?
Code: | //*************************************************************
// Unlock Registers
//*************************************************************
__builtin_write_OSCCONL(OSCCON & 0xbf) //clear the bit 6 of OSCCONL to
//unlock Pin Re-map
//******************************************************************
//This code is used when interested in inline assembly. If this code is
//used then the above two lines should not be used for unlocking.
//******************************************************************
/*
asm volatile ( "push w1 \n"
"push w2 \n"
"push w3 \n"
"mov #OSCCON, w1 \n"
"mov #0x46, w2 \n"
"mov #0x57, w3 \n"
"mov.b w2, [w1] \n"
"mov.b w3, [w1] \n"
"bclr OSCCON, #6 \n"
"pop w3 \n"
"pop w2 \n"
"pop w1");
*/
//************************************************************
// Configure Input Functions
//************************************************************
//***************************
// Assign U1Rx To Pin RP0
//***************************
RPINR18bits.U1RXR = 0; //"0 represents RP0
//***************************
// Assign U1CTS To Pin RP1
//***************************
RPINR18bits.U1CTSR = 1; //"1 represents RP1
//************************************************************
// Configure Output Functions
//************************************************************
//***************************
// Assign U1Tx To Pin RP2
//***************************
RPOR1bits.RP2R = 3; //"3 represents U1TX
//***************************
// Assign U1RTS To Pin RP3
//***************************
RPOR1bits.RP3R = 4; //"4 represents U1RTS
//************************************************************
// Lock Registers
//************************************************************
__builtin_write_OSCCONL(OSCCON | 0x40) //set the bit 6 of OSCCONL to
//lock Pin Re-map
//******************************************************************
//This code is used when interested in inline assembly. If this code is
//used then the above two lines should not be used for unlocking.
//******************************************************************
/*
asm volatile ( "push w1 \n"
"push w2 \n"
"push w3 \n"
"mov #OSCCON, w1 \n"
"mov #0x46, w2 \n"
"mov #0x57, w3 \n"
"mov.b w2, [w1] \n"
"mov.b w3, [w1] \n"
"bset OSCCON, #6 \n"
"pop w3 \n"
"pop w2 \n"
"pop w1;
*/ |
_________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Thu Dec 23, 2010 11:25 am |
|
|
Quote: | As long as the C compiles to exactly the right sequence... |
Unfortunately, it doesn't.
Code: | .................... OSCCON=0x46;
*
024C: MOV.B #46,W0L
024E: MOV.B W0L,742
.................... OSCCON=0x57;
0250: MOV.B #57,W0L
0252: MOV.B W0L,742
.................... IOLOCK=0;
0254: BCLR.B 742.6 |
This sequence does not write to the IOLOCK bit, as you can check e.g. with a debugger. The problem is, that OSCCON=0x57 is using two machine instructions instead of one. Curiously, CCS is using the same useless code in PCD, as I already previously mentioned in a post. PCD is intending to lock peripheral pin select registers in main startup, but it doesn't. So you can simply write to the registers without unlocking anything.
The assembly code used by rsappia has multiple errors. It's neither writing the address of OSCCON to a register nor using indirect writes, as required.
Last edited by FvM on Thu Dec 23, 2010 11:47 am; edited 1 time in total |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Thu Dec 23, 2010 11:40 am |
|
|
FvM wrote: | Quote: | As long as the C compiles to exactly the right sequence... |
Unfortunately, it doesn't.
|
Yep. Why I wrote that.
When CCS first added the PIC18Fxxj11 series, the unlock sequence was wrong and I had to write my own in assembler.
Inline assembly worked fine as long as I used "ASIS" because even a simple bclr to the unlock bit had a bank set in front of it or something goofy.
So even ASM may not be exactly the ASM you think unless you check the LST file.
Cheers,
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Thu Dec 23, 2010 12:14 pm |
|
|
Quote: | Why don't people bother to read the datasheet? |
Good question. Apparently also PCD compiler programmers at CCS don't. I missed your previous post,
because I was double checking the unlock code operation in the meantime.
Finally, referring to the original post. Although the unlock/lock code is invalid, the PPS registers are written
correctly, so the Tx pin switch should work. You can, by the way, also enable Tx output to multiple pins.
For questioned unlock/lock sequence, the below code does surely work. You don't need to save the lower work
registers, unless you are in the middle of a complex (e.g. arithmetic) compiler operation.
Code: | #asm
mov #0x742,w1
mov #0x46,w2
mov #0x57,w3
mov.b w2,[w1]
mov.b w3,[w1]
bset 0x742,#6
#endasm |
|
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Thu Dec 23, 2010 1:08 pm |
|
|
FvM wrote: | Quote: | Why don't people bother to read the datasheet? |
Good question. Apparently also PCD compiler programmers at CCS don't. |
Makes ya wonder.
It's kinda like all the DC-DC switchers I've been seeing lately that are definitely not following the layout guidelines which all typically talk about LOW IMPEDANCE PATHS... and you see like 10mil lines running to the main switching Inductor or some such. Datasheets are your FRIEND. EmBRACE them. Don't reject them lest they don't tell you the important stuff you need to know. :D _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Thu Dec 23, 2010 3:25 pm |
|
|
Actually, they are probably just suffering from the way the data sheets disagree....
If you look at the PPS section of the reference, and compare the bit mappings used with the data sheet, they differ. The text description, also differs from the example sequence. Unfortunately, while the early Microchip data sheets were 99% 'right', the current generation, seem to be taking lessons from some other companies, and are full of errors... :-(
The one thing that hasn't been mentioned, which might well stop the lock/unlock working, for the 'dynamic' change wanted, is the first line of 12.4.5.1.
"1. Disable any fixed digital peripherals on the pins to be used."
You need to turn the UART 'off', before trying to remap.
Best Wishes |
|
|
rsappia
Joined: 22 Dec 2010 Posts: 12
|
|
Posted: Thu Dec 23, 2010 3:38 pm |
|
|
temtronic wrote: | My answer was not an attack on you, rather that this forum is for real PICs, and NOT a Proteus simulator forum.
Simulator's are NOT reliable and are FULL of 'hidden' problems that cannot easily be diagnosed.
I'm not surprised Proteus does not work right, never seen one yet be 100% reliable in 45 years of cutting code.
However if you have real code in a real PIC, give a short, complete version of your program that can be compiled, along with the compiler version you're using and the PIC chip/die number.
This is necessary as a newer version of the PIC might have an 'errata' that the compile version you have does not correct for.
There are lots of codecutters on this site that can help with real code inside real hardware but it's beyond the scope of all of us to peer inside Proteus to see what is screwed up this time.
With respect to your error..do you have the proper RS232 drivers on both pins connected to 2 serial ports on a PC. Have you verified that the PC will accept data correctly on both ports.
Have you tried a simple loopback program that accepts data from PC on one comport to the PIC, then have the PIC loopback that data to the other comport on the PC? This will quickly show that the PIC hardware is functioning as well as the PC software.
hth |
Hi, PORT RS232 is working properly. I have tried using virtual ports and real ports with no problems at all... I think that the problem is how Im trying to access the OSCCON register.
I understand what you say about Proteus, but, I just consider this feature a very simple one. I usally simulate first in proteus an then download the code in real MCU and i have had no problem in several years of practice (till now!!!! )
Quote: |
The data sheet, simply says that IOLOCK, must be cleared or set in one operation after the 46/57 sequence.
Why not just try doing this in C?.
Code:
#byte OSCCON=0x742
#bit IOLOCK=OSCCON.6
void unlock_io(void) {
OSCCON=0x46;
OSCCON=0x57;
IOLOCK=0;
}
void lock_io(void) {
OSCCON=0x46;
OSCCON=0x57;
IOLOCK=1;
}
I don't see that what they are doing, actually complies with the data sheet statement...
Best Wishes
|
I also tryed this way, and it didnt work :(
Quote: |
What PIC are you using? You need to post a short working example with your compiler version for us. it looks like you're using a 16bit PIC.
cheers,
Ben
|
Im using the PIC24FJ64GA004
bkamen wrote: |
Here: Directly from the datasheet for PIC24's...
Why don't people bother to read the datasheet? ...
|
CCS does not support this assembler sintax, I also tried with this after bother myself reading the data sheet and lot of examples. What I am trying to do is something similar to what is explained in microchip's data sheet, but i know im not doing well when trying to write in OSCCON
FvM wrote: |
This sequence does not write to the IOLOCK bit, as you can check e.g. with a debugger. The problem is, that OSCCON=0x57 is using two machine instructions instead of one. Curiously, CCS is using the same useless code in PCD, as I already previously mentioned in a post. PCD is intending to lock peripheral pin select registers in main startup, but it doesn't. So you can simply write to the registers without unlocking anything.
The assembly code used by rsappia has multiple errors. It's neither writing the address of OSCCON to a register nor using indirect writes, as required.
|
I totally agree with you... my code has multiple errors!!
So you say I could go ahead and change the PPS without doing the 46/57 steps?
FvM wrote: |
PostPosted: Thu Dec 23, 2010 12:14 pm Post subject:
Quote:
Why don't people bother to read the datasheet?
Good question. Apparently also PCD compiler programmers at CCS don't. I missed your previous post,
because I was double checking the unlock code operation in the meantime.
Finally, referring to the original post. Although the unlock/lock code is invalid, the PPS registers are written
correctly, so the Tx pin switch should work. You can, by the way, also enable Tx output to multiple pins.
For questioned unlock/lock sequence, the below code does surely work. You don't need to save the lower work
registers, unless you are in the middle of a complex (e.g. arithmetic) compiler operation.
Code:
#asm
mov #0x742,w1
mov #0x46,w2
mov #0x57,w3
mov.b w2,[w1]
mov.b w3,[w1]
bset 0x742,#6
#endasm
|
THANKS!!!! I'll try it tomorrow @ first hour... here I see clearly how should I proceed to write in OSCCON address using the [ ]. |
|
|
rsappia
Joined: 22 Dec 2010 Posts: 12
|
|
Posted: Thu Dec 23, 2010 3:52 pm |
|
|
FvM wrote: | Quote: | Why don't people bother to read the datasheet? |
Good question. Apparently also PCD compiler programmers at CCS don't. I missed your previous post,
because I was double checking the unlock code operation in the meantime.
Finally, referring to the original post. Although the unlock/lock code is invalid, the PPS registers are written
correctly, so the Tx pin switch should work. You can, by the way, also enable Tx output to multiple pins.
For questioned unlock/lock sequence, the below code does surely work. You don't need to save the lower work
registers, unless you are in the middle of a complex (e.g. arithmetic) compiler operation.
Code: | #asm
mov #0x742,w1
mov #0x46,w2
mov #0x57,w3
mov.b w2,[w1]
mov.b w3,[w1]
bset 0x742,#6
#endasm |
|
This absolutely works!
Now I see OSCCON is being written
The only one thing I see... is that I'm still having TX1 assigned to RB0 and RB15 :(
Isn't it enough if I do this? :
Code: |
unlockIO();
RPOR0 = 0x0000;
RPOR7 = 0x0300; // UART1 TXD1 ---> RP15 RB15
lockIO();
printf ("\n \r Now I use RB15");
delay_ms(50);
unlockIO();
RPOR7 = 0x0000;
RPOR0 = 0x0003; // UART1 TXD1 ---> RP0 RB0
lockIO() ;
delay_ms(1);
printf ("\n \r Now I use RB0");
|
Doing RPOR0 = 0x0000; wouldn't make RB0/RB1 to get disconnected from UART1?... |
|
|
|
|
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
|