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 CCS Technical Support

Change UART setup at run time

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



Joined: 12 Jun 2019
Posts: 15

View user's profile Send private message

Change UART setup at run time
PostPosted: Mon Oct 07, 2019 2:09 am     Reply with quote

Hi,
I am doing a project with PIC18F26K40 and I want to change uart setup (pins location and baud rate) at run time.

I have written this code but it is not working

Code:
if ((bufInRS232AresseDev[3] == 0x03)&&(bufInRS232AresseDev[4] == 0x00)){
            bootMode = 1;
            sensorMode = 0;
            pin_select("U1RX", PIN_C1, TRUE, FALSE);
            pin_select("U1TX", PIN_C0, TRUE, FALSE);
            set_uart_speed(19200,ESP32);
            bootProcedure();
        }
        else if ((bufInRS232AresseDev[3] == 0x03)&&(bufInRS232AresseDev[4] == 0x99)){
            bootMode = 0;
            sensorMode = 1;
            pin_select("U1RX", PIN_B4, TRUE, FALSE);
            pin_select("U1TX", PIN_B3, TRUE, FALSE);
            set_uart_speed(115200,ESP32);
        }


I have also active the fuse NOPPS1WAY to allow several changes in PPS.
#fuse NOPPS1WAY

What am I doing wrong? Am I forgetting anything?

Thanks,
temtronic



Joined: 01 Jul 2010
Posts: 9245
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Oct 07, 2019 4:25 am     Reply with quote

While I don't use that PIC, I know that not all peripherals can be connected to every pin. Have you confirmed that those pins CAN be used for UARTS ?
Then there's the 5 volt PIC 3 volt peripheral problem. I know ESP32 is a 3 volt only device, so can you run that PIC at whatever clock speed(?) with a 3 volt VDD ? Again, the datasheet will tell you what is allowed.
I'm pretty sure that PIC has at least 2 UARTS, so do we assume the 2nd UART is already used, say to a PC ?

JAy
GL82



Joined: 12 Jun 2019
Posts: 15

View user's profile Send private message

PostPosted: Mon Oct 07, 2019 5:09 am     Reply with quote

Yes, B and C ports can be used for UART in this PIC.
There should not be problems with voltage.
I am already using the other UART for another serial communication.

Rereading the datasheet I think it is possible my code has the PPS unlocking sequence left.

However I have added this to the code

Code:
#byte PPSLOCK = getenv("SFR:PPSLOCK")
#bit PPSLOCKED = PPSLOCK.0


And then, in the start of the main

Code:
 PPSLOCKED = 0;


Unfortunately it still does not work.
Ttelmah



Joined: 11 Mar 2010
Posts: 19550

View user's profile Send private message

PostPosted: Mon Oct 07, 2019 7:24 am     Reply with quote

What compiler version?.

Current compilers unlock the port fine.

Now if yours is one that does not unlock the port, what you post won't work.
That is not how you unlock the port.
The PPSLOCKED bit can only be changed _after an unlocking sequence is
performed
_.
Code required is:
Code:

    disable_interrupts(GLOBAL);
    PPSLOCK=0x55;
    PPSLOCK=0xAA;
    PPSLOCKED=0;


The PPSLOCKED bit can only be cleared after the 0x55, 0xAA sequence
is loaded into the register without pause.
GL82



Joined: 12 Jun 2019
Posts: 15

View user's profile Send private message

PostPosted: Mon Oct 07, 2019 7:49 am     Reply with quote

The compiler version is v5.070.

I have added the code you said and know I can stop the program and check PPSLOCKED=0 (before this I always saw PPSLOCKED=1).

However the program still does not work.

It is strange that with PPSLOCKED=0 and this code the program does not work
Code:
if ((bufInRS232AresseDev[3] == 0x03)&&(bufInRS232AresseDev[4] == 0x00)){
            bootMode = 1;
            sensorMode = 0;
            pin_select("U1RX", PIN_C1, TRUE, FALSE);
            pin_select("U1TX", PIN_C0, TRUE, FALSE);
            set_uart_speed(19200,ESP32);
            bootProcedure();
        }
        else if ((bufInRS232AresseDev[3] == 0x03)&&(bufInRS232AresseDev[4] == 0x99)){
            bootMode = 0;
            sensorMode = 1;
            pin_select("U1RX", PIN_B4, TRUE, FALSE);
            pin_select("U1TX", PIN_B3, TRUE, FALSE);
            set_uart_speed(115200,ESP32);
}


