/* BigXionFlasher.c */ /* ==================================================================== * Copyright (c) 2011-2013 by Thomas König . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the * BigXionFlasher Project. (http://www.bigxionflasher.org/)" * * 4. The name "BigXionFlasher" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * info@bigxionflasher.org. * * 5. Products derived from this software may not be called "BigXionFlasher" * nor may "BigXionFlasher" appear in their names without prior written * permission of the BigXionFlasher Project. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the * BigXionFlasher Project. (http://www.bigxionflasher.org/)" * * THIS SOFTWARE IS PROVIDED BY THE BigXionFlasher PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE BigXionFlasher PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ #include #include #include #include #include #ifdef __WIN32__ #include #define DEVICE_OPEN NULL #define TREIBER_NAME "mhstcan.dll" #define _NL "\n\r" #define _DEGREE_SIGN "o" #else #define DEVICE_OPEN NULL #define TREIBER_NAME "libmhstcan.so" #define _NL "\n" #define _DEGREE_SIGN "°" #endif #include "can_drv.h" #define __DOSTR(v) #v #define __STR(v) __DOSTR(v) #define __BXF_VERSION__ "V 0.2.4 rev. 97" #define UNLIMITED_SPEED_VALUE 70 /* Km/h */ #define UNLIMITED_MIN_SPEED_VALUE 30 /* Km/h */ #define MAX_THROTTLE_SPEED_VALUE 70 /* Km/h */ //#include "registers.h" #define TIMEOUT_VALUE 80 #define TIMEOUT_US 10000 // 10ms #define BATTERY_REF_HW 1 #define BATTERY_REF_SW 1 #define BATTERY_SN_PN_HI 1 #define BATTERY_SN_PN_LO 1 #define BATTERY_SN_ITEM_HI 1 #define BATTERY_SN_ITEM_LO 1 #define BATTERY_STATUS_VBATT_HI 1 #define BATTERY_STATUS_VBATT_LO 1 #define BATTERY_STATUS_LEVEL 1 #define BATTERY_STATS_VBATTMAX 1 #define BATTERY_STATS_VBATTMIN 1 #define BATTERY_STATS_VBATTMEA 1 #define BATTERY_STATS_VBATTMEAN 1 #define BATTERY_STATS_RESET_HI 1 #define BATTERY_STATS_RESET_LO 1 #define BATTERY_STSTS_GGJSRCALIB 1 #define BATTERY_STSTS_VCTRLSHORTS 1 #define BATTERY_STATS_LMD_HI 1 #define BATTERY_STATS_LMD_LO 1 #define BATTERY_CONFIG_CELLCAPACITY_HI 1 #define BATTERY_CONFIG_CELLCAPACITY_LO 1 #define BATTERY_STATS_CHARGETIMEWORST_HI 1 #define BATTERY_STATS_CHARGETIMEWORST_LO 1 #define BATTERY_STATS_CHARGETIMEMEAN_HI 1 #define BATTERY_STATS_CHARGETIMEMEAN_LO 1 #define BATTERY_STATS_BATTCYCLES_HI 1 #define BATTERY_STATS_BATTCYCLES_LO 1 #define BATTERY_STATS_BATTFULLCYCLES_HI 1 #define BATTERY_STATS_BATTFULLCYCLES_LO 1 #define BATTERY_STATS_POWERCYCLES_HI 1 #define BATTERY_STATS_POWERCYCLES_LO 1 #define BATTERY_STATS_TBATTMAX 1 #define BATTERY_STATS_TBATTMIN 1 #define MOTOR_REF_HW 1 #define MOTOR_REF_SW 1 #define MOTOR_REALTIME_TEMP 1 #define MOTOR_SN_PN_HI 1 #define MOTOR_SN_PN_LO 1 #define MOTOR_SN_ITEM_HI 1 #define MOTOR_SN_ITEM_LO 1 #define CONSOLE_STATUS_SLAVE 1 #define BATTERY_CONFIG_SHUTDOWN 1 #define CONSOLE_ASSIST_MAXSPEEDFLAG 1 #define CONSOLE_ASSIST_MAXSPEED_HI 1 #define CONSOLE_ASSIST_MAXSPEED_LO 1 #define MOTOR_PROTECT_UNLOCK 1 #define MOTOR_PROTECT_UNLOCK_KEY 1 #define MOTOR_ASSIST_MAXSPEED 1 #define CONSOLE_GEOMETRY_CIRC_HI 1 #define CONSOLE_GEOMETRY_CIRC_LO1 #define CONSOLE_GEOMETRY_CIRC_LO 1 #define MOTOR_GEOMETRY_CIRC_HI1 #define MOTOR_GEOMETRY_CIRC_HI 1 #define MOTOR_GEOMETRY_CIRC_LO 1 #define CONSOLE_ASSIST_MINSPEEDFLAG 1 #define CONSOLE_ASSIST_MINSPEED 1 #define CONSOLE_THROTTLE_MAXSPEEDFLAG 1 #define CONSOLE_THROTTLE_MAXSPEED_HI 1 #define CONSOLE_THROTTLE_MAXSPEED_LO 1 #define BATTERY_CONFIG_PACKSERIAL 1 #define BATTERY_CELLMON_BALANCERENABLED 1 #define BATTERY_CONFIG_PACKPARALLEL 1 #define BATTERY_CELLMON_CHANNELADDR 1 #define BATTERY_CELLMON_CHANNELDATA_HI 1 #define BATTERY_STATUS_PACKTEMPERATURE1 1 #define BATTERY_CELLMON_CHANNELDATA_LO 1 #define CONSOLE_REF_HW 1 #define CONSOLE_REF_SW 1 #define CONSOLE_ASSIST_INITLEVEL 1 #define CONSOLE_SN_PN_HI 1 #define CONSOLE_SN_PN_LO 1 #define CONSOLE_SN_ITEM_HI 1 #define CONSOLE_SN_ITEM_LO 1 #define CONSOLE_ASSIST_MOUNTAINCAP 1 #define CONSOLE_STATS_BCValueTypeWord_1 1 #define CONSOLE_STATS_BCValueTypeWord_2 1 #define CONSOLE_STATS_BCValueTypeWord_3 1 #define CONSOLE_STATS_BCValueTypeWord_4 1 #define doSleep(x) usleep(x*1000) int gAssistInitLevel = -1, gPrintSystemSettings = 0, gSkipShutdown = 0, gPowerOff = 0, gConsoleSetSlaveMode = 1, gNoSerialNumbers = 0, gSetMountainCap = -1, gSetWheelCircumference = 0; double gSetSpeedLimit = -1, gSetMinSpeedLimit = -1, gSetThrottleSpeedLimit = -1; #define CONSOLE 1 #define MOTOR 2 #define BATTERY 3 #define BIB 4 char *getNodeName(unsigned char id) { if (id == CONSOLE) return "console"; else if (id == BATTERY) return "battery"; else if (id == MOTOR) return "motor"; else if (id == BIB) return "bib"; else return "UNKNOWN"; } void setValue(unsigned char receipient, unsigned char reg, unsigned char value) { struct TCanMsg msg; int timeout = TIMEOUT_VALUE; msg.MsgFlags = 0L; msg.Id = receipient; msg.MsgLen = 4; msg.MsgData[0] = 0x00; msg.MsgData[1] = reg; msg.MsgData[2] = 0x00; msg.MsgData[3] = value; CanTransmit(0, &msg, 1); while(timeout-- && CanTransmitGetCount(0)) usleep(TIMEOUT_US); if (timeout == -1) printf("error: could not send value to %s" _NL, getNodeName(receipient)); } unsigned int getValue(unsigned char receipient, unsigned char reg) { struct TCanMsg msg; int err, retry = 20; int timeout = TIMEOUT_VALUE; msg.MsgFlags = 0L; msg.Id = receipient; msg.MsgLen = 2; msg.MsgData[0] = 0x00; msg.MsgData[1] = reg; CanTransmit(0, &msg, 1); while(timeout-- && CanTransmitGetCount(0)) usleep(TIMEOUT_US); if (timeout == -1) printf("error: could not send value to node %s" _NL, getNodeName(receipient)); retry: timeout = TIMEOUT_VALUE; while(timeout-- && !CanReceiveGetCount(0)) usleep(TIMEOUT_US); if (timeout == -1) { printf("error: no response from node %s" _NL, getNodeName(receipient)); return 0; } if ((err = CanReceive(0, &msg, 1)) > 0) { if (--retry && (msg.Id != BIB || msg.MsgLen != 4 || msg.MsgData[1] != reg)) goto retry; if (!retry) { printf("error: no response from node %s to %s" _NL, getNodeName(receipient), getNodeName(BIB)); return 0; } return (unsigned int) msg.MsgData[3]; } else { printf("Error: %d" _NL, err); } return 0; } void setSpeedLimit(double speed) { int limit = (speed != 0); if (!speed) speed = UNLIMITED_SPEED_VALUE; setValue(CONSOLE, CONSOLE_ASSIST_MAXSPEEDFLAG, limit); setValue(CONSOLE, CONSOLE_ASSIST_MAXSPEED_HI, ((int)(speed * 10)) >> 8); setValue(CONSOLE, CONSOLE_ASSIST_MAXSPEED_LO, ((int)(speed * 10)) & 0xff); setValue(MOTOR, MOTOR_PROTECT_UNLOCK, MOTOR_PROTECT_UNLOCK_KEY); setValue(MOTOR, MOTOR_ASSIST_MAXSPEED, (int)speed); } void setWheelCircumference(unsigned short circumference) { if (!circumference) return; setValue(CONSOLE, CONSOLE_GEOMETRY_CIRC_HI, (int) (circumference >> 8)); setValue(CONSOLE, CONSOLE_GEOMETRY_CIRC_LO, (int) (circumference & 0xff)); setValue(MOTOR, MOTOR_PROTECT_UNLOCK, MOTOR_PROTECT_UNLOCK_KEY); setValue(MOTOR, MOTOR_GEOMETRY_CIRC_HI, (int) (circumference >> 8)); setValue(MOTOR, MOTOR_GEOMETRY_CIRC_LO, (int) (circumference & 0xff)); } void setMinSpeedLimit(double speed) { char limit = (speed != 0); setValue(CONSOLE, CONSOLE_ASSIST_MINSPEEDFLAG, limit); setValue(CONSOLE, CONSOLE_ASSIST_MINSPEED, (int)(speed * 10)); } void setThrottleSpeedLimit(double speed) { int limit = (speed != 0); if (!speed) speed = MAX_THROTTLE_SPEED_VALUE; setValue(CONSOLE, CONSOLE_THROTTLE_MAXSPEEDFLAG, limit); setValue(CONSOLE, CONSOLE_THROTTLE_MAXSPEED_HI, ((int)(speed * 10)) >> 8); setValue(CONSOLE, CONSOLE_THROTTLE_MAXSPEED_LO, ((int)(speed * 10)) & 0xff); } void printBatteryStats() { int channel = 1, packSerial, packParallel; printf( " balancer enabled ...: %s" _NL _NL, (getValue(BATTERY, BATTERY_CELLMON_BALANCERENABLED != 0) ? "yes" : "no")); packSerial = getValue(BATTERY, BATTERY_CONFIG_PACKSERIAL); packParallel = getValue(BATTERY, BATTERY_CONFIG_PACKPARALLEL); packSerial = (packSerial > 20) ? 0 : packSerial; packParallel = (packParallel > 20) ? 0 : packParallel; for (;channel <= packSerial; channel++) { setValue(BATTERY, BATTERY_CELLMON_CHANNELADDR, (int)0x80 + channel); printf(" voltage cell #%02d ...: %.3fV" _NL, channel, ((getValue(BATTERY, BATTERY_CELLMON_CHANNELDATA_HI) << 8) + getValue(BATTERY,BATTERY_CELLMON_CHANNELDATA_LO)) * 0.001); } for (channel = 0 ; channel < packParallel ; channel ++) printf(" temperature pack #%02d: %d" _DEGREE_SIGN "C" _NL, channel + 1, getValue(BATTERY, BATTERY_STATUS_PACKTEMPERATURE1 + channel)); printf(_NL); } void printChargeStats() { int channel = 1, totalChagres = 0, c; for (channel = 1 ; channel <= 10; channel++) { setValue(BATTERY, 0xf6, channel); c = (getValue(BATTERY, 0xf7) << 8) + getValue(BATTERY,0xf8); totalChagres += c; printf(" charge level @ %03d%% : %04d" _NL, channel*10, c); } printf(" total # of charges .: %04d" _NL _NL, totalChagres); } double getVoltageValue(unsigned char in, unsigned char reg) { return (getValue(BATTERY, reg) + 20.8333) * 0.416667; } void usage(void) { printf( "usage:" _NL " -l .......... set the speed limit to (1 - " __STR(UNLIMITED_SPEED_VALUE) "), 0 = remove the limit" _NL ); } int parseOptions(int argc, char **argv) { int oc; char odef[] = "l:t:m:sa:pnxio:c:h?"; while((oc = getopt(argc,argv,odef)) != -1) { switch(oc) { case 'p': gPowerOff = 1; break; case 'x': gSkipShutdown = 1; break; case 'l': gSetSpeedLimit = atof(optarg); if (gSetSpeedLimit > UNLIMITED_SPEED_VALUE || gSetSpeedLimit < 0) { printf("error: speed limit %.2f is out of range. exiting..." _NL, gSetSpeedLimit); return -1; } break; case 't': gSetThrottleSpeedLimit = atof(optarg); if (gSetThrottleSpeedLimit > MAX_THROTTLE_SPEED_VALUE || gSetThrottleSpeedLimit < 0) { printf("error: throttle speed limit %.2f is out of range. exiting..." _NL, gSetThrottleSpeedLimit); return -1; } break; case 'm': gSetMinSpeedLimit = atof(optarg); if (gSetMinSpeedLimit > UNLIMITED_MIN_SPEED_VALUE || gSetMinSpeedLimit < 0) { printf("error: min speed limit %.2f is out of range. exiting..." _NL, gSetMinSpeedLimit); return -1; } break; case 'a': gAssistInitLevel = atoi(optarg); if (gAssistInitLevel > 4 || gAssistInitLevel < 0) { printf("error: initial assist level %d is out of range. exiting..." _NL, gAssistInitLevel); return -1; } break; case 'o': gSetMountainCap = atoi(optarg); if (gSetMountainCap > 100 || gSetMountainCap < 0) { printf("error: mountain cap level %d is out of range. exiting..." _NL, gSetMountainCap); return -1; } break; case 'c': gSetWheelCircumference = atoi(optarg); if (gSetWheelCircumference > 3000 || gSetWheelCircumference < 1000) { printf("error: wheel circumference %d is out of range. exiting..." _NL, gSetWheelCircumference); return -1; } break; case 'n': gConsoleSetSlaveMode = 0; break; case 'i': gNoSerialNumbers = 1; break; case 's': gPrintSystemSettings = 1; break; case 'h': case '?': default: usage(); return -1; } } return 0; } void printSystemSettings() { int hwVersion, swVersion, wheelCirc; char *sl; double speedLimit = 0; printf(_NL _NL); hwVersion = getValue(CONSOLE, CONSOLE_REF_HW); if (hwVersion == 0) printf("Console not responding" _NL _NL); else { swVersion = getValue(CONSOLE, CONSOLE_REF_SW); printf( "Console information:" _NL " hardware version ........: %02d" _NL " software version ........: %02d" _NL " assistance level ........: %d" _NL, hwVersion, swVersion, getValue(CONSOLE, CONSOLE_ASSIST_INITLEVEL) ); if (!gNoSerialNumbers) printf( " part number .............: %05d" _NL " item number .............: %05d" _NL _NL, ((getValue(CONSOLE, CONSOLE_SN_PN_HI) << 8) + getValue(CONSOLE, CONSOLE_SN_PN_LO)), ((getValue(CONSOLE, CONSOLE_SN_ITEM_HI) << 8) + getValue(CONSOLE, CONSOLE_SN_ITEM_LO)) ); /* ASSIST speed limit */ sl = getValue(CONSOLE, CONSOLE_ASSIST_MAXSPEEDFLAG) == 0 ? (char*)"no" : (char*)"yes"; speedLimit = ((getValue(CONSOLE, CONSOLE_ASSIST_MAXSPEED_HI) << 8) + getValue(CONSOLE, CONSOLE_ASSIST_MAXSPEED_LO)) / (double)10; printf( " max limit enabled .......: %s" _NL " speed limit .............: %0.2f Km/h" _NL _NL, sl, speedLimit); /* MIN speed limit */ sl = getValue(CONSOLE, CONSOLE_ASSIST_MINSPEEDFLAG) == 0 ? (char*)"no" : (char*)"yes"; speedLimit = (getValue(CONSOLE, CONSOLE_ASSIST_MINSPEED)) / (double)10; printf( " min limit enabled .......: %s" _NL " min speed limit .........: %0.2f Km/h" _NL _NL, sl, speedLimit); /* THROTTLE speed limit */ sl = getValue(CONSOLE, CONSOLE_THROTTLE_MAXSPEEDFLAG) == 0 ? (char*)"no" : (char*)"yes"; speedLimit = ((getValue(CONSOLE, CONSOLE_THROTTLE_MAXSPEED_HI) << 8) + getValue(CONSOLE, CONSOLE_THROTTLE_MAXSPEED_LO)) / (double)10; printf( " throttle limit enabled ..: %s" _NL " throttle speed limit ....: %0.2f Km/h" _NL _NL, sl, speedLimit); /* WHEEL CIRCUMFERENCE */ wheelCirc = (getValue(CONSOLE, CONSOLE_GEOMETRY_CIRC_HI) << 8) + getValue(CONSOLE, CONSOLE_GEOMETRY_CIRC_LO); printf( " wheel circumference .....: %d mm" _NL _NL, wheelCirc); if (swVersion >= 59) printf( " mountain cap ............: %0.2f%%" _NL, (getValue(CONSOLE, CONSOLE_ASSIST_MOUNTAINCAP) * 1.5625)); printf( " odo .....................: %0.2f Km" _NL _NL, ((getValue(CONSOLE, CONSOLE_STATS_BCValueTypeWord_1) << 24) + (getValue(CONSOLE, CONSOLE_STATS_BCValueTypeWord_2) << 16) + (getValue(CONSOLE, CONSOLE_STATS_BCValueTypeWord_3) << 8) + (getValue(CONSOLE, CONSOLE_STATS_BCValueTypeWord_4))) / (double)10 ); } hwVersion = getValue(BATTERY, BATTERY_REF_HW); if (hwVersion == 0) printf("Battery not responding" _NL _NL); else { printf( "Battery information:" _NL " hardware version ........: %02d" _NL " software version ........: %02d" _NL, hwVersion, getValue(BATTERY, BATTERY_REF_SW) ); if (!gNoSerialNumbers) printf( " part number .............: %05d" _NL " item number .............: %05d" _NL, ((getValue(BATTERY, BATTERY_SN_PN_HI) << 8) + getValue(BATTERY, BATTERY_SN_PN_LO)), ((getValue(BATTERY, BATTERY_SN_ITEM_HI) << 8) + getValue(BATTERY, BATTERY_SN_ITEM_LO)) ); printf( " voltage .................: %0.2fV" _NL " battery level ...........: %0.2f%%" _NL " maximum voltage .........: %0.2f%%" _NL " minimum voltage .........: %0.2f%%" _NL " mean voltage ............: %0.2f%%" _NL " resets ..................: %0d" _NL " ggjrCalib ...............: %0d" _NL " vctrlShorts .............: %0d" _NL " lmd .....................: %0.2fAh" _NL " cell capacity ...........: %0.2fAh" _NL _NL, ((getValue(BATTERY, BATTERY_STATUS_VBATT_HI) << 8) + getValue(BATTERY, BATTERY_STATUS_VBATT_LO)) * 0.001, (getValue(BATTERY, BATTERY_STATUS_LEVEL) * 6.6667), getVoltageValue(BATTERY, BATTERY_STATS_VBATTMAX), getVoltageValue(BATTERY, BATTERY_STATS_VBATTMIN), getVoltageValue(BATTERY, BATTERY_STATS_VBATTMEAN), (getValue(BATTERY, BATTERY_STATS_RESET_HI) << 8) + getValue(BATTERY, BATTERY_STATS_RESET_LO), getValue(BATTERY, BATTERY_STSTS_GGJSRCALIB), getValue(BATTERY, BATTERY_STSTS_VCTRLSHORTS), ((getValue(BATTERY, BATTERY_STATS_LMD_HI) << 8) + getValue(BATTERY, BATTERY_STATS_LMD_LO)) * 0.002142, ((getValue(BATTERY, BATTERY_CONFIG_CELLCAPACITY_HI) << 8) + getValue(BATTERY, BATTERY_CONFIG_CELLCAPACITY_LO)) * 0.001 ); printf( " charge time worst .......: %0d" _NL " charge time mean ........: %0d" _NL " charge cycles ...........: %0d" _NL " full charge cycles ......: %0d" _NL " power cycles ............: %0d" _NL " battery temp max ........: %0d" _NL " battery temp min ........: %0d" _NL _NL, (getValue(BATTERY, BATTERY_STATS_CHARGETIMEWORST_HI) << 8) + getValue(BATTERY, BATTERY_STATS_CHARGETIMEWORST_LO), (getValue(BATTERY, BATTERY_STATS_CHARGETIMEMEAN_HI) << 8) + getValue(BATTERY, BATTERY_STATS_CHARGETIMEMEAN_LO), (getValue(BATTERY, BATTERY_STATS_BATTCYCLES_HI) << 8) + getValue(BATTERY, BATTERY_STATS_BATTCYCLES_LO), (getValue(BATTERY, BATTERY_STATS_BATTFULLCYCLES_HI) << 8) + getValue(BATTERY, BATTERY_STATS_BATTFULLCYCLES_LO), (getValue(BATTERY, BATTERY_STATS_POWERCYCLES_HI) << 8) + getValue(BATTERY, BATTERY_STATS_POWERCYCLES_HI), getValue(BATTERY, BATTERY_STATS_TBATTMAX), getValue(BATTERY, BATTERY_STATS_TBATTMIN) ); printChargeStats(); if (hwVersion >= 60) printBatteryStats(); else printf(" no battery details supported by battery hardware #%d" _NL _NL, hwVersion); } hwVersion = getValue(MOTOR, MOTOR_REF_HW); if (hwVersion == 0) printf("Motor not responding" _NL _NL); else { printf( "Motor information:" _NL " hardware version ........: %02d" _NL " software version ........: %02d" _NL //" temperature .............: %02d" _DEGREE_SIGN "C"_NL " speed limit .............: %02d Km/h" _NL, hwVersion, getValue(MOTOR, MOTOR_REF_SW), getValue(MOTOR, MOTOR_REALTIME_TEMP), getValue(MOTOR, MOTOR_ASSIST_MAXSPEED) ); wheelCirc = (getValue(MOTOR, MOTOR_GEOMETRY_CIRC_HI) << 8) + getValue(MOTOR, MOTOR_GEOMETRY_CIRC_LO); printf( " wheel circumference .....: %d mm" _NL _NL, wheelCirc); if (!gNoSerialNumbers) printf( " part number .............: %05d" _NL " item number .............: %05d" _NL _NL, ((getValue(MOTOR, MOTOR_SN_PN_HI) << 8) + getValue(MOTOR, MOTOR_SN_PN_LO)), ((getValue(MOTOR, MOTOR_SN_ITEM_HI) << 8) + getValue(MOTOR, MOTOR_SN_ITEM_LO)) ); } } int xmain(int argc, char **argv) { int err, doShutdown = 0, consoleInSlaveMode = 0; struct TDeviceStatus status; printf("BigXionFlasher USB " __BXF_VERSION__ _NL " (c) 2011-2013 by Thomas Koenig - www.bigxionflasher.org" _NL); if ((err=parseOptions(argc, argv) < 0)) exit(1); if ((err = LoadDriver(TREIBER_NAME)) < 0) { printf("LoadDriver error: %d" _NL, err); goto error; } if ((err = CanInitDriver(NULL)) < 0) { printf("CanInitDriver error: %d" _NL, err); goto error; } if ((err = CanDeviceOpen(0, DEVICE_OPEN)) < 0) { printf("CanDeviceOpen error: %d" _NL, err); goto error; } CanSetSpeed(0, CAN_125K_BIT); CanSetMode(0, OP_CAN_START, CAN_CMD_ALL_CLEAR); CanGetDeviceStatus(0, &status); if (status.DrvStatus >= DRV_STATUS_CAN_OPEN) { if (status.CanStatus == CAN_STATUS_BUS_OFF) { printf("CAN Status BusOff" _NL); CanSetMode(0, OP_CAN_RESET, CAN_CMD_NONE); } } else { printf("error: could not open device" _NL); goto error; } consoleInSlaveMode = getValue(CONSOLE, CONSOLE_STATUS_SLAVE); if (consoleInSlaveMode) { printf("console already in salve mode. good!" _NL _NL); } else { if (gConsoleSetSlaveMode) { int retry = 20; printf("putting console in salve mode ... "); do { setValue(CONSOLE, CONSOLE_STATUS_SLAVE, 1); consoleInSlaveMode = getValue(CONSOLE, CONSOLE_STATUS_SLAVE); usleep(200000); } while(retry-- && !consoleInSlaveMode); doSleep(500); // give the console some time to settle printf("%s" _NL _NL, consoleInSlaveMode ? "done" : "failed"); } else printf("console not in slave mode" _NL _NL); } if (gAssistInitLevel != -1) { printf("setting initial assistance level to %d" _NL, gAssistInitLevel); setValue(CONSOLE, CONSOLE_ASSIST_INITLEVEL, gAssistInitLevel); } if (gSetSpeedLimit > 0) { printf("set speed limit to %0.2f km/h" _NL, gSetSpeedLimit); setSpeedLimit(gSetSpeedLimit); doShutdown = 1; } else if (gSetSpeedLimit == 0) { printf("disable speed limit, drive carefully" _NL); setSpeedLimit(0); doShutdown = 1; } if (gSetMinSpeedLimit > 0) { printf("set minimal speed limit to %0.2f km/h" _NL, gSetMinSpeedLimit); setMinSpeedLimit(gSetMinSpeedLimit); doShutdown = 1; } else if (gSetMinSpeedLimit == 0) { printf("disable minimal speed limit, drive carefully" _NL); setMinSpeedLimit(0); doShutdown = 1; } if (gSetThrottleSpeedLimit > 0) { printf("set throttle speed limit to %0.2f km/h" _NL, gSetThrottleSpeedLimit); setThrottleSpeedLimit(gSetThrottleSpeedLimit); doShutdown = 1; } else if (gSetThrottleSpeedLimit == 0) { printf("disable throttle speed limit, drive carefully" _NL); setThrottleSpeedLimit(0); doShutdown = 1; } if (gSetMountainCap > 0) { printf("set mountain cap level to %0.2f%%" _NL, ((int)gSetMountainCap / 1.5625) * 1.5625); setValue(CONSOLE, CONSOLE_ASSIST_MOUNTAINCAP, gSetMountainCap / 1.5625); } if (gSetWheelCircumference > 0) { printf("set wheel circumference to %d" _NL, gSetWheelCircumference); setWheelCircumference(gSetWheelCircumference); } if (gPrintSystemSettings) printSystemSettings(); if ((doShutdown && !gSkipShutdown) || gPowerOff) { doSleep(1000); printf("shutting down system." _NL); setValue(BATTERY, BATTERY_CONFIG_SHUTDOWN, 1); } CanDownDriver(); UnloadDriver(); return 0; error: CanDownDriver(); UnloadDriver(); return 1; }