|
|
View previous topic :: View next topic |
Author |
Message |
virtuosa
Joined: 19 Jan 2014 Posts: 7
|
Remapping UARTs during runtime on a PIC18F25J11 |
Posted: Sun Jan 19, 2014 2:27 pm |
|
|
Hi,
I am new to pics so please bear with this. I have been looking around for a while but no matter what I try I can not get the UARTs to swap in the main loop of my program.
From what I can see CCS does not support this as a built in function so I will need to write to the special registers directly in order to use the PPS feature. The problem I am having is that, these registers do not update their values when the code executes. It makes me think it might be an issue with IOLOCK however CCS supposedly leaves this open by default?
There is a mention of IOL1WAY register which supposedly only lets one write to these registers take affect. Perhaps CCS doesn't set this register by default? I am also not certain on how to set this either, as none of the registers I tried writing to responded.
The code I am using is as below:
Code: |
#include <C:\Program Files\PICC\Devices\18F25J11.h>
#use delay(clock=8M,int=2M)
#fuses INTRC,NOPROTECT
#PIN_SELECT RX2=PIN_C5
#PIN_SELECT TX2=PIN_C4
#use rs232(uart1,baud=9600,parity=N,bits=8,stream=PC)
#use rs232(uart2,baud=9600,parity=N,bits=8,stream=XB)
int8 RPOR12;
#byte RPOR12=0x0ED2
#word RPOR15=0xED5
int main(){
setup_comparator( NC_NC_NC_NC ); // disable comparators
setup_adc_ports( NO_ANALOGS ); // disable analog inputs
setup_adc( ADC_OFF ); // disable A2D
set_tris_c(0xB2);//set the I/O states on port C.
delay_ms(2);
delay_ms(100);
/*
#asm
MOVLW 0xFF
MOVWF 0xFC1
MOVLW 0x05
MOVWF 0xED2
#endasm*/
RPOR12=0x05;
//RPOR15=0x00;
while(1){
delay_ms(10);
putc('1',PC);
putc('2',PC);
putc('C',XB);
putc('B',XB);
//delay_ms(2);
}
return 0;
}
|
My method of setting the registers was taken from this page.
http://www.ccsinfo.com/faq.php?page=access_pic_sfr
I am not sure on how to get what version of CCS I am using but in MPLAB under the about section suite_CCSPic shows 2.0.0.7.
If I have gotten the wrong idea at some point or I am doing the register writes completely wrong then please feel free to educate me, I am very curious as to why this is not working.
Many thanks |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19516
|
|
Posted: Sun Jan 19, 2014 4:03 pm |
|
|
IOL1WAY, is set by the fuses. IOL1WAY, or NOIOL1WAY.
Defaults to IOL1WAY, since this is the 'un-programmed' state for the fuse. You need NOIOL1WAY.
Be more friendly to yourself.
Use register names. A lot of the manual and examples predate this ability, but far nicer for readability, and future debugging, to use:
#byte RPOR12 = getenv("SFR:RPOR12")
Same applies to the other registers.
You don't have to declare the int8. #byte creates a int8 variable if one doesn't exist.
However you have to perform the unlock sequence to change a pin selection. You don't need assembler, just declare the IOLOCK bit and clear it.
Code: |
#bit IOLOCK = getenv("BIT:IOLOCK")
#byte EECON2 = getenv("SFR:EECON2")
#byte RPOR12 = getenv("SFR:RPOR12")
#byte RPOR15 = getenv("SFR:RPOR15")
#define DISCONNECT 0
#define TX2 5
EECON2=0x55;
EECON2=0xAA; //unlock
IOLOCK=FALSE; //PPS writeable
RPOR15=DISCONNECT;
RPOR12=TX2; //move TX2 to C1
EECON2=0x55;
EECON2=0xAA; //lock
IOLOCK=TRUE; //PPS write protected
|
Note disconnecting TX2 from C4, then moving it to C1.
Best Wishes |
|
|
virtuosa
Joined: 19 Jan 2014 Posts: 7
|
|
Posted: Sun Jan 19, 2014 4:05 pm |
|
|
Just an update, I don't know if I am still doing something wrong but I tried writing a value to the EECON2 register (testing the IOLOCK unlock sequence). When I did this I was unable to get the value to change.
The new version is shown below, neither the "C" method or ASM code seem to affect it. I am using the view special registers menu in MPLAB if that helps.
Code: | #include <C:\Program Files\PICC\Devices\18F25J11.h>
#use delay(clock=8M,int=2M)
#fuses INTRC,NOPROTECT
#PIN_SELECT RX2=PIN_C5
#PIN_SELECT TX2=PIN_C4
#use rs232(uart1,baud=9600,parity=N,bits=8,stream=PC)
#use rs232(uart2,baud=9600,parity=N,bits=8,stream=XB)
int8 RPOR12;
//int8 EECON2;
#byte RPOR12=0x0ED2
#word RPOR15=0xED5
#byte EECON2=0xFA7
int main(){
EECON2=0x55;
#asm
MOVLB 0x0E // Bank 14
MOVLW 0x55 // 1st unlock code into W
MOVWF EECON2 // 1st unlock code from W to EECON2
MOVLW 0xAA // 2nd unlock code into W
MOVWF EECON2 // 2nd unlock code from W into EECON2
#endasm#
setup_comparator( NC_NC_NC_NC ); // disable comparators
setup_adc_ports( NO_ANALOGS ); // disable analog inputs
setup_adc( ADC_OFF ); // disable A2D
set_tris_c(0xB2);//set the I/O states on port C.
delay_ms(2);
delay_ms(100);
/*
#asm
MOVLW 0xFF
MOVWF 0xFC1
MOVLW 0x05
MOVWF 0xED2
#endasm*/
RPOR12=0x05;
//RPOR15=0x00;
while(1){
delay_ms(10);
putc('1',PC);
putc('2',PC);
putc('C',XB);
putc('B',XB);
//delay_ms(2);
}
return 0;
} |
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9228 Location: Greensville,Ontario
|
|
Posted: Sun Jan 19, 2014 5:40 pm |
|
|
I'm just a tad curious here...why do you want to 'remap' the UARTs?
Traditionally UARTs are tied to hardware/software specific 'devices' following a protocol. Seems like you can get into a LOT of trouble if your program thinks you're talking to 'A' when really it's 'B'.
jay |
|
|
virtuosa
Joined: 19 Jan 2014 Posts: 7
|
|
Posted: Sun Jan 19, 2014 5:59 pm |
|
|
Ttelmah, I have updated my code with your ideas and the remapping function is working fine, thank you very much for your input on that.
It seems that both the NOIOL1WAY fuse and the unlock sequence are needed for it to work. One thing which I am still confused about, but you might be able to shed light is the EECON2 register not showing changes.
In the special register window when stepping through the code I do not see the data that is written to EECON2, however without those lines the remapping will not work. Is there an intuitive reason for this?
My updated code is below.
Code: |
#include <C:\Program Files\PICC\Devices\18F25J11.h>
#use delay(clock=8M,int=2M)
#fuses INTRC,NOPROTECT,NOIOL1WAY
#PIN_SELECT RX2=PIN_C5
#PIN_SELECT TX2=PIN_C4
#use rs232(uart1,baud=9600,parity=N,bits=8,stream=PC)
#use rs232(uart2,baud=9600,parity=N,bits=8,stream=XB)
#bit IOLOCK = getenv("BIT:IOLOCK")
#byte EECON2 = getenv("SFR:EECON2")
//#byte EECON2=0xFA7
#byte RPOR12 = getenv("SFR:RPOR12")
//#byte RPOR12=0xED2
#byte RPOR15 = getenv("SFR:RPOR15")
#define DISCONNECT 0
#define TX2 5
int main(){
setup_comparator( NC_NC_NC_NC ); // disable comparators
setup_adc_ports( NO_ANALOGS ); // disable analog inputs
setup_adc( ADC_OFF ); // disable A2D
//set_tris_c(0xB2);//set the I/O states on port C.
EECON2=0x55;
EECON2=0xAA; //unlock
IOLOCK=FALSE; //PPS writeable
RPOR15=DISCONNECT;
RPOR12=TX2; //move TX2 to C1
EECON2=0x55;
EECON2=0xAA; //lock
IOLOCK=TRUE; //PPS write protected
delay_ms(2);
delay_ms(100);
while(1){
delay_ms(100);
delay_ms(100);
putc('1',PC);
putc('2',PC);
putc('C',XB);
putc('B',XB);
//delay_ms(2);
}
return 0;
} |
Temtronic, I can appreciate the concern, and usually I would not bother, however I need to have 3 UARTs preferable, so I was thinking of just multiplexing one of the UARTs, that way no external hardware or other things are needed. The data rate and APIs going over the UART are distinct and do not require a high data rate, thus this approach should be ideal. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19516
|
|
Posted: Mon Jan 20, 2014 1:23 am |
|
|
Sorry, I should have made it clear that you need both the fuse enabling the configuration to be changed, and the unlock....
I guessed that you were perhaps trying to implement 'UART switching'.
Remember to ensure the TX lines are 'high', when the UART is disconnected from them.
EECON2, is not a physical register (look at the data sheet). Just writing particular values 'to' it (it cannot be read), 'trigger' particular settings in the hardware. If you look at page 63 in the data sheet, you will see that all bits of it are mapped as 'unimplemented bits'.
Best Wishes |
|
|
virtuosa
Joined: 19 Jan 2014 Posts: 7
|
|
Posted: Mon Jan 20, 2014 8:20 am |
|
|
Thank you for clarifying about EECON2, I did have a look at the datasheet, but not the right section ( silly me!). I agree with you now, and it all makes sense.
Your explanation made perfect sense (which is why I did both), however I was just reaffirming that both are needed in case somebody else reads this in the future.
I will be sure to make sure that the pin is pulled up so it idles high. Thaank you for your help and expertise, very impressive overall! |
|
|
|
|
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
|