View previous topic :: View next topic |
Author |
Message |
WalkOver
Joined: 14 May 2021 Posts: 24
|
LIN bus built-in function source code ? |
Posted: Fri Dec 10, 2021 8:49 am |
|
|
Hello,
I'm working on LIN bus to control a LIN water pump (Pierburg CWA400) with a dsPIC33CK MCU and a MCP2021A driver.
I managed to send a command to start the pump, everything is good on scope and logic analyser...but it is working only after a power supply OFF/ON cycle.
If the +12V is already present on the LIN bus, the program hangs during linbus_header() function which is problematic for me.
Is the code for the built-in LIN functions are available somewhere ?
Or does anyone have any idea to work around the problem?
Thank you very much for your help |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Fri Dec 10, 2021 9:41 am |
|
|
Version 5.095 added Linbus support and example code in the examples folder _________________ Google and Forum Search are some of your best tools!!!! |
|
|
WalkOver
Joined: 14 May 2021 Posts: 24
|
|
Posted: Fri Dec 10, 2021 10:04 am |
|
|
Hello,
Thank you for your help but I actually forgot to specify my compiler version.
I have the last one ( 5.105 ) and I already check the included example.
I guess I'm doing everything right since it works with an automotive grade water pump...but only after a power supply OFF/ON cycle.
If the +12V is already present before the MCU init routine, the program hangs inside the linbus_header() function.
It hangs too if I manually disconnect the LIN bus from the pump.
I have to manually power OFF/ON my power supply and everything works fine again. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Fri Dec 10, 2021 11:48 am |
|
|
Understand there are not any Linbus drivers. Linbus uses at the PIC, RS232.
However that places the same restrictions on the hardware as for normal
RS232. The RX line must be high when nothing is being sent, or the receive
code will be continuously receiving. Linbus itself is just an open collector
drive into a single wire at up to 20000bps. As with RS232, it is well worth
testing the voltage level on the RX pin is high before enabling any form of
reception (especially interrupt driven). Being open collector, there has to
be a pullup to 12v somewhere on the bus. The driver chip you are using
provides a pullup when used as a slave, but not when used as a master.
Does the pump have a pullup?. It's data sheet does not say that it does.
If the line is not being pulled up to 12v, the PIC code will hang as it will
be continuously seeing data. Their example wiring shows an external 1.2K
resistor being used. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1348
|
Re: LIN bus built-in function source code ? |
Posted: Fri Dec 10, 2021 12:04 pm |
|
|
WalkOver wrote: |
Is the code for the built-in LIN functions are available somewhere ?
|
Aside from the examples already mentioned, you can look at the generated LST files to see the assembly used for each of the functions. Not as good as C code for reviewing, but it's something. |
|
|
WalkOver
Joined: 14 May 2021 Posts: 24
|
|
Posted: Fri Dec 10, 2021 1:59 pm |
|
|
Thank you everyone for your help
As specified in datasheet, I have an external 1K pull up resistor on the bus.
The MCU UART module is configured as Master.
I spotted a problem :
On top, you can see the first header break after a power supply OFF/ON cycle and the water pump respond to the command.
On the bottom, you can see the first header break after a MCU reset ( done with a PICKIT4 ). There is ( I think ) a problem with the header sync.
Instead of using the built-in functions, I write the PID in the UxP1 register (U3P1 for me ) but I have almost the same issue, now the program no longer crashes but there is the same weird header sync after a hardware reset.
When everything is working after a power supply OFF/ON cycle, if I manually disconnect the pump from the bus, I also have this header sync problem and reconnecting the pump doesn't change anything.
I have to power OFF/ON the power supply.
Do you have any idea what's going on? |
|
|
gaugeguy
Joined: 05 Apr 2011 Posts: 303
|
|
Posted: Fri Dec 10, 2021 2:25 pm |
|
|
Are you trying to use AutoBaud? A master sends the sync for the slave to use. The baud rate of the master should never be changed but it looks like your's is trying to change the baud rate. |
|
|
WalkOver
Joined: 14 May 2021 Posts: 24
|
|
Posted: Fri Dec 10, 2021 2:29 pm |
|
|
Done
Don't know why, but I have to reset and set the U3MODE.UARTEN register bit to reset the uart module in my MCU init routine.
With this trick, the LIN bus is working like a charm even after a hardware reset or after disconnecting the pump from the bus. |
|
|
WalkOver
Joined: 14 May 2021 Posts: 24
|
|
Posted: Fri Dec 10, 2021 2:31 pm |
|
|
gaugeguy wrote: | Are you trying to use AutoBaud? A master sends the sync for the slave to use. The baud rate of the master should never be changed but it looks like your's is trying to change the baud rate. |
No the baudrate is fixed at 19200 bauds. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Fri Dec 10, 2021 11:04 pm |
|
|
Glad you have it working.
Would suggest you try using the NO INIT option on the #use RS232,
then at the start of the code, wait till the RX line is seen as high, then
init the RS232.
Think what is happening is the UART is seeing one or more glitches
on it's RX line at the start.
I notice the Linbus example does not have ERRORS in it's RS232 setup.
Put this in.
Generally with CCS, if you are using the hardware UART, you _must_ either
have ERRORS in the declaration, or you need to test the UART error
bits yourself and clear if necessary.
With ERRORS there the UART will still work if it gets a framing error or
an overrun error. Without this, if either happens the UART will stop receiving.
It is a bit of a 'naughty' in some of the CCS examples, that they omit this. |
|
|
WalkOver
Joined: 14 May 2021 Posts: 24
|
|
Posted: Sun Dec 12, 2021 8:50 am |
|
|
Ttelmah wrote: | Glad you have it working.
Would suggest you try using the NO INIT option on the #use RS232,
then at the start of the code, wait till the RX line is seen as high, then
init the RS232.
Think what is happening is the UART is seeing one or more glitches
on it's RX line at the start.
I notice the Linbus example does not have ERRORS in it's RS232 setup.
Put this in.
Generally with CCS, if you are using the hardware UART, you _must_ either
have ERRORS in the declaration, or you need to test the UART error
bits yourself and clear if necessary.
With ERRORS there the UART will still work if it gets a framing error or
an overrun error. Without this, if either happens the UART will stop receiving.
It is a bit of a 'naughty' in some of the CCS examples, that they omit this. |
Hello Ttelmah,
I haven't tried yet to init the uart module after the RX line is stabilized.
But I already test and clear the OERR and the FERR bit inside the while loop.
OERR cannot be cleared in software ( silicon errata ), but never get set even when my LIN bus doesn't work anymore.
I will make more test following your advice. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Sun Dec 12, 2021 12:16 pm |
|
|
If you use an interrupt driven RX handler, it should be impossible to ever
get an OERR. Normally you have to read the byte associated with the
error as part of the clearing process. On the DsPIC's these errors are
attached to the byte where they occur. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Dec 12, 2021 4:50 pm |
|
|
You asked for the source for linbus_header().
I looked at the ASM code for CCS vs. 5.105. There are only 3 places where it waits. These are shown below.
Code: |
// This code is at the start of the function:
00004: BCF RCSTA1.CREN1 // Disable receiver
00006: BSF TXSTA1.SENDB // Send Sync Break on next transmission
00008: CLRF TXREG1
0000A: BTFSC TXSTA1.SENDB // Wait until break transmission is completed
0000C: GOTO 000A
00010: MOVLW 55
00012: MOVWF TXREG1 // Send 0x55
00014: BTFSS PIR1.TX1IF // Wait until 0x55 char is transmitted
00016: GOTO 0014
// .... A lot of code (not shown) to calculate checksum.
// This code is at the end of the function:
00066: MOVWF LINBUS_CHECKSUM_1 // Save checksum
00068: MOVWF TXREG1 // Send checksum byte
0006A: BTFSS TXSTA1.TRMT // Wait until it is transmitted
0006C: GOTO 006A
00070: BSF RCSTA1.CREN1
00072: MOVF param,W
00074: GOTO 00B8 (RETURN)
|
|
|
|
WalkOver
Joined: 14 May 2021 Posts: 24
|
|
Posted: Mon Dec 13, 2021 10:34 am |
|
|
I was a little too fast....
I'm able to send header break, header sync and PID with my own function or the built in linbus_header() function.
Everything seems to works, the pump wakes up and transmit data.
BUT, I can't read out the DATA.
With the built-in linbus_rx_response(), the program hangs.
I tried to read data with just fgetc() in the while loop and the program hangs too...
I tried with an interrupt driven RX handler ( #INT_RDA3 ) in my case,
But this time, the program hangs if I use the built-in linbus_header() function
It hangs too if I use my own Lin_send() function and the built-in fgetc function the the handler.
The best I can get is to use my own Lin_send() function and read the register U3RXREG in the handler, but the result is the PID I send and nothing more. After reading one time, the buffer is empty and I can read the other 8 bytes.
Does someone have an idea ? I want to tear my hair out.
Thank you very much |
|
|
|