Class CbusBootloaderPane
- java.lang.Object
-
- java.awt.Component
-
- java.awt.Container
-
- javax.swing.JComponent
-
- javax.swing.JPanel
-
- jmri.util.swing.JmriPanel
-
- jmri.jmrix.can.swing.CanPanel
-
- jmri.jmrix.can.cbus.swing.bootloader.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 calculationprotected static class
CbusBootloaderPane.BootProtocol
Bootloader protocolprotected static class
CbusBootloaderPane.BootState
Bootloader state machine statesprotected static class
CbusBootloaderPane.BootStatus
Bootloader status valuesstatic 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
-
-
Field Summary
Fields Modifier and Type Field Description protected int
bootAddress
protected CbusBootloaderPane.BootChecksum
bootChecksum
protected CbusBootloaderPane.BootProtocol
bootProtocol
protected CbusBootloaderPane.BootState
bootState
(package private) BusyDialog
busyDialog
protected int
checksum
protected javax.swing.JCheckBox
configCheckBox
protected HexRecord
currentRecord
protected int
dataFramesSent
protected int
dataTimeout
protected javax.swing.JCheckBox
eepromCheckBox
(package private) CbusParameters
fileParams
(package private) CbusParameters
hardwareParams
(package private) HexFile
hexFile
(package private) javax.swing.JFileChooser
hexFileChooser
(package private) boolean
hexForBootloader
protected javax.swing.JCheckBox
moduleCheckBox
(package private) int
nextParam
(package private) int
nodeNumber
protected javax.swing.JTextField
nodeNumberField
protected javax.swing.JButton
openFileChooserButton
protected javax.swing.JButton
programButton
protected javax.swing.JButton
readNodeParamsButton
protected boolean
recordDone
protected int
recordIndex
-
Fields inherited from class javax.swing.JComponent
listenerList, TOOL_TIP_TEXT_KEY, ui, UNDEFINED_CONDITION, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, WHEN_FOCUSED, WHEN_IN_FOCUSED_WINDOW
-
-
Constructor Summary
Constructors Constructor Description CbusBootloaderPane()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
addToLog(java.lang.String boottext)
Add to boot loader Logprotected boolean
dataIsFiltered(int address)
Check if data is filtered (e.g., EEPROM selection unticked) Used only for AN247void
dispose()
disconnect from the CBUSjava.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 programmingprotected void
logFrame(CanMessage m)
void
message(CanMessage m)
Process some outgoing CAN frames(package private) void
protocolError()
Protocol Errorvoid
reply(CanReply r)
Processes incoming CAN repliesprotected 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 protocolprotected void
sendData(int timeout)
Send data to the hardware and keep a running checksumprotected 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 deviceprotected 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 jmri.jmrix.can.swing.CanPanel
getMemo, initContext, prependConnToString
-
Methods inherited from class jmri.util.swing.JmriPanel
getHelpTarget, getMinimumDimension, getWindowInterface, initComponents, isMultipleInstances, setWindowInterface
-
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
-
Methods inherited from interface jmri.jmrix.can.CanListener
addTc, addTc, removeTc, removeTc
-
-
-
-
Field Detail
-
nodeNumberField
protected javax.swing.JTextField nodeNumberField
-
configCheckBox
protected javax.swing.JCheckBox configCheckBox
-
eepromCheckBox
protected javax.swing.JCheckBox eepromCheckBox
-
moduleCheckBox
protected javax.swing.JCheckBox moduleCheckBox
-
programButton
protected javax.swing.JButton programButton
-
openFileChooserButton
protected javax.swing.JButton openFileChooserButton
-
readNodeParamsButton
protected javax.swing.JButton readNodeParamsButton
-
hexFileChooser
final javax.swing.JFileChooser hexFileChooser
-
hardwareParams
CbusParameters hardwareParams
-
fileParams
CbusParameters fileParams
-
hexForBootloader
boolean hexForBootloader
-
nodeNumber
int nodeNumber
-
nextParam
int nextParam
-
currentRecord
protected HexRecord currentRecord
-
recordIndex
protected int recordIndex
-
recordDone
protected boolean recordDone
-
busyDialog
BusyDialog busyDialog
-
bootProtocol
protected CbusBootloaderPane.BootProtocol bootProtocol
-
bootChecksum
protected CbusBootloaderPane.BootChecksum bootChecksum
-
bootState
protected CbusBootloaderPane.BootState bootState
-
bootAddress
protected int bootAddress
-
checksum
protected int checksum
-
dataFramesSent
protected int dataFramesSent
-
dataTimeout
protected int dataTimeout
-
-
Constructor Detail
-
CbusBootloaderPane
public CbusBootloaderPane()
-
-
Method Detail
-
initComponents
public void initComponents(CanSystemConnectionMemo memo)
2nd stage of initialization, invoked after the Constructor is complete.This needs to be connected to the initContext() method in implementing classes.
- Specified by:
initComponents
in interfaceCanPanelInterface
- Overrides:
initComponents
in classCanPanel
- Parameters:
memo
- system connection.
-
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.
-
getMenus
public java.util.List<javax.swing.JMenu> getMenus()
Creates a Menu List. Provide menu items to add to a menu bar.
-
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 framesThe 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 interfaceCanListener
- Parameters:
m
- CanMessage
-
reply
public void reply(CanReply r)
Processes incoming CAN repliesThe 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 interfaceCanListener
- 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
-
protocolError
void protocolError()
Protocol Error
-
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
-
logFrame
protected void logFrame(CanMessage m)
-
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
-
writeNextDataAn247
void writeNextDataAn247()
Write next data for AN247 protocol
-
writeNextDataCbus
void writeNextDataCbus()
Write next data for CBUS protocol
-
writeNextData
void writeNextData()
Write the next data frame for the bootloader
-
requestDevId
protected void requestDevId()
-
requestBootId
protected void requestBootId()
-
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 NodeWill 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
-
-