View previous topic :: View next topic |
Author |
Message |
robleso7473
Joined: 25 Mar 2009 Posts: 47
|
Can you change the MSSP clock rate on the fly? |
Posted: Fri Apr 21, 2023 8:14 pm |
|
|
Hi All,
I am using PIC16F18056 MCU with the I2C function. Currently I'm setting the I2C clock rate to 400kHz with the following line:
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3,restart_wdt,force_hw)
According to table 29-2, this means the BRG counter gets loaded with 13h (with a internal 32MHz clock setting) via the SSPxADD register.
My question is:
Can you rewrite the SSPxADD register with 4Fh (to set MSSP baud rate generator to 100KHz) by simply updating SSPxADD with 4fh in the main() function? I am planning on having the user change it via UART serial console by selecting Slow or Fast on the console prompt.
Appreciate any help you can provide.
Thanks
Oscar |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sat Apr 22, 2023 1:43 am |
|
|
Look at the I2c_speed function.....
However don't do your I2C setup like this. Use:
Code: |
#PIN_SELECT SCL1OUT=PIN_C3
#PIN_SELECT SDA1=PIN_C4
#use i2c(Master,Fast=400000,I2C1)
|
With a PPS chip, this is the safe and sure way to ensure that the hardware
is used. Look at the top of the forum for the notes about this.
Also, be explicit with the baud rate you want. Though 'fast' ought
to select 400K, never trust that it will.
I2c_speed(100000);
Will then select the 100K rate.
The code actually turns the port off, then sets the BRG counter, and
turns it back on.
Also, don't use the 'restart_wdt options. This is a poorly designed setting,
which almost makes the watchdog useless, since you end up with
restart_wdt instructions throughout the code, that can be reached even
if the processor has crashed. The watchdog reset instructions should
_only_ be reachable when you have tested that the code is working
correctly. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Sat Apr 22, 2023 5:25 am |
|
|
I'm just curious...
why would you need to change the I2C bus speed ? |
|
|
robleso7473
Joined: 25 Mar 2009 Posts: 47
|
|
Posted: Sat Apr 22, 2023 11:12 am |
|
|
Hi Ttelmah,
Doh! I totally missed that one. I was worried that the I2C clock gets set in the pre-processor only once and wasn't sure if it could be updated at all. I will follow your advice on setting up I2C per your code snippet.
Regarding the restart_wdt option, are you talking about in general not to use it? Because I use that all over the place for the delay and rs232 funcitons:
#use delay(internal=32MHz,restart_wdt)
#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1,restart_wdt)
Should I remove the restart_wdt from these other two?
Thanks so much for the prompt and helpful support,
Oscar |
|
|
robleso7473
Joined: 25 Mar 2009 Posts: 47
|
|
Posted: Sat Apr 22, 2023 11:15 am |
|
|
Hi temtronic,
The reason I want to update the i2c speed during application is because our motherboard will interface with daughterboard cards that will change in the future. They require i2c interface but I can't guarantee that the i2c bus capacitance will not exceed 400pf and cause issues at 400KHz. I would like to be able to downgrade the speed to 100KHz if needed.
regards,
Oscar |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sat Apr 22, 2023 11:45 am |
|
|
Yes.
The point is that 'good' WDT coding should ensure that the watchdog
can _only_be reset, when everything is working correctly in the code.
The recommended way of coding it, is to have a reset function, that is
called, and verifies all variables are inside their recommended ranges,
all hardware is inside the required ranges, and only resets the watchdog
is this is all true. Problem otherwise is that a code crash that jumps to
an incorrect function, and is walking through the wrong part of the code,
can still reset the watchdog, making it not actually do anything useful at
all.... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Sat Apr 22, 2023 12:29 pm |
|
|
OK, I understand the 'upgrade' reason...so..
what prevents the client from selecting the wrong speed ??
My idea is that if 100KHz is an acceptable speed, just program it once and forget about future 'operator errors' !
Sometimes 'options' aren't always good. |
|
|
robleso7473
Joined: 25 Mar 2009 Posts: 47
|
|
Posted: Sat Apr 22, 2023 2:41 pm |
|
|
Hi Ttelmah,
I see your point. Normally I write such small programs that I don't put much thought into how the watchdog is used.
Thank you for the great support as always.
Oscar |
|
|
robleso7473
Joined: 25 Mar 2009 Posts: 47
|
|
Posted: Sat Apr 22, 2023 2:46 pm |
|
|
Hi temtronic,
The actual client will be me . During development stage I will be using the serial console to change speed to test it across various scenarios. Future daughterboards (not designed by my team) may present a high capacitance bus and the idea is to have the option to step down i2c clock in those cases. I'm just trying to design preemptively in case this is ever an issue. Last thing I want to do is redesign our motherboard to accommodate an outlier daughtercard.
Regards,
Oscar |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sun Apr 23, 2023 11:02 am |
|
|
Just FYI, this site gives a really good overview about a watchdog:
[url]
https://betterembsw.blogspot.com/2014/05/proper-watchdog-timer-use.html
[/url]
This line in particular is 'telling':
Quote: |
Improper use of a watchdog timer leads to a false sense of security in which software task deaths and software task time overruns are not detected, causing possible missed deadlines or partial software failures.
|
|
|
|
RamashrayChauhan
Joined: 26 Apr 2023 Posts: 1
|
|
Posted: Wed Apr 26, 2023 6:57 am |
|
|
Hi Oscar,
Yes, you can update the SSPxADD register in the main() function with a value of 4Fh to set the I2C data transfer rate to 100 kHz. To do this, you first need to set the I2C data transfer mode to Master mode, as you have done in your current code line:
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3,restart_wdt,force_hw)
Then, you can use the i2c_write() function to write the value of 4Fh to the SSPxADD register. Here's an example code:
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3,restart_wdt,force_hw)
void main() {
// Here goes your UART initialization and setup code
// Set the I2C data transfer rate to 100 kHz
i2c_start();
i2c_write(0x00); // Write device address in write mode
i2c_write(0x4F); // Write the value 4Fh to the SSPxADD register
i2c_stop();
// Here goes your main code
}
Note that before using the i2c_write() function, you must call the i2c_start() function to establish a connection with the I2C device.
Hope this helps! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Wed Apr 26, 2023 7:39 am |
|
|
Er. No.
That just sends 00, 4F out on the I2C. Doesn't do anything to the baud rate.
Completely wrong. |
|
|
|