CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Remapping UARTs during runtime on a PIC18F25J11

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
virtuosa



Joined: 19 Jan 2014
Posts: 7

View user's profile Send private message

Remapping UARTs during runtime on a PIC18F25J11
PostPosted: Sun Jan 19, 2014 2:27 pm     Reply with quote

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: 19333

View user's profile Send private message

PostPosted: Sun Jan 19, 2014 4:03 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jan 19, 2014 4:05 pm     Reply with quote

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: 9163
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Jan 19, 2014 5:40 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jan 19, 2014 5:59 pm     Reply with quote

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: 19333

View user's profile Send private message

PostPosted: Mon Jan 20, 2014 1:23 am     Reply with quote

Sorry, I should have made it clear that you need both the fuse enabling the configuration to be changed, and the unlock.... Smile

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

View user's profile Send private message

PostPosted: Mon Jan 20, 2014 8:20 am     Reply with quote

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!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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