Forking https://os.mbed.com/users/cam/code/Modbus/ to work for NUCLEO 64 boards

Fork of Cam's original FreeModbus port (https://os.mbed.com/users/cam/code/Modbus/)

Change: - Serial implementation to work for NUCLEO 64 boards and receive interrupts instead of timer. (see `portserial.cpp`)

Added: - Custom RTU mode. Allows for external implementation of packet receiving and sending. Sends and receives packets as whole frames (address + PDU) (i.e. this was added for a custom LoRa implementation). implement `xMBRTUCustGetPDU` and `xMBRTUCustSendResponse` (see `mbport.h`) and call `eMBRTUCustomInit( address )`. implementations need to be fully initialised as `eMBRTUCustomInit` only sets the address and nothing else.

Files at this revision

API Documentation at this revision

Comitter:
danielmckinnell
Date:
Tue Aug 04 04:42:52 2020 +0000
Parent:
3:4cda95d7b6c5
Commit message:
RTU Serial updates

Changed in this revision

mbrtu.cpp Show annotated file Show diff for this revision Revisions of this file
mbrtucustom.cpp Show annotated file Show diff for this revision Revisions of this file
portserial.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/mbrtu.cpp	Mon Jan 06 01:17:26 2020 +0000
+++ b/mbrtu.cpp	Tue Aug 04 04:42:52 2020 +0000
@@ -218,6 +218,11 @@
         /* Activate the transmitter. */
         eSndState = STATE_TX_XMIT;
         vMBPortSerialEnable( FALSE, TRUE );
+        while( !pxMBFrameCBTransmitterEmpty( ) ){ 
+            // hack fix for no TX empty interrupt.
+            //  enable TX empty interrupt on Serial in portserial.cpp
+            //  and remove this.
+        };
     }
     else
     {
--- a/mbrtucustom.cpp	Mon Jan 06 01:17:26 2020 +0000
+++ b/mbrtucustom.cpp	Tue Aug 04 04:42:52 2020 +0000
@@ -75,11 +75,9 @@
     ENTER_CRITICAL_SECTION(  );
     if( xMBRTUCustGetPDU( &pucMBFrame, &usLength ) != FALSE )
     {
-
-        //TODO: check modbus CRC vs LoRa CRC (redundant if both)
-
+        //TODO:
         // usMBCRC16( ( UCHAR * ) ucRTUBuf, usRcvBufferPos ) == 0;
-        *pucRcvAddress = pucMBFrame[0]; //TODO: check this is address for modbus RTU
+        *pucRcvAddress = pucMBFrame[0];
         *ppucFrame = &pucMBFrame[1];
         *pusLength = usLength - 1; // removed address
         eStatus = MB_ENOERR;
--- a/portserial.cpp	Mon Jan 06 01:17:26 2020 +0000
+++ b/portserial.cpp	Tue Aug 04 04:42:52 2020 +0000
@@ -39,51 +39,47 @@
 #endif
 
 /* ----------------------- static functions ---------------------------------*/
-static void prvvUARTTxReadyISR( void );
+
+static void prvvUARTTxISR( void );
 static void prvvUARTRxISR( void );
-static void prvvUARTISR( void );
 
 /* ----------------------- System Variables ---------------------------------*/
-RawSerial modbus_serial(MBED_CONF_APP_MODBUS_SERIAL_TX, MBED_CONF_APP_MODBUS_SERIAL_RX); // Dan
 
-Ticker simISR;                      // Cam - mbed ticker
-                                    // we don't have the TX buff empty interrupt, so
-                                    // we just interrupt every 1 mSec and read RX & TX
-                                    // status to simulate the proper ISRs.
-
-static BOOL RxEnable, TxEnable;     // Cam - keep a static copy of the RxEnable and TxEnable
-                                    // status for the simulated ISR (ticker)
-
+static RawSerial* modbus_serial;
 
 /* ----------------------- Start implementation -----------------------------*/
-// Cam - This is called every 1mS to simulate Rx character received ISR and
-// Tx buffer empty ISR.
-// Dan - Edited to only simulate Tx buffer empty ISR.
-static void
-prvvUARTISR( void )
-{
-    if (TxEnable)
-        if(modbus_serial.writeable())
-            prvvUARTTxReadyISR();    
+
+void xMBSetSerial(RawSerial* s){
+    modbus_serial = s;
 }
 
 void
 vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
 {
-    /* If xRXEnable enable serial receive interrupts. If xTxENable enable
-     * transmitter empty interrupts.
-     */
-    RxEnable = xRxEnable;
-    TxEnable = xTxEnable;
+    if(xRxEnable){
+        modbus_serial->attach(&prvvUARTRxISR, RawSerial::RxIrq); // Dan
+    }else{
+        modbus_serial->attach(nullptr, RawSerial::RxIrq);
+    }
+
+    // if(xTxEnable){
+    //     modbus_serial->attach(&prvvUARTTxISR, RawSerial::TxIrq); // Dan
+    // }else{
+    //     modbus_serial->attach(nullptr, RawSerial::TxIrq);
+    // }
 }
 
+
+
 BOOL
 xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
 {
-    modbus_serial.attach(&prvvUARTRxISR, RawSerial::RxIrq); // Dan
-    simISR.attach_us(&prvvUARTISR,1000);    // Cam - attach prvvUARTISR to a 1mS ticker to simulate serial interrupt behaviour
-                                            // 1mS is just short of a character time at 9600 bps, so quick enough to pick
-                                            // up status on a character by character basis.
+    SerialBase::Parity p = eParity == MB_PAR_NONE ? SerialBase::None :
+        eParity == MB_PAR_EVEN ? SerialBase::Even : SerialBase::Odd;
+
+    modbus_serial->baud(ulBaudRate);
+    modbus_serial->format(ucDataBits, p);
+    
     return TRUE;
 }
 
@@ -93,7 +89,7 @@
     /* Put a byte in the UARTs transmit buffer. This function is called
      * by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been
      * called. */
-    modbus_serial.putc( ucByte);
+    modbus_serial->putc( ucByte);
     return TRUE;
 }
 
@@ -103,17 +99,12 @@
     /* Return the byte in the UARTs receive buffer. This function is called
      * by the protocol stack after pxMBFrameCBByteReceived( ) has been called.
      */
-    *pucByte = modbus_serial.getc();
+    *pucByte = modbus_serial->getc();
     return TRUE;
 }
 
-/* Create an interrupt handler for the transmit buffer empty interrupt
- * (or an equivalent) for your target processor. This function should then
- * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that
- * a new character can be sent. The protocol stack will then call 
- * xMBPortSerialPutByte( ) to send the character.
- */
-static void prvvUARTTxReadyISR( void )
+
+static void prvvUARTTxISR( void )
 {
     pxMBFrameCBTransmitterEmpty(  );
 }
@@ -126,6 +117,4 @@
 static void prvvUARTRxISR( void )
 {
     pxMBFrameCBByteReceived(  );
-}
-
-
+}
\ No newline at end of file