Dual Brushless Motor ESC, 10-62V, up to 50A per motor. Motors ganged or independent, multiple control input methods, cycle-by-cycle current limit, speed mode and torque mode control. Motors tiny to kW. Speed limit and other parameters easily set in firmware. As used in 'The Brushless Brutalist' locomotive - www.jons-workshop.com. See also Model Engineer magazine June-October 2019.
Dependencies: mbed BufferedSerial Servo PCT2075 FastPWM
Update 17th August 2020 Radio control inputs completed
24LC64_eeprom.cpp@17:cc9b854295d6, 2020-08-16 (annotated)
- Committer:
- JonFreeman
- Date:
- Sun Aug 16 14:13:19 2020 +0000
- Revision:
- 17:cc9b854295d6
- Parent:
- 16:d1e4b9ad3b8b
August 2020. Checked Radio Control input ops.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
JonFreeman | 0:435bf84ce48a | 1 | #include "mbed.h" |
JonFreeman | 13:ef7a06fa11de | 2 | #include "STM3_ESC.h" |
JonFreeman | 0:435bf84ce48a | 3 | #include "BufferedSerial.h" |
JonFreeman | 0:435bf84ce48a | 4 | extern BufferedSerial pc; |
JonFreeman | 12:d1d21a2941ef | 5 | extern error_handling_Jan_2019 ESC_Error ; // Provides array usable to store error codes. |
JonFreeman | 3:ecb00e0e8d68 | 6 | // Code for 24LC64 8k x 8 bit eeprom |
JonFreeman | 0:435bf84ce48a | 7 | // Code based on earlier work using memory FM24W256, also at i2c address 0xa0; |
JonFreeman | 12:d1d21a2941ef | 8 | |
JonFreeman | 16:d1e4b9ad3b8b | 9 | const int addr_rd = 0xa1; // set bit 0 for read, clear bit 0 for write 24LC64 |
JonFreeman | 16:d1e4b9ad3b8b | 10 | const int addr_wr = 0xa0; // set bit 0 for read, clear bit 0 for write 24LC64 |
JonFreeman | 16:d1e4b9ad3b8b | 11 | const int ACK = 1; |
JonFreeman | 16:d1e4b9ad3b8b | 12 | /*struct optpar { |
JonFreeman | 16:d1e4b9ad3b8b | 13 | int min, max, de_fault; // min, max, default |
JonFreeman | 16:d1e4b9ad3b8b | 14 | const char * txt; // description |
JonFreeman | 12:d1d21a2941ef | 15 | } ; |
JonFreeman | 16:d1e4b9ad3b8b | 16 | */ |
JonFreeman | 16:d1e4b9ad3b8b | 17 | struct optpar option_list[] = { |
JonFreeman | 16:d1e4b9ad3b8b | 18 | {0, 1, 1, "MotorA direction [0 or 1]"}, // MOTADIR |
JonFreeman | 16:d1e4b9ad3b8b | 19 | {0, 1, 0, "MotorB direction [0 or 1]"}, // MOTBDIR |
JonFreeman | 16:d1e4b9ad3b8b | 20 | {4, 8, 8, "MotorA poles 4 or 6 or 8"}, // MOTAPOLES |
JonFreeman | 16:d1e4b9ad3b8b | 21 | {4, 8, 8, "MotorB poles 4 or 6 or 8"}, // MOTBPOLES |
JonFreeman | 16:d1e4b9ad3b8b | 22 | {1, 4, 1, "MotorA 0R05 shunt Rs 1 to 4"}, // ISHUNTB |
JonFreeman | 16:d1e4b9ad3b8b | 23 | {1, 4, 1, "MotorB 0R05 shunt Rs 1 to 4"}, // ISHUNTB |
JonFreeman | 16:d1e4b9ad3b8b | 24 | {10, 50, 20, "POT_REGBRAKE_RANGE percentage 10 to 50"}, // POT_REGBRAKE_RANGE |
JonFreeman | 16:d1e4b9ad3b8b | 25 | {0, 1, 0, "Servo1 out 0 = Disabled, 1= Output enabled"}, // SVO1 |
JonFreeman | 16:d1e4b9ad3b8b | 26 | {0, 1, 0, "Servo2 out 0 = Disabled, 1= Output enabled"}, // SVO2 |
JonFreeman | 16:d1e4b9ad3b8b | 27 | {0, 2, 0, "RC Input1 0 = Not used, 1= Uni_dir, 2= Bi_dir"}, // RCIN1 |
JonFreeman | 16:d1e4b9ad3b8b | 28 | {0, 2, 0, "RC Input2 0 = Not used, 1= Uni_dir, 2= Bi_dir"}, // RCIN2 |
JonFreeman | 16:d1e4b9ad3b8b | 29 | {2, 6, 2, "Command source 2= COM2 (Touch Screen), 3= Pot, 4= RCIn1, 5= RCIn2, 6=RCin_both"}, // COMM_SRC |
JonFreeman | 16:d1e4b9ad3b8b | 30 | {'1', '9', '0', "Alternative ID ascii '1' to '9'"}, // BOARD_ID defaults to '0' before eerom setup for first time |
JonFreeman | 16:d1e4b9ad3b8b | 31 | {10, 250, 60, "Top speed MPH, range 1.0 to 25.0"}, // New Jan 2019 TOP_SPEED |
JonFreeman | 16:d1e4b9ad3b8b | 32 | {50, 253, 98, "Wheel diameter mm"}, // New 01/06/2018 |
JonFreeman | 16:d1e4b9ad3b8b | 33 | {10, 253, 27, "Motor pinion"}, // New 01/06/2018 |
JonFreeman | 16:d1e4b9ad3b8b | 34 | {50, 253, 85, "Wheel gear"}, // New 01/06/2018 ** NOTE this and above two used to calculate RPM to MPH ** |
JonFreeman | 16:d1e4b9ad3b8b | 35 | {0, 255, 12, "RC in 1 trim"}, // New Dec 2019 RCI1_TRIM read as 2's complement (-128 to +127), user enters -128 to +127 |
JonFreeman | 16:d1e4b9ad3b8b | 36 | {0, 255, 12, "RC in 2 trim"}, // New Dec 2019 RCI2_TRIM read as 2's complement (-128 to +127), user enters -128 to +127 |
JonFreeman | 16:d1e4b9ad3b8b | 37 | {10, 50, 20, "RCIN_REGBRAKE_RANGE stick range percent 10 to 50"}, // RCIN_REGBRAKE_RANGE |
JonFreeman | 16:d1e4b9ad3b8b | 38 | {10, 90, 50, "RCIN_STICK_ATTACK rate percent 10 to 90"}, // RCIN_STICK_ATTACK |
JonFreeman | 16:d1e4b9ad3b8b | 39 | {0, 1, 0, "RCIN1 direction swap 0 normal, 1 reverse"}, // RCIN1REVERSE |
JonFreeman | 16:d1e4b9ad3b8b | 40 | {0, 1, 0, "RCIN2 direction swap 0 normal, 1 reverse"}, // RCIN2REVERSE |
JonFreeman | 16:d1e4b9ad3b8b | 41 | {11, 63, 48, "Nominal system voltage, used to calculate current scaling"}, // NOM_SYSTEM_VOLTS |
JonFreeman | 16:d1e4b9ad3b8b | 42 | {5, 91, 90, "Brake Effectiveness percentage"}, |
JonFreeman | 16:d1e4b9ad3b8b | 43 | {1, 5, 1, "Baud rate, [1=9k6, 2=19k2, 3=38k4, 4=78k6, 5=115k2] = "}, // BAUD 1=9k6, 2=19k2, 3=38k4, 4=78k6, 5=115k2 |
JonFreeman | 16:d1e4b9ad3b8b | 44 | {0, 100, 0, "Future 11"}, |
JonFreeman | 16:d1e4b9ad3b8b | 45 | {0, 100, 0, "Future 12"}, |
JonFreeman | 16:d1e4b9ad3b8b | 46 | {0, 100, 0, "Future 13"}, |
JonFreeman | 16:d1e4b9ad3b8b | 47 | {0, 100, 0, "Future 14"}, |
JonFreeman | 16:d1e4b9ad3b8b | 48 | {0, 100, 0, "Future 15"}, |
JonFreeman | 16:d1e4b9ad3b8b | 49 | {0, 100, 0, "Future 16"}, |
JonFreeman | 12:d1d21a2941ef | 50 | } ; |
JonFreeman | 12:d1d21a2941ef | 51 | |
JonFreeman | 16:d1e4b9ad3b8b | 52 | const int numof_eeprom_options = sizeof(option_list) / sizeof (struct optpar); |
JonFreeman | 12:d1d21a2941ef | 53 | |
JonFreeman | 12:d1d21a2941ef | 54 | |
JonFreeman | 12:d1d21a2941ef | 55 | |
JonFreeman | 12:d1d21a2941ef | 56 | |
JonFreeman | 12:d1d21a2941ef | 57 | /* |
JonFreeman | 12:d1d21a2941ef | 58 | class eeprom_settings { |
JonFreeman | 12:d1d21a2941ef | 59 | I2C i2c; |
JonFreeman | 12:d1d21a2941ef | 60 | uint32_t errors; |
JonFreeman | 14:acaa1add097b | 61 | uint32_t i2c_device_count; |
JonFreeman | 14:acaa1add097b | 62 | uint32_t i2c_device_list[12]; // max 12 i2c devices |
JonFreeman | 12:d1d21a2941ef | 63 | char settings [36]; |
JonFreeman | 16:d1e4b9ad3b8b | 64 | double rpm2mphdbl, user_brake_rangedbl, Vnomdbl; |
JonFreeman | 16:d1e4b9ad3b8b | 65 | bool rd_24LC64 (uint32_t start_addr, char * dest, uint32_t length) ; |
JonFreeman | 16:d1e4b9ad3b8b | 66 | bool wr_24LC64 (uint32_t start_addr, char * dest, uint32_t length) ; |
JonFreeman | 12:d1d21a2941ef | 67 | bool set_24LC64_internal_address (int start_addr) ; |
JonFreeman | 12:d1d21a2941ef | 68 | bool ack_poll () ; |
JonFreeman | 12:d1d21a2941ef | 69 | public: |
JonFreeman | 12:d1d21a2941ef | 70 | eeprom_settings (PinName sda, PinName scl); // Constructor |
JonFreeman | 14:acaa1add097b | 71 | bool do_we_have_i2c (uint32_t x) ; |
JonFreeman | 12:d1d21a2941ef | 72 | char rd (uint32_t) ; // Read one setup char value from private buffer 'settings' |
JonFreeman | 12:d1d21a2941ef | 73 | bool wr (char, uint32_t) ; // Write one setup char value to private buffer 'settings' |
JonFreeman | 12:d1d21a2941ef | 74 | bool save () ; // Write 'settings' buffer to EEPROM |
JonFreeman | 16:d1e4b9ad3b8b | 75 | bool set_defaults (); // Put default settings into EEPROM and local buffer |
JonFreeman | 12:d1d21a2941ef | 76 | uint32_t errs () ; // Return errors |
JonFreeman | 16:d1e4b9ad3b8b | 77 | const char * t (uint32_t); |
JonFreeman | 16:d1e4b9ad3b8b | 78 | int min (uint32_t) ; |
JonFreeman | 16:d1e4b9ad3b8b | 79 | int max (uint32_t) ; |
JonFreeman | 16:d1e4b9ad3b8b | 80 | int def (uint32_t) ; |
JonFreeman | 16:d1e4b9ad3b8b | 81 | bool in_range (char val, uint32_t p) ; |
JonFreeman | 16:d1e4b9ad3b8b | 82 | void edit (double * dbl, uint32_t numof_dbls) ; |
JonFreeman | 16:d1e4b9ad3b8b | 83 | double user_brake_range () ; |
JonFreeman | 16:d1e4b9ad3b8b | 84 | double top_speed () ; |
JonFreeman | 16:d1e4b9ad3b8b | 85 | double rpm2mph () ; |
JonFreeman | 16:d1e4b9ad3b8b | 86 | double rpm2mph (double) ; |
JonFreeman | 12:d1d21a2941ef | 87 | } ; |
JonFreeman | 12:d1d21a2941ef | 88 | */ |
JonFreeman | 12:d1d21a2941ef | 89 | |
JonFreeman | 16:d1e4b9ad3b8b | 90 | uint32_t eeprom_settings::baud () { |
JonFreeman | 16:d1e4b9ad3b8b | 91 | const uint32_t brates[] = {0, 9600, 19200, 38400, 76800, 11520}; |
JonFreeman | 16:d1e4b9ad3b8b | 92 | return brates[settings[BAUD]]; |
JonFreeman | 16:d1e4b9ad3b8b | 93 | } |
JonFreeman | 16:d1e4b9ad3b8b | 94 | |
JonFreeman | 16:d1e4b9ad3b8b | 95 | double eeprom_settings::top_speed () { |
JonFreeman | 16:d1e4b9ad3b8b | 96 | return top_speeddbl; |
JonFreeman | 16:d1e4b9ad3b8b | 97 | } |
JonFreeman | 16:d1e4b9ad3b8b | 98 | |
JonFreeman | 16:d1e4b9ad3b8b | 99 | double eeprom_settings::brake_effectiveness () { |
JonFreeman | 16:d1e4b9ad3b8b | 100 | return brake_eff; |
JonFreeman | 16:d1e4b9ad3b8b | 101 | } |
JonFreeman | 16:d1e4b9ad3b8b | 102 | |
JonFreeman | 16:d1e4b9ad3b8b | 103 | double eeprom_settings::user_brake_range () { |
JonFreeman | 16:d1e4b9ad3b8b | 104 | return user_brake_rangedbl; |
JonFreeman | 16:d1e4b9ad3b8b | 105 | } |
JonFreeman | 16:d1e4b9ad3b8b | 106 | |
JonFreeman | 16:d1e4b9ad3b8b | 107 | double eeprom_settings::Vnom () { |
JonFreeman | 16:d1e4b9ad3b8b | 108 | return Vnomdbl; |
JonFreeman | 16:d1e4b9ad3b8b | 109 | } |
JonFreeman | 16:d1e4b9ad3b8b | 110 | |
JonFreeman | 16:d1e4b9ad3b8b | 111 | double eeprom_settings::rpm2mph () { |
JonFreeman | 16:d1e4b9ad3b8b | 112 | return rpm2mphdbl; |
JonFreeman | 16:d1e4b9ad3b8b | 113 | } |
JonFreeman | 16:d1e4b9ad3b8b | 114 | |
JonFreeman | 16:d1e4b9ad3b8b | 115 | double eeprom_settings::rpm2mph (double rpm) { |
JonFreeman | 16:d1e4b9ad3b8b | 116 | return rpm2mphdbl * rpm; |
JonFreeman | 16:d1e4b9ad3b8b | 117 | } |
JonFreeman | 16:d1e4b9ad3b8b | 118 | |
JonFreeman | 16:d1e4b9ad3b8b | 119 | void eeprom_settings::edit (double * dbl, uint32_t numof_dbls) { |
JonFreeman | 16:d1e4b9ad3b8b | 120 | extern void set_RCIN_offsets () ; |
JonFreeman | 16:d1e4b9ad3b8b | 121 | const char* labs[3] = {"Disabled","Uni_directional","Bi_directional"}; |
JonFreeman | 16:d1e4b9ad3b8b | 122 | char temps[MAX_CLI_PARAMS+1]; // max num of parameters entered from pc terminal |
JonFreeman | 16:d1e4b9ad3b8b | 123 | uint32_t i; |
JonFreeman | 16:d1e4b9ad3b8b | 124 | double user_scratch; |
JonFreeman | 16:d1e4b9ad3b8b | 125 | double topspeed; // New Jan 2019 - set max loco speed |
JonFreeman | 16:d1e4b9ad3b8b | 126 | pc.printf ("\r\nus - User Settings data in EEPROM\r\nSyntax 'us' with no parameters lists current state.\r\n"); |
JonFreeman | 16:d1e4b9ad3b8b | 127 | if (numof_dbls > 0) { // If more than 0 parameters supplied |
JonFreeman | 16:d1e4b9ad3b8b | 128 | if (numof_dbls > MAX_CLI_PARAMS) |
JonFreeman | 16:d1e4b9ad3b8b | 129 | numof_dbls = MAX_CLI_PARAMS; |
JonFreeman | 16:d1e4b9ad3b8b | 130 | for (i = 0; i < numof_dbls; i++) |
JonFreeman | 16:d1e4b9ad3b8b | 131 | temps[i] = (char)dbl[i]; // recast doubles to char |
JonFreeman | 16:d1e4b9ad3b8b | 132 | while (MAX_CLI_PARAMS > i) |
JonFreeman | 16:d1e4b9ad3b8b | 133 | temps[i++] = 0; |
JonFreeman | 16:d1e4b9ad3b8b | 134 | i = temps[0]; |
JonFreeman | 16:d1e4b9ad3b8b | 135 | switch (i) { // First number read from user response after "mode" |
JonFreeman | 16:d1e4b9ad3b8b | 136 | case 11: // MotorA_dir [0 or 1], MotorB_dir [0 or 1] |
JonFreeman | 16:d1e4b9ad3b8b | 137 | wr(temps[1], MOTADIR); |
JonFreeman | 16:d1e4b9ad3b8b | 138 | wr(temps[2], MOTBDIR); |
JonFreeman | 16:d1e4b9ad3b8b | 139 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 140 | case 12: // MotorA_poles [4,6,8], MotorB_poles [4,6,8] |
JonFreeman | 16:d1e4b9ad3b8b | 141 | if (temps[1] == 4 || temps[1] == 6 || temps[1] == 8) |
JonFreeman | 16:d1e4b9ad3b8b | 142 | wr(temps[1], MOTAPOLES); |
JonFreeman | 16:d1e4b9ad3b8b | 143 | if (temps[2] == 4 || temps[2] == 6 || temps[2] == 8) |
JonFreeman | 16:d1e4b9ad3b8b | 144 | wr(temps[2], MOTBPOLES); |
JonFreeman | 16:d1e4b9ad3b8b | 145 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 146 | case 13: // MotorA_ current sense resistors [1 to 4], MotorB_ current sense resistors [1 to 4] |
JonFreeman | 16:d1e4b9ad3b8b | 147 | wr(temps[1], ISHUNTA); // Corrected since published |
JonFreeman | 16:d1e4b9ad3b8b | 148 | wr(temps[2], ISHUNTB); |
JonFreeman | 16:d1e4b9ad3b8b | 149 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 150 | case 14: |
JonFreeman | 16:d1e4b9ad3b8b | 151 | wr(temps[1], BRAKE_EFFECTIVENESS); |
JonFreeman | 16:d1e4b9ad3b8b | 152 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 153 | case 15: |
JonFreeman | 16:d1e4b9ad3b8b | 154 | pc.printf ("POT_REGBRAKE_RANGE value entered = %d\r\n", temps[1]); |
JonFreeman | 16:d1e4b9ad3b8b | 155 | if (!in_range(temps[1], POT_REGBRAKE_RANGE)) |
JonFreeman | 16:d1e4b9ad3b8b | 156 | temps[1] = def(POT_REGBRAKE_RANGE); |
JonFreeman | 16:d1e4b9ad3b8b | 157 | wr (temps[1], POT_REGBRAKE_RANGE); |
JonFreeman | 16:d1e4b9ad3b8b | 158 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 159 | case 16: // 2 Servo1 [0 or 1], Servo2 [0 or 1] |
JonFreeman | 16:d1e4b9ad3b8b | 160 | wr(temps[1], SVO1); |
JonFreeman | 16:d1e4b9ad3b8b | 161 | wr(temps[2], SVO2); |
JonFreeman | 16:d1e4b9ad3b8b | 162 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 163 | case 17: // 3 RCIn1 [0 or 1], RCIn2 [0 or 1] |
JonFreeman | 16:d1e4b9ad3b8b | 164 | wr(temps[1], RCIN1); |
JonFreeman | 16:d1e4b9ad3b8b | 165 | wr(temps[2], RCIN2); |
JonFreeman | 16:d1e4b9ad3b8b | 166 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 167 | case 18: |
JonFreeman | 16:d1e4b9ad3b8b | 168 | wr(temps[1], RCIN1REVERSE); |
JonFreeman | 16:d1e4b9ad3b8b | 169 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 170 | case 19: |
JonFreeman | 16:d1e4b9ad3b8b | 171 | wr(temps[1], RCIN2REVERSE); |
JonFreeman | 16:d1e4b9ad3b8b | 172 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 173 | /* case 33: // Not shown in menu, just to test stuff searching for strtod bug, to be deleted later |
JonFreeman | 16:d1e4b9ad3b8b | 174 | pc.printf ("Testing to fix strtod bug, "); |
JonFreeman | 16:d1e4b9ad3b8b | 175 | i = 0; |
JonFreeman | 16:d1e4b9ad3b8b | 176 | while (numof_dbls--) |
JonFreeman | 16:d1e4b9ad3b8b | 177 | pc.printf ("%.3f, ", dbl[i++]); |
JonFreeman | 16:d1e4b9ad3b8b | 178 | pc.printf ("TheEnd\r\n"); |
JonFreeman | 16:d1e4b9ad3b8b | 179 | break;*/ |
JonFreeman | 16:d1e4b9ad3b8b | 180 | case 21: // 3 RCIn1 trim [-128 to +127] |
JonFreeman | 16:d1e4b9ad3b8b | 181 | case 22: // 3 RCIn2 trim [-128 to +127] |
JonFreeman | 16:d1e4b9ad3b8b | 182 | user_scratch = dbl[1]; |
JonFreeman | 16:d1e4b9ad3b8b | 183 | if (user_scratch > 127.0) user_scratch = 127.0; |
JonFreeman | 16:d1e4b9ad3b8b | 184 | if (user_scratch < -128.0) user_scratch = -128.0; |
JonFreeman | 16:d1e4b9ad3b8b | 185 | wr (((signed char) user_scratch), i == 21 ? RCI1_TRIM : RCI2_TRIM); |
JonFreeman | 16:d1e4b9ad3b8b | 186 | set_RCIN_offsets () ; |
JonFreeman | 16:d1e4b9ad3b8b | 187 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 188 | case 23: // RCIN_REGBRAKE_RANGE |
JonFreeman | 16:d1e4b9ad3b8b | 189 | wr (temps[1], RCIN_REGBRAKE_RANGE); |
JonFreeman | 16:d1e4b9ad3b8b | 190 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 191 | case 24: // RCIN_STICK_ATTACK |
JonFreeman | 16:d1e4b9ad3b8b | 192 | wr (temps[1], RCIN_STICK_ATTACK); |
JonFreeman | 16:d1e4b9ad3b8b | 193 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 194 | case 25: // 4 Board ID '0' to '9' |
JonFreeman | 16:d1e4b9ad3b8b | 195 | if (temps[1] <= 9) // pointless to compare unsigned integer with zero |
JonFreeman | 16:d1e4b9ad3b8b | 196 | wr('0' | temps[1], BOARD_ID); |
JonFreeman | 16:d1e4b9ad3b8b | 197 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 198 | case 26: // TOP_SPEED |
JonFreeman | 16:d1e4b9ad3b8b | 199 | topspeed = dbl[1]; |
JonFreeman | 16:d1e4b9ad3b8b | 200 | if (topspeed > 25.0) topspeed = 25.0; |
JonFreeman | 16:d1e4b9ad3b8b | 201 | if (topspeed < 1.0) topspeed = 1.0; |
JonFreeman | 16:d1e4b9ad3b8b | 202 | wr((char)(topspeed * 10.0), TOP_SPEED); |
JonFreeman | 16:d1e4b9ad3b8b | 203 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 204 | case 27: // 5 Wheel dia mm, Motor pinion teeth, Wheel gear teeth |
JonFreeman | 16:d1e4b9ad3b8b | 205 | wr(temps[1], WHEELDIA); |
JonFreeman | 16:d1e4b9ad3b8b | 206 | wr(temps[2], MOTPIN); |
JonFreeman | 16:d1e4b9ad3b8b | 207 | wr(temps[3], WHEELGEAR); |
JonFreeman | 16:d1e4b9ad3b8b | 208 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 209 | case 28: // {2, 5, 2, "Command source 2= COM2 (Touch Screen), 3= Pot, 4= RC Input1, 5= RC Input2, 6=RC1+2 Robot"}, |
JonFreeman | 16:d1e4b9ad3b8b | 210 | if (temps[1] > 1 && temps[1] <= 6) |
JonFreeman | 16:d1e4b9ad3b8b | 211 | wr(temps[1], COMM_SRC); |
JonFreeman | 16:d1e4b9ad3b8b | 212 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 213 | case 29: // Nominal System Voltage |
JonFreeman | 16:d1e4b9ad3b8b | 214 | wr (temps[1], NOM_SYSTEM_VOLTS); |
JonFreeman | 16:d1e4b9ad3b8b | 215 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 216 | case 83: // set to defaults |
JonFreeman | 16:d1e4b9ad3b8b | 217 | set_defaults (); |
JonFreeman | 16:d1e4b9ad3b8b | 218 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 219 | case 30: // BAUD |
JonFreeman | 16:d1e4b9ad3b8b | 220 | wr (temps[1], BAUD); |
JonFreeman | 16:d1e4b9ad3b8b | 221 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 222 | /* case 9: // 9 Save settings |
JonFreeman | 16:d1e4b9ad3b8b | 223 | save (); |
JonFreeman | 16:d1e4b9ad3b8b | 224 | pc.printf ("Saving settings to EEPROM\r\n"); |
JonFreeman | 16:d1e4b9ad3b8b | 225 | break;*/ |
JonFreeman | 16:d1e4b9ad3b8b | 226 | default: |
JonFreeman | 16:d1e4b9ad3b8b | 227 | pc.printf ("Not found - user setting %d\r\n", i); |
JonFreeman | 16:d1e4b9ad3b8b | 228 | i = 0; |
JonFreeman | 16:d1e4b9ad3b8b | 229 | break; |
JonFreeman | 16:d1e4b9ad3b8b | 230 | } // endof switch |
JonFreeman | 16:d1e4b9ad3b8b | 231 | if (i) { |
JonFreeman | 16:d1e4b9ad3b8b | 232 | save (); |
JonFreeman | 16:d1e4b9ad3b8b | 233 | pc.printf ("Saving settings to EEPROM\r\n"); |
JonFreeman | 16:d1e4b9ad3b8b | 234 | } |
JonFreeman | 16:d1e4b9ad3b8b | 235 | } // endof // If more than 0 parameters supplied |
JonFreeman | 16:d1e4b9ad3b8b | 236 | else { // command was just "mode" on its own |
JonFreeman | 16:d1e4b9ad3b8b | 237 | pc.printf ("No Changes\r\n"); |
JonFreeman | 16:d1e4b9ad3b8b | 238 | } |
JonFreeman | 16:d1e4b9ad3b8b | 239 | pc.printf ("us 11\t%s = %d, %s = %d\r\n", t(MOTADIR), settings[MOTADIR], t(MOTBDIR), settings[MOTBDIR]); |
JonFreeman | 16:d1e4b9ad3b8b | 240 | pc.printf ("us 12\t%s = %d, %s = %d\r\n", t(MOTAPOLES), settings[MOTAPOLES], t(MOTBPOLES), settings[MOTBPOLES]); |
JonFreeman | 16:d1e4b9ad3b8b | 241 | pc.printf ("us 13\tNumof motor current shunt resistors [%d to %d], MotorA = %d, MotorB = %d\r\n", min(ISHUNTA), max(ISHUNTA), settings[ISHUNTA], settings[ISHUNTB]); |
JonFreeman | 16:d1e4b9ad3b8b | 242 | pc.printf ("us 14\t%s [min %d, max %d] = %d\r\n", t(BRAKE_EFFECTIVENESS), min(BRAKE_EFFECTIVENESS), max(BRAKE_EFFECTIVENESS), settings[BRAKE_EFFECTIVENESS]); |
JonFreeman | 16:d1e4b9ad3b8b | 243 | pc.printf ("us 15\t%s[%d to %d] = %d\r\n", t(POT_REGBRAKE_RANGE), min(POT_REGBRAKE_RANGE), max(POT_REGBRAKE_RANGE), settings[POT_REGBRAKE_RANGE]); |
JonFreeman | 16:d1e4b9ad3b8b | 244 | pc.printf ("us 16\tServo1 [0 or 1] = %d %s, Servo2 [0 or 1] = %d %s\r\n", settings[SVO1], settings[SVO1] == 0 ? "Disabled":"Enabled", settings[SVO2], settings[SVO2] == 0 ? "Disabled":"Enabled"); |
JonFreeman | 16:d1e4b9ad3b8b | 245 | pc.printf ("us 17\tRCIn1 [0 disable, 1 Uni_dir, 2 Bi_dir] = %d, %s\r\n\tRCIn2 [0 disable, 1 Uni_dir, 2 Bi_dir] = %d, %s\r\n", settings[RCIN1], labs[settings[RCIN1]], settings[RCIN2], labs[rd(RCIN2)]); |
JonFreeman | 16:d1e4b9ad3b8b | 246 | pc.printf ("us 18\t%s RCIN1 = %d, %s\r\n", t(RCIN1REVERSE), settings[RCIN1REVERSE], settings[RCIN1REVERSE] == 0 ? "NORMAL":"REVERSE"); |
JonFreeman | 16:d1e4b9ad3b8b | 247 | pc.printf ("us 19\t%s RCIN2 = %d, %s\r\n", t(RCIN2REVERSE), settings[RCIN2REVERSE], settings[RCIN2REVERSE] == 0 ? "NORMAL":"REVERSE"); |
JonFreeman | 16:d1e4b9ad3b8b | 248 | pc.printf ("us 21\tRCIn1 two's comp trim, [-128 to +127] = %d\r\n", (signed char) settings[RCI1_TRIM]); |
JonFreeman | 16:d1e4b9ad3b8b | 249 | pc.printf ("us 22\tRCIn2 two's comp trim, [-128 to +127] = %d\r\n", (signed char) settings[RCI2_TRIM]); |
JonFreeman | 16:d1e4b9ad3b8b | 250 | pc.printf ("us 23\tRCIn Regen braking uses this pcntage of movement range, [%d to %d] = %d\r\n",min(RCIN_REGBRAKE_RANGE), max(RCIN_REGBRAKE_RANGE), settings[RCIN_REGBRAKE_RANGE]); |
JonFreeman | 16:d1e4b9ad3b8b | 251 | pc.printf ("us 24\tRCIn Stick move Attack rate, [%d to %d] = %d\r\n",min(RCIN_STICK_ATTACK), max(RCIN_STICK_ATTACK), settings[RCIN_STICK_ATTACK]); |
JonFreeman | 16:d1e4b9ad3b8b | 252 | pc.printf ("us 25\tBoard ID ['0' to '9'] = '%c'\r\n", settings[BOARD_ID]); |
JonFreeman | 16:d1e4b9ad3b8b | 253 | pc.printf ("us 26\t%s = %.1f\r\n", t(TOP_SPEED), double(settings[TOP_SPEED]) / 10.0); |
JonFreeman | 16:d1e4b9ad3b8b | 254 | // WHEELDIA, MOTPIN, WHEELGEAR, used in converting RPM to MPH |
JonFreeman | 16:d1e4b9ad3b8b | 255 | pc.printf ("us 27\t%s = %d, %s = %d, %s = %d\r\n", t(WHEELDIA), settings[WHEELDIA], t(MOTPIN), settings[MOTPIN], t(WHEELGEAR), settings[WHEELGEAR]); |
JonFreeman | 16:d1e4b9ad3b8b | 256 | pc.printf ("us 28\tCommand Src [%d] - 2=COM2 (Touch Screen), 3=Pot, 4=RC In1, 5=RC In2, 6=RC1+2\r\n", settings[COMM_SRC]); |
JonFreeman | 16:d1e4b9ad3b8b | 257 | pc.printf ("us 29\t%s = %d\r\n", t(NOM_SYSTEM_VOLTS), settings[NOM_SYSTEM_VOLTS]); |
JonFreeman | 16:d1e4b9ad3b8b | 258 | pc.printf ("us 30\t%s %d\r\n", t(BAUD), settings[BAUD]); |
JonFreeman | 16:d1e4b9ad3b8b | 259 | pc.printf ("us 83\tSet to defaults\r\n"); |
JonFreeman | 16:d1e4b9ad3b8b | 260 | // pc.printf ("us 9\tSave settings\r\r\n"); |
JonFreeman | 16:d1e4b9ad3b8b | 261 | } |
JonFreeman | 16:d1e4b9ad3b8b | 262 | |
JonFreeman | 16:d1e4b9ad3b8b | 263 | bool eeprom_settings::in_range (char val, uint32_t p) { |
JonFreeman | 16:d1e4b9ad3b8b | 264 | if ((val >= option_list[p].min) && (val <= option_list[p].max)) |
JonFreeman | 16:d1e4b9ad3b8b | 265 | return true; |
JonFreeman | 16:d1e4b9ad3b8b | 266 | return false; |
JonFreeman | 16:d1e4b9ad3b8b | 267 | } |
JonFreeman | 16:d1e4b9ad3b8b | 268 | uint32_t eeprom_settings::min (uint32_t i) { |
JonFreeman | 16:d1e4b9ad3b8b | 269 | if (i >= numof_eeprom_options) |
JonFreeman | 16:d1e4b9ad3b8b | 270 | i = numof_eeprom_options - 1; |
JonFreeman | 16:d1e4b9ad3b8b | 271 | return option_list[i].min; |
JonFreeman | 16:d1e4b9ad3b8b | 272 | } |
JonFreeman | 16:d1e4b9ad3b8b | 273 | uint32_t eeprom_settings::max (uint32_t i) { |
JonFreeman | 16:d1e4b9ad3b8b | 274 | if (i >= numof_eeprom_options) |
JonFreeman | 16:d1e4b9ad3b8b | 275 | i = numof_eeprom_options - 1; |
JonFreeman | 16:d1e4b9ad3b8b | 276 | return option_list[i].max; |
JonFreeman | 16:d1e4b9ad3b8b | 277 | } |
JonFreeman | 16:d1e4b9ad3b8b | 278 | uint32_t eeprom_settings::def (uint32_t i) { |
JonFreeman | 16:d1e4b9ad3b8b | 279 | if (i >= numof_eeprom_options) |
JonFreeman | 16:d1e4b9ad3b8b | 280 | i = numof_eeprom_options - 1; |
JonFreeman | 16:d1e4b9ad3b8b | 281 | return option_list[i].de_fault; |
JonFreeman | 16:d1e4b9ad3b8b | 282 | } |
JonFreeman | 16:d1e4b9ad3b8b | 283 | |
JonFreeman | 16:d1e4b9ad3b8b | 284 | const char * eeprom_settings::t (uint32_t i) { |
JonFreeman | 16:d1e4b9ad3b8b | 285 | if (i >= numof_eeprom_options) |
JonFreeman | 16:d1e4b9ad3b8b | 286 | i = numof_eeprom_options - 1; |
JonFreeman | 16:d1e4b9ad3b8b | 287 | return option_list[i].txt; |
JonFreeman | 16:d1e4b9ad3b8b | 288 | } |
JonFreeman | 16:d1e4b9ad3b8b | 289 | |
JonFreeman | 12:d1d21a2941ef | 290 | bool eeprom_settings::set_defaults () { // Put default settings into EEPROM and local buffer |
JonFreeman | 16:d1e4b9ad3b8b | 291 | for (int i = 0; i < numof_eeprom_options; i++) |
JonFreeman | 16:d1e4b9ad3b8b | 292 | settings[i] = option_list[i].de_fault; // Load defaults and 'Save Settings' |
JonFreeman | 12:d1d21a2941ef | 293 | return save (); |
JonFreeman | 12:d1d21a2941ef | 294 | } |
JonFreeman | 12:d1d21a2941ef | 295 | |
JonFreeman | 12:d1d21a2941ef | 296 | uint32_t eeprom_settings::errs () { |
JonFreeman | 12:d1d21a2941ef | 297 | return errors; |
JonFreeman | 12:d1d21a2941ef | 298 | } |
JonFreeman | 12:d1d21a2941ef | 299 | |
JonFreeman | 14:acaa1add097b | 300 | bool eeprom_settings::do_we_have_i2c (uint32_t x) { |
JonFreeman | 14:acaa1add097b | 301 | for (int i = 0; i < i2c_device_count; i++) { |
JonFreeman | 14:acaa1add097b | 302 | if (i2c_device_list[i] == x) |
JonFreeman | 14:acaa1add097b | 303 | return true; |
JonFreeman | 14:acaa1add097b | 304 | } |
JonFreeman | 14:acaa1add097b | 305 | return false; |
JonFreeman | 14:acaa1add097b | 306 | } |
JonFreeman | 14:acaa1add097b | 307 | |
JonFreeman | 12:d1d21a2941ef | 308 | // Use : eeprom_settings (SDA_PIN, SCL_PIN); |
JonFreeman | 12:d1d21a2941ef | 309 | eeprom_settings::eeprom_settings (PinName sda, PinName scl) : i2c(sda, scl) // Constructor |
JonFreeman | 12:d1d21a2941ef | 310 | { |
JonFreeman | 14:acaa1add097b | 311 | errors = i2c_device_count = 0; |
JonFreeman | 12:d1d21a2941ef | 312 | for (int i = 0; i < 36; i++) |
JonFreeman | 12:d1d21a2941ef | 313 | settings[i] = 0; |
JonFreeman | 16:d1e4b9ad3b8b | 314 | for (int i = 0; i < MAX_I2C_DEVICES; i++) |
JonFreeman | 14:acaa1add097b | 315 | i2c_device_list[i] = 0; |
JonFreeman | 12:d1d21a2941ef | 316 | i2c.frequency(400000); // Speed 400000 max. |
JonFreeman | 14:acaa1add097b | 317 | int q; |
JonFreeman | 12:d1d21a2941ef | 318 | for (int i = 0; i < 255; i += 2) { // Search for devices at all possible i2c addresses |
JonFreeman | 12:d1d21a2941ef | 319 | i2c.start(); |
JonFreeman | 12:d1d21a2941ef | 320 | q = i2c.write(i); // may return error code 2 when no start issued |
JonFreeman | 12:d1d21a2941ef | 321 | switch (q) { |
JonFreeman | 12:d1d21a2941ef | 322 | case ACK: |
JonFreeman | 14:acaa1add097b | 323 | i2c_device_list[i2c_device_count++] = i; |
JonFreeman | 16:d1e4b9ad3b8b | 324 | if (i2c_device_count >= MAX_I2C_DEVICES) { |
JonFreeman | 16:d1e4b9ad3b8b | 325 | i = 300; // break out |
JonFreeman | 16:d1e4b9ad3b8b | 326 | pc.printf ("Too many i2c devices %d\r\n", i2c_device_count); |
JonFreeman | 16:d1e4b9ad3b8b | 327 | } |
JonFreeman | 12:d1d21a2941ef | 328 | case 2: // Device not seen at this address |
JonFreeman | 12:d1d21a2941ef | 329 | break; |
JonFreeman | 12:d1d21a2941ef | 330 | default: |
JonFreeman | 14:acaa1add097b | 331 | pc.printf ("Unknown error %d from i2c.write while looking for i2c devices\r\n", q); |
JonFreeman | 12:d1d21a2941ef | 332 | errors |= 512; |
JonFreeman | 12:d1d21a2941ef | 333 | break; |
JonFreeman | 12:d1d21a2941ef | 334 | } |
JonFreeman | 12:d1d21a2941ef | 335 | } |
JonFreeman | 12:d1d21a2941ef | 336 | i2c.stop(); |
JonFreeman | 14:acaa1add097b | 337 | if (errors || !do_we_have_i2c(0xa0)) { |
JonFreeman | 12:d1d21a2941ef | 338 | pc.printf ("Error - EEPROM not seen %d\r\n", errors); |
JonFreeman | 12:d1d21a2941ef | 339 | errors |= 0xa0; |
JonFreeman | 12:d1d21a2941ef | 340 | ESC_Error.set (FAULT_EEPROM, errors); // Set FAULT_EEPROM bits if 24LC64 problem |
JonFreeman | 12:d1d21a2941ef | 341 | } |
JonFreeman | 12:d1d21a2941ef | 342 | else { // Found 24LC64 memory on I2C. Attempt to load settings from EEPROM |
JonFreeman | 12:d1d21a2941ef | 343 | errors = 0; |
JonFreeman | 12:d1d21a2941ef | 344 | if (!rd_24LC64 (0, settings, 32)) |
JonFreeman | 12:d1d21a2941ef | 345 | ESC_Error.set (FAULT_EEPROM, 2); // Set FAULT_EEPROM bit 1 if 24LC64 problem |
JonFreeman | 16:d1e4b9ad3b8b | 346 | for (int i = 0; i < numof_eeprom_options; i++) { |
JonFreeman | 16:d1e4b9ad3b8b | 347 | if ((settings[i] < option_list[i].min) || (settings[i] > option_list[i].max)) { |
JonFreeman | 16:d1e4b9ad3b8b | 348 | pc.printf ("EEROM error with %s\r\n", option_list[i].txt); |
JonFreeman | 16:d1e4b9ad3b8b | 349 | settings[i] = option_list[i].de_fault; // Load default for faulty entry |
JonFreeman | 12:d1d21a2941ef | 350 | errors++; |
JonFreeman | 12:d1d21a2941ef | 351 | } |
JonFreeman | 12:d1d21a2941ef | 352 | } |
JonFreeman | 12:d1d21a2941ef | 353 | } |
JonFreeman | 12:d1d21a2941ef | 354 | ESC_Error.set (FAULT_EEPROM, errors); // sets nothing if 0 |
JonFreeman | 16:d1e4b9ad3b8b | 355 | // if (errors > 1) { ??why > 1 ? |
JonFreeman | 16:d1e4b9ad3b8b | 356 | if (errors > 0) { |
JonFreeman | 16:d1e4b9ad3b8b | 357 | // pc.printf ("Bad settings found at startup. Restoring defaults\r\n"); |
JonFreeman | 16:d1e4b9ad3b8b | 358 | // for (int i = 0; i < numof_eeprom_options2; i++) |
JonFreeman | 16:d1e4b9ad3b8b | 359 | // settings[i] = option_list[i].de_fault; // Load defaults and 'Save Settings' |
JonFreeman | 12:d1d21a2941ef | 360 | if (!wr_24LC64 (0, settings, 32)) // Save settings |
JonFreeman | 16:d1e4b9ad3b8b | 361 | pc.printf ("Error saving EEPROM in user_settings19\r\n"); |
JonFreeman | 12:d1d21a2941ef | 362 | } |
JonFreeman | 16:d1e4b9ad3b8b | 363 | rpm2mphdbl = 60.0 // to Motor Revs per hour; |
JonFreeman | 16:d1e4b9ad3b8b | 364 | * ((double)settings[MOTPIN] / (double)settings[WHEELGEAR]) // Wheel revs per hour |
JonFreeman | 16:d1e4b9ad3b8b | 365 | * PI * ((double)settings[WHEELDIA] / 1000.0) // metres per hour |
JonFreeman | 16:d1e4b9ad3b8b | 366 | * 39.37 / (1760.0 * 36.0); // miles per hour |
JonFreeman | 16:d1e4b9ad3b8b | 367 | update_dbls (); |
JonFreeman | 16:d1e4b9ad3b8b | 368 | // else // 0 or 1 error max found |
JonFreeman | 16:d1e4b9ad3b8b | 369 | // pc.printf ("At startup, settings errors = %d\r\n", errors); |
JonFreeman | 12:d1d21a2941ef | 370 | } // endof constructor |
JonFreeman | 12:d1d21a2941ef | 371 | |
JonFreeman | 16:d1e4b9ad3b8b | 372 | void eeprom_settings::update_dbls () { |
JonFreeman | 16:d1e4b9ad3b8b | 373 | user_brake_rangedbl = (double)settings[POT_REGBRAKE_RANGE] / 100.0; |
JonFreeman | 16:d1e4b9ad3b8b | 374 | Vnomdbl = (double)settings[NOM_SYSTEM_VOLTS]; |
JonFreeman | 16:d1e4b9ad3b8b | 375 | brake_eff = (double)settings[BRAKE_EFFECTIVENESS] / 100.0; |
JonFreeman | 16:d1e4b9ad3b8b | 376 | top_speeddbl = (double)settings[TOP_SPEED] / 10.0; |
JonFreeman | 16:d1e4b9ad3b8b | 377 | } |
JonFreeman | 16:d1e4b9ad3b8b | 378 | |
JonFreeman | 12:d1d21a2941ef | 379 | bool eeprom_settings::ack_poll () { // wait short while for any previous memory operation to complete |
JonFreeman | 0:435bf84ce48a | 380 | const int poll_tries = 40; |
JonFreeman | 0:435bf84ce48a | 381 | int poll_count = 0; |
JonFreeman | 0:435bf84ce48a | 382 | bool i2cfree = false; |
JonFreeman | 0:435bf84ce48a | 383 | while (poll_count++ < poll_tries && !i2cfree) { |
JonFreeman | 0:435bf84ce48a | 384 | i2c.start (); |
JonFreeman | 0:435bf84ce48a | 385 | if (i2c.write(addr_wr) == ACK) |
JonFreeman | 0:435bf84ce48a | 386 | i2cfree = true; |
JonFreeman | 0:435bf84ce48a | 387 | else |
JonFreeman | 17:cc9b854295d6 | 388 | wait_us (1000); // June 2020 changed from wait_ms as now deprecated |
JonFreeman | 0:435bf84ce48a | 389 | } |
JonFreeman | 0:435bf84ce48a | 390 | return i2cfree; |
JonFreeman | 0:435bf84ce48a | 391 | } |
JonFreeman | 0:435bf84ce48a | 392 | |
JonFreeman | 12:d1d21a2941ef | 393 | bool eeprom_settings::set_24LC64_internal_address (int start_addr) { |
JonFreeman | 0:435bf84ce48a | 394 | if (!ack_poll()) |
JonFreeman | 0:435bf84ce48a | 395 | { |
JonFreeman | 0:435bf84ce48a | 396 | pc.printf ("Err in set_24LC64_internal_address, no ACK writing device address byte\r\n"); |
JonFreeman | 0:435bf84ce48a | 397 | i2c.stop(); |
JonFreeman | 0:435bf84ce48a | 398 | return false; |
JonFreeman | 0:435bf84ce48a | 399 | } |
JonFreeman | 0:435bf84ce48a | 400 | int err = 0; |
JonFreeman | 0:435bf84ce48a | 401 | if (i2c.write(start_addr >> 8) != ACK) err++; |
JonFreeman | 0:435bf84ce48a | 402 | if (i2c.write(start_addr & 0xff) != ACK) err++; |
JonFreeman | 0:435bf84ce48a | 403 | if (err) { |
JonFreeman | 0:435bf84ce48a | 404 | pc.printf ("In set_24LC64_internal_address, Believe Device present, failed in writing 2 mem addr bytes %d\r\n", err); |
JonFreeman | 0:435bf84ce48a | 405 | i2c.stop(); |
JonFreeman | 0:435bf84ce48a | 406 | return false; |
JonFreeman | 0:435bf84ce48a | 407 | } |
JonFreeman | 0:435bf84ce48a | 408 | return true; |
JonFreeman | 0:435bf84ce48a | 409 | } |
JonFreeman | 0:435bf84ce48a | 410 | |
JonFreeman | 16:d1e4b9ad3b8b | 411 | bool eeprom_settings::rd_24LC64 (uint32_t start_addr, char * dest, uint32_t length) { |
JonFreeman | 12:d1d21a2941ef | 412 | int acknak = ACK; |
JonFreeman | 12:d1d21a2941ef | 413 | if(length < 1) |
JonFreeman | 12:d1d21a2941ef | 414 | return false; |
JonFreeman | 12:d1d21a2941ef | 415 | if (!set_24LC64_internal_address (start_addr)) { |
JonFreeman | 12:d1d21a2941ef | 416 | pc.printf ("In rd_24LC64, failed to set_ramaddr\r\n"); |
JonFreeman | 12:d1d21a2941ef | 417 | return false; |
JonFreeman | 12:d1d21a2941ef | 418 | } |
JonFreeman | 12:d1d21a2941ef | 419 | i2c.start(); |
JonFreeman | 12:d1d21a2941ef | 420 | if (i2c.write(addr_rd) != ACK) { |
JonFreeman | 12:d1d21a2941ef | 421 | pc.printf ("Errors in rd_24LC64 sending addr_rd\r\n"); |
JonFreeman | 12:d1d21a2941ef | 422 | return false; |
JonFreeman | 12:d1d21a2941ef | 423 | } |
JonFreeman | 12:d1d21a2941ef | 424 | while(length--) { |
JonFreeman | 12:d1d21a2941ef | 425 | if(length == 0) |
JonFreeman | 12:d1d21a2941ef | 426 | acknak = 0; |
JonFreeman | 12:d1d21a2941ef | 427 | *dest++ = i2c.read(acknak); |
JonFreeman | 12:d1d21a2941ef | 428 | } |
JonFreeman | 12:d1d21a2941ef | 429 | i2c.stop(); |
JonFreeman | 12:d1d21a2941ef | 430 | return true; |
JonFreeman | 12:d1d21a2941ef | 431 | } |
JonFreeman | 12:d1d21a2941ef | 432 | |
JonFreeman | 16:d1e4b9ad3b8b | 433 | bool eeprom_settings::wr_24LC64 (uint32_t start_addr, char * source, uint32_t length) { |
JonFreeman | 0:435bf84ce48a | 434 | int err = 0; |
JonFreeman | 0:435bf84ce48a | 435 | if(length < 1 || length > 32) { |
JonFreeman | 0:435bf84ce48a | 436 | pc.printf ("Length out of range %d in wr_24LC64\r\n", length); |
JonFreeman | 0:435bf84ce48a | 437 | return false; |
JonFreeman | 0:435bf84ce48a | 438 | } |
JonFreeman | 3:ecb00e0e8d68 | 439 | ack_poll (); |
JonFreeman | 0:435bf84ce48a | 440 | if (!set_24LC64_internal_address (start_addr)) { |
JonFreeman | 0:435bf84ce48a | 441 | pc.printf ("In wr_24LC64, Believe Device present, failed in writing 2 mem addr bytes %d\r\n", err); |
JonFreeman | 0:435bf84ce48a | 442 | return false; |
JonFreeman | 0:435bf84ce48a | 443 | } |
JonFreeman | 0:435bf84ce48a | 444 | while(length--) |
JonFreeman | 0:435bf84ce48a | 445 | err += ACK - i2c.write(*source++); |
JonFreeman | 0:435bf84ce48a | 446 | i2c.stop(); |
JonFreeman | 0:435bf84ce48a | 447 | if (err) { |
JonFreeman | 0:435bf84ce48a | 448 | pc.printf ("in wr_24LC64, device thought good, mem addr write worked, failed writing string\r\n"); |
JonFreeman | 0:435bf84ce48a | 449 | return false; |
JonFreeman | 0:435bf84ce48a | 450 | } |
JonFreeman | 13:ef7a06fa11de | 451 | // pc.printf ("In wr_24LC64 No Errors Found!\r\n"); |
JonFreeman | 0:435bf84ce48a | 452 | return true; |
JonFreeman | 0:435bf84ce48a | 453 | } |
JonFreeman | 0:435bf84ce48a | 454 | |
JonFreeman | 12:d1d21a2941ef | 455 | char eeprom_settings::rd (uint32_t i) { // Read one setup char value from private buffer 'settings' |
JonFreeman | 12:d1d21a2941ef | 456 | if (i > 31) { |
JonFreeman | 16:d1e4b9ad3b8b | 457 | pc.printf ("ERROR Attempt to read setting %d\r\n", i); |
JonFreeman | 12:d1d21a2941ef | 458 | return 0; |
JonFreeman | 0:435bf84ce48a | 459 | } |
JonFreeman | 12:d1d21a2941ef | 460 | return settings[i]; |
JonFreeman | 12:d1d21a2941ef | 461 | } |
JonFreeman | 12:d1d21a2941ef | 462 | |
JonFreeman | 16:d1e4b9ad3b8b | 463 | /* |
JonFreeman | 16:d1e4b9ad3b8b | 464 | bool eeprom_settings::in_range (char val, uint32_t p) { |
JonFreeman | 16:d1e4b9ad3b8b | 465 | if ((val >= option_list[p].min) && (val <= option_list[p].max)) |
JonFreeman | 16:d1e4b9ad3b8b | 466 | return true; |
JonFreeman | 16:d1e4b9ad3b8b | 467 | return false; |
JonFreeman | 16:d1e4b9ad3b8b | 468 | } |
JonFreeman | 16:d1e4b9ad3b8b | 469 | */ |
JonFreeman | 16:d1e4b9ad3b8b | 470 | bool eeprom_settings::wr (char val, uint32_t p) { // Write one setup char value to private buffer 'settings' |
JonFreeman | 16:d1e4b9ad3b8b | 471 | if (p > 31) |
JonFreeman | 0:435bf84ce48a | 472 | return false; |
JonFreeman | 16:d1e4b9ad3b8b | 473 | if ((val >= min(p)) && (val <= max(p))) { |
JonFreeman | 16:d1e4b9ad3b8b | 474 | settings[p] = val; |
JonFreeman | 16:d1e4b9ad3b8b | 475 | return true; |
JonFreeman | 16:d1e4b9ad3b8b | 476 | } |
JonFreeman | 16:d1e4b9ad3b8b | 477 | settings[p] = def(p); |
JonFreeman | 16:d1e4b9ad3b8b | 478 | // pc.printf ("Wrong in wr, %s\r\n", t(p)); |
JonFreeman | 16:d1e4b9ad3b8b | 479 | return false; |
JonFreeman | 0:435bf84ce48a | 480 | } |
JonFreeman | 0:435bf84ce48a | 481 | |
JonFreeman | 12:d1d21a2941ef | 482 | bool eeprom_settings::save () { // Write 'settings' buffer to EEPROM |
JonFreeman | 16:d1e4b9ad3b8b | 483 | update_dbls (); |
JonFreeman | 12:d1d21a2941ef | 484 | return wr_24LC64 (0, settings, 32); |
JonFreeman | 0:435bf84ce48a | 485 | } |
JonFreeman | 12:d1d21a2941ef | 486 |