Class CbusBootloaderPane

  • All Implemented Interfaces:
    java.awt.image.ImageObserver, java.awt.MenuContainer, java.io.Serializable, java.util.EventListener, javax.accessibility.Accessible, AbstractMRListener, CanListener, CanPanelInterface

    public class CbusBootloaderPane
    extends CanPanel
    implements CanListener
    Bootloader client for uploading CBUS node firmware.

    Update March 2022 A new CBUS bootloader protocol supports two new features: - Reading back device ID - Reading back bootloader ID - Positive acknowledgement (or error) for write command - Possibility fro alternative checksum algorithms.

    The module may buffer write commands in RAM, sending an immediate ACK and only writing when a FLASH page worth of data is received, which will result in a delayed ACK.

    A new command, that will be ignored by the old bootloader, is used to request the bootloader ID. If no reply is received after a suitable timeout then the original protocol will be used. The old protocol is only supported for older PIC18 K8x devices. Modules based on any other devices are expected to support the new protocol.

    See Also:
    Serialized Form
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      protected static class  CbusBootloaderPane.BootChecksum
      Bootloader checksum calculation
      protected static class  CbusBootloaderPane.BootProtocol
      Bootloader protocol
      protected static class  CbusBootloaderPane.BootState
      Bootloader state machine states
      protected static class  CbusBootloaderPane.BootStatus
      Bootloader status values
      static class  CbusBootloaderPane.Default
      Nested class to create one of these using old-style defaults.
      • Nested classes/interfaces inherited from class javax.swing.JPanel

        javax.swing.JPanel.AccessibleJPanel
      • Nested classes/interfaces inherited from class javax.swing.JComponent

        javax.swing.JComponent.AccessibleJComponent
      • Nested classes/interfaces inherited from class java.awt.Container

        java.awt.Container.AccessibleAWTContainer
      • Nested classes/interfaces inherited from class java.awt.Component

        java.awt.Component.AccessibleAWTComponent, java.awt.Component.BaselineResizeBehavior, java.awt.Component.BltBufferStrategy, java.awt.Component.FlipBufferStrategy
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void addToLog​(java.lang.String boottext)
      Add to boot loader Log
      protected boolean dataIsFiltered​(int address)
      Check if data is filtered (e.g., EEPROM selection unticked) Used only for AN247
      void dispose()
      disconnect from the CBUS
      java.util.List<javax.swing.JMenu> getMenus()
      Creates a Menu List.
      java.lang.String getTitle()
      Provide a recommended title for an enclosing frame.
      (package private) int getWriteDelay()
      Get the delay to be inserted between bootloader data writes.
      protected boolean hasActiveTimers()
      See if any timers are running, ie waiting for a response from a physical Node.
      void init()
      Not sure this comment really applies here as init() does not use the tc Don't use initComponent() as memo doesn't yet exist when that gets called.
      void initComponents​(CanSystemConnectionMemo memo)
      2nd stage of initialization, invoked after the Constructor is complete.
      (package private) boolean isProgrammingNeeded​(byte[] d)
      Is Programming Needed Check if any data bytes actually need programming
      protected void logFrame​(CanMessage m)  
      void message​(CanMessage m)
      Process some outgoing CAN frames
      (package private) void protocolError()
      Protocol Error
      void reply​(CanReply r)
      Processes incoming CAN replies
      protected void requestBootId()  
      protected void requestDevId()  
      void requestParam​(int param)
      Request a single Parameter from a Physical Node
      (package private) void sendBootEnables()
      Send the memory region write enable bit mask for CBUS bootloader protocol
      protected void sendData​(int timeout)
      Send data to the hardware and keep a running checksum
      protected void sendReset()
      Send bootloader reset frame to put the node back into operating mode.
      (package private) void showBootId​(CanReply r)
      Show the bootloader ID Major/Minor version number, checksum algorithm error report capability
      (package private) void showDevId​(CanReply r)
      Show the device ID Manufacturere and device from cbusdefs.h, device ID from the device
      protected void updateChecksum​(byte[] d)
      Add array of bytes to checksum
      (package private) void writeNextData()
      Write the next data frame for the bootloader
      (package private) void writeNextDataAn247()
      Write next data for AN247 protocol
      (package private) void writeNextDataCbus()
      Write next data for CBUS protocol
      • Methods inherited from class javax.swing.JPanel

        getAccessibleContext, getUI, getUIClassID, paramString, setUI, updateUI
      • Methods inherited from class javax.swing.JComponent

        addAncestorListener, addNotify, addVetoableChangeListener, computeVisibleRect, contains, createToolTip, disable, enable, firePropertyChange, firePropertyChange, firePropertyChange, fireVetoableChange, getActionForKeyStroke, getActionMap, getAlignmentX, getAlignmentY, getAncestorListeners, getAutoscrolls, getBaseline, getBaselineResizeBehavior, getBorder, getBounds, getClientProperty, getComponentGraphics, getComponentPopupMenu, getConditionForKeyStroke, getDebugGraphicsOptions, getDefaultLocale, getFontMetrics, getGraphics, getHeight, getInheritsPopupMenu, getInputMap, getInputMap, getInputVerifier, getInsets, getInsets, getListeners, getLocation, getMaximumSize, getMinimumSize, getNextFocusableComponent, getPopupLocation, getPreferredSize, getRegisteredKeyStrokes, getRootPane, getSize, getToolTipLocation, getToolTipText, getToolTipText, getTopLevelAncestor, getTransferHandler, getVerifyInputWhenFocusTarget, getVetoableChangeListeners, getVisibleRect, getWidth, getX, getY, grabFocus, hide, isDoubleBuffered, isLightweightComponent, isManagingFocus, isOpaque, isOptimizedDrawingEnabled, isPaintingForPrint, isPaintingOrigin, isPaintingTile, isRequestFocusEnabled, isValidateRoot, paint, paintBorder, paintChildren, paintComponent, paintImmediately, paintImmediately, print, printAll, printBorder, printChildren, printComponent, processComponentKeyEvent, processKeyBinding, processKeyEvent, processMouseEvent, processMouseMotionEvent, putClientProperty, registerKeyboardAction, registerKeyboardAction, removeAncestorListener, removeNotify, removeVetoableChangeListener, repaint, repaint, requestDefaultFocus, requestFocus, requestFocus, requestFocusInWindow, requestFocusInWindow, resetKeyboardActions, reshape, revalidate, scrollRectToVisible, setActionMap, setAlignmentX, setAlignmentY, setAutoscrolls, setBackground, setBorder, setComponentPopupMenu, setDebugGraphicsOptions, setDefaultLocale, setDoubleBuffered, setEnabled, setFocusTraversalKeys, setFont, setForeground, setInheritsPopupMenu, setInputMap, setInputVerifier, setMaximumSize, setMinimumSize, setNextFocusableComponent, setOpaque, setPreferredSize, setRequestFocusEnabled, setToolTipText, setTransferHandler, setUI, setVerifyInputWhenFocusTarget, setVisible, unregisterKeyboardAction, update
      • Methods inherited from class java.awt.Container

        add, add, add, add, add, addContainerListener, addImpl, addPropertyChangeListener, addPropertyChangeListener, applyComponentOrientation, areFocusTraversalKeysSet, countComponents, deliverEvent, doLayout, findComponentAt, findComponentAt, getComponent, getComponentAt, getComponentAt, getComponentCount, getComponents, getComponentZOrder, getContainerListeners, getFocusTraversalKeys, getFocusTraversalPolicy, getLayout, getMousePosition, insets, invalidate, isAncestorOf, isFocusCycleRoot, isFocusCycleRoot, isFocusTraversalPolicyProvider, isFocusTraversalPolicySet, layout, list, list, locate, minimumSize, paintComponents, preferredSize, printComponents, processContainerEvent, processEvent, remove, remove, removeAll, removeContainerListener, setComponentZOrder, setFocusCycleRoot, setFocusTraversalPolicy, setFocusTraversalPolicyProvider, setLayout, transferFocusDownCycle, validate, validateTree
      • Methods inherited from class java.awt.Component

        action, add, addComponentListener, addFocusListener, addHierarchyBoundsListener, addHierarchyListener, addInputMethodListener, addKeyListener, addMouseListener, addMouseMotionListener, addMouseWheelListener, bounds, checkImage, checkImage, coalesceEvents, contains, createImage, createImage, createVolatileImage, createVolatileImage, disableEvents, dispatchEvent, enable, enableEvents, enableInputMethods, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, getBackground, getBounds, getColorModel, getComponentListeners, getComponentOrientation, getCursor, getDropTarget, getFocusCycleRootAncestor, getFocusListeners, getFocusTraversalKeysEnabled, getFont, getForeground, getGraphicsConfiguration, getHierarchyBoundsListeners, getHierarchyListeners, getIgnoreRepaint, getInputContext, getInputMethodListeners, getInputMethodRequests, getKeyListeners, getLocale, getLocation, getLocationOnScreen, getMouseListeners, getMouseMotionListeners, getMousePosition, getMouseWheelListeners, getName, getParent, getPropertyChangeListeners, getPropertyChangeListeners, getSize, getToolkit, getTreeLock, gotFocus, handleEvent, hasFocus, imageUpdate, inside, isBackgroundSet, isCursorSet, isDisplayable, isEnabled, isFocusable, isFocusOwner, isFocusTraversable, isFontSet, isForegroundSet, isLightweight, isMaximumSizeSet, isMinimumSizeSet, isPreferredSizeSet, isShowing, isValid, isVisible, keyDown, keyUp, list, list, list, location, lostFocus, mouseDown, mouseDrag, mouseEnter, mouseExit, mouseMove, mouseUp, move, nextFocus, paintAll, postEvent, prepareImage, prepareImage, processComponentEvent, processFocusEvent, processHierarchyBoundsEvent, processHierarchyEvent, processInputMethodEvent, processMouseWheelEvent, remove, removeComponentListener, removeFocusListener, removeHierarchyBoundsListener, removeHierarchyListener, removeInputMethodListener, removeKeyListener, removeMouseListener, removeMouseMotionListener, removeMouseWheelListener, removePropertyChangeListener, removePropertyChangeListener, repaint, repaint, repaint, requestFocus, requestFocus, requestFocusInWindow, resize, resize, setBounds, setBounds, setComponentOrientation, setCursor, setDropTarget, setFocusable, setFocusTraversalKeysEnabled, setIgnoreRepaint, setLocale, setLocation, setLocation, setMixingCutoutShape, setName, setSize, setSize, show, show, size, toString, transferFocus, transferFocusBackward, transferFocusUpCycle
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Method Detail

      • init

        public void init()
        Not sure this comment really applies here as init() does not use the tc Don't use initComponent() as memo doesn't yet exist when that gets called. Instead, call init() function from initComponents(memo)
      • getTitle

        public java.lang.String getTitle()
        Provide a recommended title for an enclosing frame.
        Overrides:
        getTitle in class JmriPanel
        Returns:
        the title; a null value will be treated as "" by the enclosing frame
      • getMenus

        public java.util.List<javax.swing.JMenu> getMenus()
        Creates a Menu List. Provide menu items to add to a menu bar.
        Overrides:
        getMenus in class JmriPanel
        Returns:
        a list of menu items to add or an empty list
      • getWriteDelay

        int getWriteDelay()
        Get the delay to be inserted between bootloader data writes. For AN247, that has no handshaking can be slow or fast and then extended for slow writes to EEPROM and CONFIG. Only a single long timeout is used for CBUS protocol, which has full handshaking
        Returns:
        Delay in ms
      • message

        public void message​(CanMessage m)
        Process some outgoing CAN frames

        The CBUS bootloader was originally "fire and forget", with no positive acknowledgement. We had to wait an indeterminate time and assume the write was successful.

        A PIC based node will halt execution for some time ((10+ ms with newer Q series devices) whilst FLASH operations (erase and/or write) complete, during which time I/O will not be serviced. This is probably OK with CAN transport, assuming the ECAN continues to accept frames. With serial (UART) transport, as used by Pi-SPROG, the timing is much more critical as a single missed character will corrupt the node firmware.

        Furthermore, on some platforms, e.g., Raspberry Pi, there can be considerable delays between the call to the traffic controller sendMessage() method and the message being sent by the transmit thread. This may be due to Flash file system operations and could be affected by the speed of the SD card. Once the message leaves the transmit thread, we are at the mercy of the underlying OS, where there can be further delays.

        We could set an overlong timeout, but that would slow down the bootloading process in all cases.

        To improve things somewhat we wait until the message has definitely reached the TC transmit thread, by looking for bootloader data write messages here. Testing indicates this is a marked improvement with no failures observed. This is unnecessary, and not used, for the new protocol which has a positive acknowledge mechanism.

        Specified by:
        message in interface CanListener
        Parameters:
        m - CanMessage
      • reply

        public void reply​(CanReply r)
        Processes incoming CAN replies

        The bootloader is only interested in standard parameter responses and extended bootloader responses. Called when an incoming CanFrame is received from the CAN Network.

        Specified by:
        reply in interface CanListener
        Parameters:
        r - the CanReply being received.
      • showDevId

        void showDevId​(CanReply r)
        Show the device ID Manufacturere and device from cbusdefs.h, device ID from the device
        Parameters:
        r - device ID reply
      • showBootId

        void showBootId​(CanReply r)
        Show the bootloader ID Major/Minor version number, checksum algorithm error report capability
        Parameters:
        r - Bootloader ID reply
      • sendBootEnables

        void sendBootEnables()
        Send the memory region write enable bit mask for CBUS bootloader protocol
      • isProgrammingNeeded

        boolean isProgrammingNeeded​(byte[] d)
        Is Programming Needed Check if any data bytes actually need programming
        Parameters:
        d - data bytes to check
        Returns:
        false if all bytes are 0xFF, else true
      • dataIsFiltered

        protected boolean dataIsFiltered​(int address)
        Check if data is filtered (e.g., EEPROM selection unticked) Used only for AN247
        Parameters:
        address - of data record
        Returns:
        true if data is filtered and should not be written
      • sendData

        protected void sendData​(int timeout)
        Send data to the hardware and keep a running checksum
        Parameters:
        timeout - timeout for write operation
      • writeNextData

        void writeNextData()
        Write the next data frame for the bootloader
      • sendReset

        protected void sendReset()
        Send bootloader reset frame to put the node back into operating mode. There will be no reply to this.
      • updateChecksum

        protected void updateChecksum​(byte[] d)
        Add array of bytes to checksum
        Parameters:
        d - the array of bytes
      • requestParam

        public void requestParam​(int param)
        Request a single Parameter from a Physical Node

        Will not send the request if there are existing active timers. Starts Parameter timeout

        Parameters:
        param - Parameter Index Number, Index 0 is total parameters
      • hasActiveTimers

        protected boolean hasActiveTimers()
        See if any timers are running, ie waiting for a response from a physical Node.
        Returns:
        true if timers are running else false
      • addToLog

        public void addToLog​(java.lang.String boottext)
        Add to boot loader Log
        Parameters:
        boottext - String console message