001package jmri.jmrix.sprog.update;
002
003import org.slf4j.Logger;
004import org.slf4j.LoggerFactory;
005
006/**
007 * Class to hold SPROG type
008 *
009 * @author Andrew crosland Copyright (C) 2012
010 */
011public class SprogType {
012
013    // NOTE the numerical order of thes constants is used in the bootloader
014    // to test for various SPROG types
015    public static final int UNKNOWN = 0;
016    public static final int NO_PROMPT_FOUND = 1;
017    public static final int NOT_A_SPROG = 2;
018    public static final int NOT_RECOGNISED = 3;
019    public static final int TIMEOUT = 4;
020    public static final int SPROGV4 = 10;
021    public static final int SPROGII = 20;
022    public static final int SPROGIIUSB = 21;
023    public static final int SPROGIIv3 = 23;
024    public static final int SPROGIIv4 = 24;
025    public static final int SPROG3 = 30;
026    public static final int SPROGIV = 40;
027    public static final int SPROG5 = 50;
028    public static final int PISPROGONE = 60;
029    public static final int NANO = 1000;
030    public static final int PISPROGNANO = 1001;
031    public static final int SNIFFER = 2000;
032    public int sprogType = UNKNOWN;
033
034    /**
035     * Construct a new SPROG type of a given type.
036     *
037     * @param type int, one of SprogType.xxx constants
038     */
039    public SprogType(int type) {
040        if (log.isDebugEnabled()) {
041            log.debug("SprogType(int) ctor, type: {}", type);
042        }
043        sprogType = type;
044    }
045
046    /**
047     * Check for any SPROG type
048     *
049     * @return true if this object holds a SPROG type
050     */
051    public boolean isSprog() {
052        return sprogType >= SPROGV4;
053    }
054
055    /**
056     * Check for a SPROG II type
057     *
058     * @return true if this object holds a SPROG II type
059     */
060    public boolean isSprogII() {
061        return (sprogType >= SPROGII) && (sprogType <= SPROGIIv4);
062    }
063
064    /**
065     * Return the multiplier for scaling the current limit from hardware units
066     * to physical units (mA).
067     *
068     * @return the multiplier for the current limit
069     */
070    public double getCurrentMultiplier() {
071        switch (sprogType) {
072            case PISPROGONE:
073                // Value returned is number of ADC steps 0f 3.22mV across 0.47
074                // ohms, or equivalent
075                return 3220.0/470;
076                
077            default:
078                // Value returned is number of ADC steps 0f 4.88mV across 0.47
079                // ohms, or equivalent
080                return 4880.0/470;
081        }
082    }
083    
084    /**
085     * Get the Flash memory block Length for bootloader.
086     *
087     * @return blocklen
088     */
089    public int getBlockLen() {
090        switch (sprogType) {
091            case NO_PROMPT_FOUND:
092            case NOT_A_SPROG:
093            case NOT_RECOGNISED:
094            case TIMEOUT:
095            default:
096                return -1;
097
098            case SPROGV4:
099            case SPROGIIUSB:
100            case SPROGII:
101                return 8;
102
103            case SPROGIIv3:
104            case SPROGIIv4:
105            case SPROG3:
106            case SPROGIV:
107            case SPROG5:
108            case PISPROGONE:
109            case NANO:
110            case PISPROGNANO:
111            case SNIFFER:
112                return 16;
113        }
114    }
115
116    /**
117     * Get the Flash memory block Length for bootloader.
118     *
119     * @param bootVer the bootloader version
120     * @return length in bytes
121     */
122    static public int getBlockLen(int bootVer) {
123        switch (bootVer) {
124            case 10:
125            case 11:
126                return 8;
127            case 13:
128                return 16;
129            default:
130                return -1;
131        }
132    }
133
134    /**
135     * Check if an address is one which should be reprogrammed during bootloader
136     * operation. Checks if address is above the bootloader's address space and
137     * below the debug executive's address space.
138     *
139     * @param addr int
140     * @return true or false
141     */
142    public Boolean isValidFlashAddress(int addr) {
143        switch (sprogType) {
144            case SPROGV4:
145
146            case SPROGIIUSB:
147            case SPROGII:
148                if (addr >= 0x200) {
149                    return true;
150                }
151                break;
152
153            case SPROGIIv3:
154            case SPROGIIv4:
155            case SPROG3:
156            case SPROGIV:
157            case SPROG5:
158            case NANO:
159            case SNIFFER:
160                if ((addr >= 0x2200) && (addr < 0x3F00)) {
161                    return true;
162                }
163                break;
164
165            case PISPROGNANO:
166                if ((addr >= 0x0C00) && (addr < 0x1FF0)) {
167                    return true;
168                }
169                break;
170                
171            case PISPROGONE:
172                if ((addr >= 0x1000) && (addr < 0x3E00)) {
173                    return true;
174                }
175                break;
176
177            default:
178                return false;
179        }
180        return false;
181    }
182
183    public int getEraseStart() {
184        switch (sprogType) {
185            case SPROGIIUSB:
186            case SPROGII:
187                return 0x200;
188
189            case SPROGIIv3:
190            case SPROGIIv4:
191            case SPROG3:
192            case SPROGIV:
193            case SPROG5:
194            case NANO:
195            case SNIFFER:
196                return 0x2200;
197
198            case PISPROGNANO:
199                return 0x0C00;
200
201            case PISPROGONE:
202                return 0x1000;
203
204            default:
205                break;
206        }
207        log.error("Can't determine erase start adress");
208        return -1;
209    }
210
211    /**
212     *
213     * @return String representation of a SPROG type
214     */
215    @Override
216    public String toString() {
217        return this.toString(sprogType);
218    }
219
220    /**
221     * @param t Numeric SPROG type
222     * 
223     * @return String representation of a SPROG type
224     */
225    public String toString(int t) {
226        //if (log.isDebugEnabled()) { log.debug("Integer {}", t); }
227        switch (t) {
228            case NO_PROMPT_FOUND:
229                return Bundle.getMessage("TypeNoSprogPromptFound");
230            case NOT_A_SPROG:
231                return Bundle.getMessage("TypeNotConnectedToSPROG");
232            case NOT_RECOGNISED:
233                return Bundle.getMessage("TypeUnrecognisedSPROG");
234            case TIMEOUT:
235                return Bundle.getMessage("TypeTimeoutTalkingToSPROG");
236            case SPROGV4:
237                return "SPROG ";
238            case SPROGIIUSB:
239                return "SPROG II USB ";
240            case SPROGII:
241                return "SPROG II ";
242            case SPROGIIv3:
243                return "SPROG IIv3 ";
244            case SPROGIIv4:
245                return "SPROG IIv4 ";
246            case SPROG3:
247                return "SPROG 3 ";
248            case SPROGIV:
249                return "SPROG IV ";
250            case SPROG5:
251                return "SPROG 5 ";
252            case PISPROGONE:
253                return "Pi-SPROG One ";
254            case NANO:
255                return "SPROG Nano ";
256            case PISPROGNANO:
257                return "Pi-SPROG Nano ";
258            case SNIFFER:
259                return "SPROG Sniffer ";
260            default:
261                return Bundle.getMessage("TypeUnknownHardware");
262        }
263    }
264
265    private final static Logger log = LoggerFactory.getLogger(SprogType.class);
266
267}