|
|
View previous topic :: View next topic |
Author |
Message |
GL82
Joined: 12 Jun 2019 Posts: 15
|
Change UART setup at run time |
Posted: Mon Oct 07, 2019 2:09 am |
|
|
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
|
|
Posted: Mon Oct 07, 2019 4:25 am |
|
|
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
|
|
Posted: Mon Oct 07, 2019 5:09 am |
|
|
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
Unfortunately it still does not work. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19550
|
|
Posted: Mon Oct 07, 2019 7:24 am |
|
|
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
|
|
Posted: Mon Oct 07, 2019 7:49 am |
|
|
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
|
|
Posted: Mon Oct 07, 2019 8:46 am |
|
|
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
|
|
Posted: Tue Oct 08, 2019 12:23 am |
|
|
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
|
|
Posted: Tue Oct 08, 2019 1:11 am |
|
|
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
|
|
Posted: Tue Oct 08, 2019 5:23 am |
|
|
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
|
|
Posted: Tue Oct 08, 2019 5:53 am |
|
|
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. |
|
|
|
|
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
|