What can be happening?
Ttelmah



Joined: 11 Mar 2010
Posts: 19550

View user's profile Send private message

PostPosted: Mon Oct 07, 2019 8:46 am     Reply with quote

Study the post at the top of the forum about using pin_select.

You need:


pin_select("U1RX", PIN_C1, TRUE, FALSE);
pin_select("U1TX", PIN_C0 FALSE, TRUE);

Note the pattern of TRUE/FALSE. The sequence must always begin
with a TRUE, and end with a TRUE. So to do three pins you can have

TRUE, FALSE
FALSE, FALSE
FALSE, TRUE

The pins will not function unless this sequence is correct. This is almost
certainly where your problem lies, since the compiler will normally
unlock the PPSLOCKED bit itself, and reset it after the changes are made.
GL82



Joined: 12 Jun 2019
Posts: 15

View user's profile Send private message

PostPosted: Tue Oct 08, 2019 12:23 am     Reply with quote

I think I do not understand well the function pin_select().
As I can read in CCS help

pin_select(peripheral_pin, pin, [unlock],[lock])

Where parameters:

unlock – optional parameter specifying whether to perform an unlock sequence before writing the RPINRx or RPORx register register determined by peripheral_pin and pin options. Default is TRUE if not specified. The unlock sequence must be performed to allow writes to the RPINRx and RPORx registers. This option allows calling pin_select() multiple times without performing an unlock sequence each time.

lock – optional parameter specifying whether to perform a lock sequence after writing the RPINRx or RPORx registers. Default is TRUE if not specified. Although not necessary it is a good idea to lock the RPINRx and RPORx registers from writes after all pins have been mapped. This option allows calling pin_select() multiple times without performing a lock sequence each time.


I understand of this explanation that lock/unlock sequences are made by CCS inside this function selecting TRUE/FALSE. So it is not necessary to do this lock/unlock sequence out of it.

Besides this, I do not understand why the order
TRUE, FALSE
TRUE, FALSE
is not working well. I understand that this order will not lock the registers from writes after the changes (and yeah, it makes an unlock sequence when the registers are already unlocked) but I think it should works.

Even without understanding well this function I have try to do it in 2 ways
Assuming pin_select function makes the lock/unlock sequence

Code:
if ((bufInRS232AresseDev[3] == 0x03)&&(bufInRS232AresseDev[4] == 0x00)){
            bootMode = 1;
            sensorMode = 0;
            pin_select("U1RX", PIN_C1, TRUE, FALSE);
            pin_select("U1TX", PIN_C0, FALSE, TRUE);
            set_uart_speed(19200,ESP32);
            bootProcedure();
        }
        else if ((bufInRS232AresseDev[3] == 0x03)&&(bufInRS232AresseDev[4] == 0x99)){
            bootMode = 0;
            sensorMode = 1;
            pin_select("U1RX", PIN_B4, TRUE, FALSE);
            pin_select("U1TX", PIN_B3, FALSE, TRUE);
            set_uart_speed(115200,ESP32);
            resetProcedure();
        }


Doing the lock/unlock sequence out of the function pin_select()

Code:
    if ((bufInRS232AresseDev[3] == 0x03)&&(bufInRS232AresseDev[4] == 0x00)){
            bootMode = 1;
            sensorMode = 0;
            unlock_PSS();
            pin_select("U1RX", PIN_C1, TRUE, FALSE);
            pin_select("U1TX", PIN_C0, FALSE, TRUE);
            set_uart_speed(19200,ESP32);
            lock_PSS();
            bootProcedure();
        }
        else if ((bufInRS232AresseDev[3] == 0x03)&&(bufInRS232AresseDev[4] == 0x99)){
            bootMode = 0;
            sensorMode = 1;
            unlock_PSS();
            pin_select("U1RX", PIN_B4, TRUE, FALSE);
            pin_select("U1TX", PIN_B3, FALSE, TRUE);
            set_uart_speed(115200,ESP32);
            lock_PSS();
            resetProcedure();
        }


