001package jmri.jmrix.can.cbus.swing.bootloader; 002 003import static jmri.jmrix.can.cbus.CbusConstants.MANU_MERG; 004import static jmri.jmrix.can.cbus.node.CbusNodeConstants.*; 005 006/** 007 * Extend hex file class for a CBUS PIC with parameter block 008 * 009 * Assumes hex record addresses are "nicely" aligned, i.e., on 8, 16, 32, ... 010 * -byte boundaries and that addresses increase monotonically. With Microchip 011 * tools you should select the options to format the hex file for download and 012 * program with default config words. 013 * 014 * @author Andrew Crosland Copyright (C) 2022 015 */ 016public class CbusPicHexFile extends HexFile{ 017 018 public static final int PARAM_OLD_START = 0x810; 019 public static final int PARAM_OLD_END = 0x817; 020 public static final int PARAM_OLD_LEN = 7; 021 public static final int PARAM_NEW_START = 0x820; 022 public static final int PARAM_NEW_END = 0x839; 023 public static final int PARAM_NEW_LEN = 32; 024 025 private CbusParameters newParams = new CbusParameters(); 026 private CbusParameters oldParams = new CbusParameters(); 027 028 private boolean checkValid = false; 029 030 /** 031 * Create a new HexFile object and initialize data to unprogrammed state. 032 * 033 * @param fileName file name to use for the hex file 034 */ 035 public CbusPicHexFile(String fileName) { 036 super(fileName); 037 } 038 039 040 /** 041 * Check one hex record from the file 042 * 043 * Overridden to capture CBUS PIC parameter block. 044 * 045 * Assumes hex record addresses are "nicely" aligned, i.e., on 8, 16, 32, ... 046 * -byte boundaries and that addresses increase monotonically. With Microchip 047 * tools you should select the options to format the hex file for download 048 * and program with default config words. 049 * 050 * @param r hex record 051 */ 052 @Override 053 protected void checkRecord(HexRecord r) { 054 int rStart = 0; 055 int rEnd = 0; 056 int pStart = 0; 057 int checksum = 0; 058 059 if (r.type == HexRecord.TYPE_DATA) { 060 // Look for "old" 8-byte paraneter block at 0x810, assuming aligned hex address 061 if (r.address == PARAM_OLD_START) { 062 for (int i = 0; i <= PARAM_OLD_LEN; i++) { 063 oldParams.setParam(pStart++, r.getData(i) & 0xFF); 064 } 065 checkValid = true; 066 } else { 067 // Look for "new" 32-byte parameter block starting at 0x820 068 if ((r.address < PARAM_NEW_START) && (r.address + r.len > PARAM_NEW_START)) { 069 // Record overlaps at start. Should only happen if record is greater than 32 bytes 070 // and encompasses the whole parameter block. 071 rStart = PARAM_NEW_START - r.address; 072 pStart = 1; 073 if (r.len > PARAM_NEW_LEN) { 074 rEnd = rStart + PARAM_NEW_LEN; 075 } else { 076 rEnd = rStart + r.len; 077 } 078 checkValid = true; 079 } else if ((r.address >= PARAM_NEW_START) && (r.address < PARAM_NEW_END)) { 080 // Record starts within the parameter block. Should only happen for 081 // 32, 16 or 8-byte records and we want all the data in the record. 082 rStart = 0; 083 rEnd = r.len; 084 pStart = r.address - 0x820 + 1; 085 checkValid = true; 086 } 087 088 if (checkValid) { 089 // Copy data to parameters and add to checksum 090 for (int i = rStart; i < rEnd; i++) { 091 newParams.setParam(pStart++, r.getData(i) & 0xFF); 092 checksum += r.getData(i) & 0xFF; 093 } 094 } 095 } 096 097 if ((r.address >= PARAM_NEW_END) && (checkValid == true)) { 098 // First record after parameter block so check if parameters are 099 checkValid = false; 100 // Copy new parameter count to parameter 101 newParams.setParam(NUM_PARAM_IDX, newParams.getParam(PARAM_COUNT_IDX)); 102 if (checksum == 0) { 103 newParams.setValid(true); 104 } else if (oldParams.getParam(MANU_ID_IDX) == (byte)MANU_MERG) { 105 // Assume old style parameter block @ 0x810 and assume only MERG made these 106 oldParams.setParam(NUM_PARAM_IDX, PARAM_OLD_LEN); 107 oldParams.setValid(true); 108 } 109 } 110 } 111 } 112 113 /** 114 * Get the file parameters 115 * 116 * Create an invalid parameter set of necessary 117 * 118 * @return CBUS parameters from the file 119 */ 120 @Override 121 public CbusParameters getParams() { 122 if (newParams.areValid()) { 123 return newParams; 124 } else if (oldParams.areValid()) { 125 return oldParams; 126 } else 127 return new CbusParameters(); 128 } 129 130// private final static Logger log = LoggerFactory.getLogger(CbusPicHexFile.class); 131 132}