STM3 ESC dual brushless motor controller. 10-60v, motor power rating tiny to kW. Ganged or independent motor control As used in 'The Brute' locomotive - www.jons-workshop.com
Dependencies: mbed BufferedSerial Servo FastPWM
Diff: 24LC64_eeprom.cpp
- Revision:
- 12:d1d21a2941ef
- Parent:
- 3:ecb00e0e8d68
--- a/24LC64_eeprom.cpp Sat Jan 19 11:45:01 2019 +0000 +++ b/24LC64_eeprom.cpp Mon Mar 04 17:51:08 2019 +0000 @@ -1,16 +1,129 @@ #include "mbed.h" -//#include "rtos.h" +#include "DualBLS.h" #include "BufferedSerial.h" extern BufferedSerial pc; -extern I2C i2c; +extern error_handling_Jan_2019 ESC_Error ; // Provides array usable to store error codes. // Code for 24LC64 8k x 8 bit eeprom // Code based on earlier work using memory FM24W256, also at i2c address 0xa0; - + const int addr_rd = 0xa1; // set bit 0 for read, clear bit 0 for write const int addr_wr = 0xa0; // set bit 0 for read, clear bit 0 for write const int ACK = 1; -bool ack_poll () { // wait short while for any previous memory operation to complete +struct optpar { + int min, max, def; // min, max, default + const char * t; // description +} ; +struct optpar option_list2[] = { + {0, 1, 1, "MotorA direction 0 or 1"}, + {0, 1, 0, "MotorB direction 0 or 1"}, + {4, 8, 8, "MotorA poles 4 or 6 or 8"}, + {4, 8, 8, "MotorB poles 4 or 6 or 8"}, + {1, 4, 1, "MotorA 0R05 ohm current shunt resistors 1 to 4"}, + {1, 4, 1, "MotorB 0R05 ohm current shunt resistors 1 to 4"}, + {0, 1, 0, "Servo1 0 = Not used, 1= Output"}, + {0, 1, 0, "Servo2 0 = Not used, 1= Output"}, + {0, 1, 0, "RC Input1 0 = Not used, 1= Output"}, + {0, 1, 0, "RC Input2 0 = Not used, 1= Output"}, + {2, 5, 2, "Command source 2= COM2 (Touch Screen), 3= Pot, 4= RC Input1, 5= RC Input2"}, + {'1', '9', '0', "Alternative ID ascii '1' to '9'"}, // defaults to '0' before eerom setup for first time + {10, 250, 60, "Top speed MPH * 10 range 1.0 to 25.0"}, // New Jan 2019 TOP_SPEED + {50, 253, 98, "Wheel diameter mm"}, // New 01/06/2018 + {10, 253, 27, "Motor pinion"}, // New 01/06/2018 + {50, 253, 85, "Wheel gear"}, // New 01/06/2018 + {0, 100, 0, "Future 1"}, + {0, 100, 0, "Future 2"}, + {0, 100, 0, "Future 3"}, + {0, 100, 0, "Future 4"}, + {0, 100, 0, "Future 5"}, +} ; + +const int numof_eeprom_options2 = sizeof(option_list2) / sizeof (struct optpar); + + + + +/* +class eeprom_settings { + I2C i2c; + uint32_t errors; + char settings [36]; + bool rd_24LC64 (int start_addr, char * dest, int length) ; + bool wr_24LC64 (int start_addr, char * dest, int length) ; + bool set_24LC64_internal_address (int start_addr) ; + bool ack_poll () ; + public: + eeprom_settings (PinName sda, PinName scl); // Constructor + char rd (uint32_t) ; // Read one setup char value from private buffer 'settings' + bool wr (char, uint32_t) ; // Write one setup char value to private buffer 'settings' + bool save () ; // Write 'settings' buffer to EEPROM + uint32_t errs () ; // Return errors +} ; +*/ + +bool eeprom_settings::set_defaults () { // Put default settings into EEPROM and local buffer + for (int i = 0; i < numof_eeprom_options2; i++) + settings[i] = option_list2[i].def; // Load defaults and 'Save Settings' + return save (); +} + +uint32_t eeprom_settings::errs () { + return errors; +} + +// Use : eeprom_settings (SDA_PIN, SCL_PIN); +eeprom_settings::eeprom_settings (PinName sda, PinName scl) : i2c(sda, scl) // Constructor +{ + errors = 0; + for (int i = 0; i < 36; i++) + settings[i] = 0; + i2c.frequency(400000); // Speed 400000 max. + int last_found = 0, q; // Note address bits 3-1 to match addr pins on device + for (int i = 0; i < 255; i += 2) { // Search for devices at all possible i2c addresses + i2c.start(); + q = i2c.write(i); // may return error code 2 when no start issued + switch (q) { + case ACK: + pc.printf ("I2C device found at 0x%x\r\n", i); + last_found = i; + case 2: // Device not seen at this address + break; + default: + pc.printf ("Unknown error %d in check_24LC64\r\n", q); + errors |= 512; + break; + } + } + i2c.stop(); + if (errors || last_found != 0xa0) { + pc.printf ("Error - EEPROM not seen %d\r\n", errors); + errors |= 0xa0; + ESC_Error.set (FAULT_EEPROM, errors); // Set FAULT_EEPROM bits if 24LC64 problem + } + else { // Found 24LC64 memory on I2C. Attempt to load settings from EEPROM + errors = 0; + if (!rd_24LC64 (0, settings, 32)) + ESC_Error.set (FAULT_EEPROM, 2); // Set FAULT_EEPROM bit 1 if 24LC64 problem + for (int i = 0; i < numof_eeprom_options2; i++) { + if ((settings[i] < option_list2[i].min) || (settings[i] > option_list2[i].max)) { + pc.printf ("EEROM error with %s\r\n", option_list2[i].t); + errors++; + } + } + } + ESC_Error.set (FAULT_EEPROM, errors); // sets nothing if 0 + if (errors > 1) { + pc.printf ("Bad settings found at startup. Restoring defaults\r\n"); + for (int i = 0; i < numof_eeprom_options2; i++) + settings[i] = option_list2[i].def; // Load defaults and 'Save Settings' + if (!wr_24LC64 (0, settings, 32)) // Save settings + pc.printf ("Error saving EEPROM in mode19\r\n"); + } + else // 0 or 1 error max found + pc.printf ("At startup, settings errors = %d\r\n", errors); +} // endof constructor + +bool eeprom_settings::ack_poll () { // wait short while for any previous memory operation to complete const int poll_tries = 40; int poll_count = 0; bool i2cfree = false; @@ -19,14 +132,12 @@ if (i2c.write(addr_wr) == ACK) i2cfree = true; else -// Thread::wait(1); // 1ms wait_ms (1); } -// pc.printf ("ack_poll, count = %d, i2cfree = %s\r\n", poll_count, i2cfree ? "true" : "false"); return i2cfree; } -bool set_24LC64_internal_address (int start_addr) { +bool eeprom_settings::set_24LC64_internal_address (int start_addr) { if (!ack_poll()) { pc.printf ("Err in set_24LC64_internal_address, no ACK writing device address byte\r\n"); @@ -44,7 +155,29 @@ return true; } -bool wr_24LC64 (int start_addr, char * source, int length) { +bool eeprom_settings::rd_24LC64 (int start_addr, char * dest, int length) { + int acknak = ACK; + if(length < 1) + return false; + if (!set_24LC64_internal_address (start_addr)) { + pc.printf ("In rd_24LC64, failed to set_ramaddr\r\n"); + return false; + } + i2c.start(); + if (i2c.write(addr_rd) != ACK) { + pc.printf ("Errors in rd_24LC64 sending addr_rd\r\n"); + return false; + } + while(length--) { + if(length == 0) + acknak = 0; + *dest++ = i2c.read(acknak); + } + i2c.stop(); + return true; +} + +bool eeprom_settings::wr_24LC64 (int start_addr, char * source, int length) { int err = 0; if(length < 1 || length > 32) { pc.printf ("Length out of range %d in wr_24LC64\r\n", length); @@ -66,46 +199,22 @@ return true; } -bool rd_24LC64 (int start_addr, char * dest, int length) { - int acknak = ACK; - if(length < 1) - return false; - if (!set_24LC64_internal_address (start_addr)) { - pc.printf ("In rd_24LC64, failed to set_ramaddr\r\n"); - return false; +char eeprom_settings::rd (uint32_t i) { // Read one setup char value from private buffer 'settings' + if (i > 31) { + pc.printf ("ERROR Attempt to read setting %d\r\n"); + return 0; } - i2c.start(); - if (i2c.write(addr_rd) != ACK) { - pc.printf ("Errors in rd_24LC64 sending addr_rd\r\n"); + return settings[i]; +} + +bool eeprom_settings::wr (char c, uint32_t i) { // Read one setup char value from private buffer 'settings' + if (i > 31) return false; - } - while(length--) { - if(length == 0) - acknak = 0; - *dest++ = i2c.read(acknak); - } - i2c.stop(); + settings[i] = c; return true; } -int check_24LC64 () { // Call from near top of main() to init i2c bus -// i2c.frequency(400000); // Speed 400000 max. - i2c.frequency(400000); // Speed 400000 max. - int last_found = 0, q; // Note address bits 3-1 to match addr pins on device - for (int i = 0; i < 255; i += 2) { // Search for devices at all possible i2c addresses - i2c.start(); - q = i2c.write(i); // may return error code 2 when no start issued - switch (q) { - case ACK: - pc.printf ("I2C device found at 0x%x\r\n", i); - last_found = i; - case 2: // Device not seen at this address - break; - default: - pc.printf ("Unknown error %d in check_24LC64\r\n", q); - break; - } - } - i2c.stop(); - return last_found; +bool eeprom_settings::save () { // Write 'settings' buffer to EEPROM + return wr_24LC64 (0, settings, 32); } +