Where lock/unlock functions are
Code:
void unlock_PSS(void)
{
    disable_interrupts(GLOBAL);
    PPSLOCK = 0x55;
    PPSLOCK = 0xAA;
    PPSLOCKED = 0;
    enable_interrupts(GLOBAL);


void lock_PSS(void)
{
    disable_interrupts(GLOBAL);
    PPSLOCK = 0x55;
    PPSLOCK = 0xAA;
    PPSLOCKED = 1;
    enable_interrupts(GLOBAL);


In both of them I have active the fuse
#fuse NOPPS1WAY

However it still does not work.
Ttelmah



Joined: 11 Mar 2010
Posts: 19550

View user's profile Send private message

PostPosted: Tue Oct 08, 2019 1:11 am     Reply with quote

You should not leave PPS 'unlocked'. It's not made clear in the data sheets,
but on some chips, the PPS selections, are only actually applied, when the
settings are locked. Hence ending with a FALSE, can leave the peripheral
unconfigured. Not sure if yours is like this, but it is much safer to end
with PPS locked.
Other things worth trying:

1) I would disable the UART before switching PPS. The data sheet
describes the setup configuration and specifically sets PPS, before
enabling the UART. In fact this is required. In one of the application
notes it refers to 'disabling peripherals' before changing PPS.

setup_uart(FALSE, ESP32);
pin_select("U1RX", PIN_C1, TRUE, FALSE);
pin_select("U1TX", PIN_C0, FALSE, TRUE);
setup_uart(19200, ESP32);

Then have you disabled the ADC on the pins you are using?. Vital.
You must have a setup_adc line, only setting the ADC to other pins.
You also need to ensure that comparator 2 is not defaulting to using
these pins (PIN B3 is the -ve input to this).
GL82



Joined: 12 Jun 2019
Posts: 15

View user's profile Send private message

PostPosted: Tue Oct 08, 2019 5:23 am     Reply with quote

Thanks for this, really very useful information
"You should not leave PPS 'unlocked'. It's not made clear in the data sheets,
but on some chips, the PPS selections, are only actually applied, when the
settings are locked. Hence ending with a FALSE, can leave the peripheral
unconfigured. Not sure if yours is like this, but it is much safer to end
with PPS locked"


I have checked the ADC and the Comparator and both of them were disabled.

Finally I have given up with the pin_select() function and I have modified directly the registers.

With these instructions the program is working well nad I can change the UART pins.

Code:
 if ((bufInRS232AresseDev[3] == 0x03)&&(bufInRS232AresseDev[4] == 0x00)){
            bootMode = 1;
            sensorMode = 0;
            setup_uart(FALSE, ESP32);
            unlock_PSS();
            RX1PPS = 0x11;
            RB3PPS = 0x0;
            RC0PPS = 0x09;
            set_uart_speed(19200,ESP32);
            lock_PSS();
            bootProcedure();
        }
        else if ((bufInRS232AresseDev[3] == 0x03)&&(bufInRS232AresseDev[4] == 0x99)){
            bootMode = 0;
            sensorMode = 1;
            setup_uart(FALSE, ESP32);
            unlock_PSS();
            RX1PPS = 0x0C;
            RC0PPS = 0x0;
            RB3PPS = 0x09;
            set_uart_speed(115200,ESP32);
            lock_PSS();
            resetProcedure();
        }


Thank you for your help Ttelmah,
Ttelmah



Joined: 11 Mar 2010
Posts: 19550

View user's profile Send private message

PostPosted: Tue Oct 08, 2019 5:53 am     Reply with quote

OK. That suggests compiler version.
Yours is quite early for the 26K40, and quite a few issues exist with the
first few compiler versions (I think the first with support for this chip was
5.064). If I remember correctly quite a few of the values in the .h
file are also wrong in these versions, and there have been threads about
these issues.
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