Electric Locomotive control system. Touch screen driver control, includes regenerative braking, drives 4 brushless motors, displays speed MPH, system volts and power

Dependencies:   BSP_DISCO_F746NG FastPWM LCD_DISCO_F746NG SD_DISCO_F746NG TS_DISCO_F746NG mbed

Committer:
JonFreeman
Date:
Mon Nov 13 09:53:00 2017 +0000
Revision:
1:8ef34deb5177
Brushless Motor electric locomotive congtrol system; Drives 4 motors using touch-screen control.; Displays speed MPH, system volts and power

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JonFreeman 1:8ef34deb5177 1 #include "mbed.h"
JonFreeman 1:8ef34deb5177 2 #include "Electric_Loco.h"
JonFreeman 1:8ef34deb5177 3 #include "SD_DISCO_F746NG.h"
JonFreeman 1:8ef34deb5177 4 /*
JonFreeman 1:8ef34deb5177 5 SD card used only to keep log of total distance travelled.
JonFreeman 1:8ef34deb5177 6 Odometer is trivial.
JonFreeman 1:8ef34deb5177 7 This file treats SD card as random access memory.
JonFreeman 1:8ef34deb5177 8 A better implementation would use library functions for FAT file system etc.
JonFreeman 1:8ef34deb5177 9
JonFreeman 1:8ef34deb5177 10 May revisit this.
JonFreeman 1:8ef34deb5177 11
JonFreeman 1:8ef34deb5177 12 */
JonFreeman 1:8ef34deb5177 13 SD_DISCO_F746NG sd;
JonFreeman 1:8ef34deb5177 14 extern Serial pc;
JonFreeman 1:8ef34deb5177 15 extern uint32_t historic_distance;
JonFreeman 1:8ef34deb5177 16 extern uint32_t get_pulse_total () ;
JonFreeman 1:8ef34deb5177 17
JonFreeman 1:8ef34deb5177 18 static const int
JonFreeman 1:8ef34deb5177 19 SD_BLOCKSIZE = 512; /* SD card data Block Size in Bytes */
JonFreeman 1:8ef34deb5177 20 // Assume SD card size is 4Gbyte, might be 8 Gbyte
JonFreeman 1:8ef34deb5177 21 // Then can use 8388608 blocks (8 * 1024 * 1024)
JonFreeman 1:8ef34deb5177 22
JonFreeman 1:8ef34deb5177 23 uint64_t SD_blockptr = 0;
JonFreeman 1:8ef34deb5177 24 uint32_t SDBuffer[(SD_BLOCKSIZE >> 2)]; // = space for (512 / 4) uint32_t
JonFreeman 1:8ef34deb5177 25 uint8_t SD_state = SD_OK, sd_jf = 0;
JonFreeman 1:8ef34deb5177 26
JonFreeman 1:8ef34deb5177 27 static const uint64_t GIGAB = 1024 * 1024 * 1024;
JonFreeman 1:8ef34deb5177 28 //static const uint64_t SDBLOCKS = (GIGAB / SD_BLOCKSIZE) * 4; // software drives SD up to 4Gbyte only - 8 M block
JonFreeman 1:8ef34deb5177 29 static const uint64_t SDBLOCKS = (GIGAB / SD_BLOCKSIZE) * 2; // software drives SD up to 4Gbyte only - 8 M block
JonFreeman 1:8ef34deb5177 30 // If data logger takes 2 minutes to fill 1 block, a 4G card takes 32 years run-time to fill
JonFreeman 1:8ef34deb5177 31 // If system generates approx 320 pulses per metre travelled, max distance recordable in uint32_t is 65536 * 65536 / 320 = 13421.772 km
JonFreeman 1:8ef34deb5177 32 bool sd_error () { // Test and Clear error code sd_jf, return true if any error bits set, false on 0
JonFreeman 1:8ef34deb5177 33 bool retval = false;
JonFreeman 1:8ef34deb5177 34 if (sd_jf != 0) {
JonFreeman 1:8ef34deb5177 35 retval = true;
JonFreeman 1:8ef34deb5177 36 sd_jf = 0;
JonFreeman 1:8ef34deb5177 37 }
JonFreeman 1:8ef34deb5177 38 return retval;
JonFreeman 1:8ef34deb5177 39 }
JonFreeman 1:8ef34deb5177 40
JonFreeman 1:8ef34deb5177 41 bool check_SD_block_clear (uint32_t block) {
JonFreeman 1:8ef34deb5177 42 uint32_t b[(SD_BLOCKSIZE >> 2)];
JonFreeman 1:8ef34deb5177 43 SD_state = sd.ReadBlocks(b, (uint64_t)(SD_BLOCKSIZE * block), SD_BLOCKSIZE, 1);
JonFreeman 1:8ef34deb5177 44 if(SD_state != SD_OK) {
JonFreeman 1:8ef34deb5177 45 sd_jf = 1;
JonFreeman 1:8ef34deb5177 46 pc.printf ("Failed, not SD_OK, erasing block %d\r\n", block);
JonFreeman 1:8ef34deb5177 47 return false;
JonFreeman 1:8ef34deb5177 48 }
JonFreeman 1:8ef34deb5177 49 for (int i = 0; i < (SD_BLOCKSIZE >> 2); i++)
JonFreeman 1:8ef34deb5177 50 if (b[i] != 0)
JonFreeman 1:8ef34deb5177 51 return false;
JonFreeman 1:8ef34deb5177 52 return true;
JonFreeman 1:8ef34deb5177 53 }
JonFreeman 1:8ef34deb5177 54
JonFreeman 1:8ef34deb5177 55 bool read_SD_state () {
JonFreeman 1:8ef34deb5177 56 if (SD_state == SD_OK)
JonFreeman 1:8ef34deb5177 57 return true;
JonFreeman 1:8ef34deb5177 58 return false;
JonFreeman 1:8ef34deb5177 59 }
JonFreeman 1:8ef34deb5177 60 /*bool erase_block (uint32_t block2erase) {
JonFreeman 1:8ef34deb5177 61 uint64_t addr = SD_BLOCKSIZE * (uint64_t)block2erase;
JonFreeman 1:8ef34deb5177 62 SD_state = sd.Erase(addr, addr + SD_BLOCKSIZE);
JonFreeman 1:8ef34deb5177 63 if (SD_state != SD_OK) {
JonFreeman 1:8ef34deb5177 64 sd_jf = 1; // Assert error flag
JonFreeman 1:8ef34deb5177 65 pc.printf ("Failed, not SD_OK, erasing block %d\r\n", block2erase);
JonFreeman 1:8ef34deb5177 66 return false;
JonFreeman 1:8ef34deb5177 67 }
JonFreeman 1:8ef34deb5177 68 return check_SD_block_clear (block2erase);
JonFreeman 1:8ef34deb5177 69 }*/
JonFreeman 1:8ef34deb5177 70
JonFreeman 1:8ef34deb5177 71 bool SD_find_next_clear_block (uint64_t * blok) { // Successive approximation algorithm to quickly find next vacant SD card 512 byte block
JonFreeman 1:8ef34deb5177 72 uint64_t toaddsub = SDBLOCKS / 2, stab = SDBLOCKS - 1;
JonFreeman 1:8ef34deb5177 73 pc.printf ("At SD_find_next_clear_block \r\n");
JonFreeman 1:8ef34deb5177 74 while (toaddsub) {
JonFreeman 1:8ef34deb5177 75 pc.printf ("stab = %lld, toadsub = %lld\r\n", stab, toaddsub); // lld for long long int
JonFreeman 1:8ef34deb5177 76 bool clear_block = true;
JonFreeman 1:8ef34deb5177 77 SD_state = sd.ReadBlocks(SDBuffer, SD_BLOCKSIZE * stab, SD_BLOCKSIZE, 1);
JonFreeman 1:8ef34deb5177 78 if(SD_state != SD_OK) {
JonFreeman 1:8ef34deb5177 79 sd_jf = 1;
JonFreeman 1:8ef34deb5177 80 pc.printf ("SD error in SD_find_next_clear_block, returning -1\r\n");
JonFreeman 1:8ef34deb5177 81 return false;
JonFreeman 1:8ef34deb5177 82 }
JonFreeman 1:8ef34deb5177 83 for (int i = 0; i < (SD_BLOCKSIZE >> 2); i++) {
JonFreeman 1:8ef34deb5177 84 if (SDBuffer[i] != 0) {
JonFreeman 1:8ef34deb5177 85 clear_block = false;
JonFreeman 1:8ef34deb5177 86 pc.printf ("Buff at %d contains %x\r\n", i, SDBuffer[i]);
JonFreeman 1:8ef34deb5177 87 i = SD_BLOCKSIZE; // to exit loop
JonFreeman 1:8ef34deb5177 88 }
JonFreeman 1:8ef34deb5177 89 }
JonFreeman 1:8ef34deb5177 90 if (clear_block)
JonFreeman 1:8ef34deb5177 91 stab -= toaddsub;
JonFreeman 1:8ef34deb5177 92 else
JonFreeman 1:8ef34deb5177 93 stab += toaddsub;
JonFreeman 1:8ef34deb5177 94 toaddsub >>= 1;
JonFreeman 1:8ef34deb5177 95 }
JonFreeman 1:8ef34deb5177 96 if (!check_SD_block_clear(stab))
JonFreeman 1:8ef34deb5177 97 stab++;
JonFreeman 1:8ef34deb5177 98 if (sd_error()) { // sd_error() tests and clears error bits
JonFreeman 1:8ef34deb5177 99 pc.printf ("check_SD_block_clear(%ld)returned ERROR in SD_find_next_clear_block\r\n", stab);
JonFreeman 1:8ef34deb5177 100 sd_jf = 1; // reassert error flag
JonFreeman 1:8ef34deb5177 101 return false;
JonFreeman 1:8ef34deb5177 102 }
JonFreeman 1:8ef34deb5177 103 pc.printf ("Completed find_next, stab = %d\r\n", stab);
JonFreeman 1:8ef34deb5177 104 *blok = stab; // block number of next free block
JonFreeman 1:8ef34deb5177 105 return true;
JonFreeman 1:8ef34deb5177 106 }
JonFreeman 1:8ef34deb5177 107
JonFreeman 1:8ef34deb5177 108 bool SD_card_erase_all (void) { // assumes sd card is 4 Gbyte, erases 4 Gbyte. Called from CLI
JonFreeman 1:8ef34deb5177 109 uint64_t EndAddr = GIGAB * 4,
JonFreeman 1:8ef34deb5177 110 StartAddr = 0LL;
JonFreeman 1:8ef34deb5177 111 sd_jf = 0;
JonFreeman 1:8ef34deb5177 112 pc.printf ("Erasing SD card ... ");
JonFreeman 1:8ef34deb5177 113 // uint8_t Erase(uint64_t StartAddr, uint64_t EndAddr);
JonFreeman 1:8ef34deb5177 114 SD_state = sd.Erase(StartAddr, EndAddr);
JonFreeman 1:8ef34deb5177 115 if (SD_state != SD_OK) {
JonFreeman 1:8ef34deb5177 116 pc.printf ("SD_card_erase_all FAILED\r\n");
JonFreeman 1:8ef34deb5177 117 sd_jf = 1;
JonFreeman 1:8ef34deb5177 118 return false;
JonFreeman 1:8ef34deb5177 119 }
JonFreeman 1:8ef34deb5177 120 pc.printf ("no error detected\r\n");
JonFreeman 1:8ef34deb5177 121 return true;
JonFreeman 1:8ef34deb5177 122 }
JonFreeman 1:8ef34deb5177 123
JonFreeman 1:8ef34deb5177 124
JonFreeman 1:8ef34deb5177 125 bool mainSDtest()
JonFreeman 1:8ef34deb5177 126 {
JonFreeman 1:8ef34deb5177 127 SD_state = sd.Init();
JonFreeman 1:8ef34deb5177 128 if(SD_state != SD_OK) {
JonFreeman 1:8ef34deb5177 129 pc.printf ("sd.Init set SD_state to %0x\r\n", SD_state);
JonFreeman 1:8ef34deb5177 130 if(SD_state == MSD_ERROR_SD_NOT_PRESENT) {
JonFreeman 1:8ef34deb5177 131 pc.printf("SD shall be inserted before running test\r\n");
JonFreeman 1:8ef34deb5177 132 } else {
JonFreeman 1:8ef34deb5177 133 pc.printf("SD Initialization : FAIL.\r\n");
JonFreeman 1:8ef34deb5177 134 }
JonFreeman 1:8ef34deb5177 135 pc.printf("SD Test Aborted.\r\n");
JonFreeman 1:8ef34deb5177 136 return false;
JonFreeman 1:8ef34deb5177 137 }
JonFreeman 1:8ef34deb5177 138 // else { // SD_state is SD_OK
JonFreeman 1:8ef34deb5177 139 pc.printf("SD Initialization : OK.\r\n");
JonFreeman 1:8ef34deb5177 140
JonFreeman 1:8ef34deb5177 141
JonFreeman 1:8ef34deb5177 142
JonFreeman 1:8ef34deb5177 143 // SD_card_erase_all();
JonFreeman 1:8ef34deb5177 144 // if (sd_error())
JonFreeman 1:8ef34deb5177 145 // pc.printf ("SD_card_erase_all() reports ERROR");
JonFreeman 1:8ef34deb5177 146
JonFreeman 1:8ef34deb5177 147
JonFreeman 1:8ef34deb5177 148
JonFreeman 1:8ef34deb5177 149 SD_find_next_clear_block(& SD_blockptr);
JonFreeman 1:8ef34deb5177 150 pc.printf ("SD_find_next_clear_block returned %lld\r\n\n\n", SD_blockptr);
JonFreeman 1:8ef34deb5177 151 if (sd_error()) {
JonFreeman 1:8ef34deb5177 152 pc.printf ("***** ERROR returned from SD_find_next_clear_block ***** SD ops aborted\r\n");
JonFreeman 1:8ef34deb5177 153 return false;
JonFreeman 1:8ef34deb5177 154 }
JonFreeman 1:8ef34deb5177 155 pc.printf("SD_find_next_clear_block() returned %ld\r\n", SD_blockptr);
JonFreeman 1:8ef34deb5177 156 if (SD_blockptr < 1) {
JonFreeman 1:8ef34deb5177 157 pc.printf ("Looks like card newly erased, SD_blockptr value of %d\r\n", SD_blockptr);
JonFreeman 1:8ef34deb5177 158 SD_blockptr = 0;
JonFreeman 1:8ef34deb5177 159 historic_distance = 0;
JonFreeman 1:8ef34deb5177 160 }
JonFreeman 1:8ef34deb5177 161 else {
JonFreeman 1:8ef34deb5177 162 SD_state = sd.ReadBlocks(SDBuffer, SD_BLOCKSIZE * (SD_blockptr - 1), SD_BLOCKSIZE, 1);
JonFreeman 1:8ef34deb5177 163 if (SD_state != SD_OK) {
JonFreeman 1:8ef34deb5177 164 pc.printf ("Error reading last block from SD block %d\r\n", SD_blockptr - 1);
JonFreeman 1:8ef34deb5177 165 return false;
JonFreeman 1:8ef34deb5177 166 }
JonFreeman 1:8ef34deb5177 167 for (int i = 0; i < (SD_BLOCKSIZE >> 2); i++)
JonFreeman 1:8ef34deb5177 168 pc.printf ("%lx\t", SDBuffer[i]);
JonFreeman 1:8ef34deb5177 169 historic_distance = SDBuffer[(SD_BLOCKSIZE >> 2) - 1];
JonFreeman 1:8ef34deb5177 170 pc.printf ("\r\nAbove, data read from last filled SD block %lld, using historic_distance = %lx\r\n", SD_blockptr - 1, historic_distance);
JonFreeman 1:8ef34deb5177 171 }
JonFreeman 1:8ef34deb5177 172 if (SD_blockptr > 2) {
JonFreeman 1:8ef34deb5177 173 for (int i = SD_blockptr - 2; i < SD_blockptr + 2; i++) {
JonFreeman 1:8ef34deb5177 174 pc.printf ("check_SD_block_clear (%d) ", i);
JonFreeman 1:8ef34deb5177 175 if (check_SD_block_clear(i))
JonFreeman 1:8ef34deb5177 176 pc.printf ("block %ld is CLEAR\r\n", i);
JonFreeman 1:8ef34deb5177 177 else
JonFreeman 1:8ef34deb5177 178 pc.printf ("block %ld is NOT clear\r\n", i);
JonFreeman 1:8ef34deb5177 179 if (sd_error()) {
JonFreeman 1:8ef34deb5177 180 pc.printf ("ERROR from check_SD_block_clear ()\r\n");
JonFreeman 1:8ef34deb5177 181 }
JonFreeman 1:8ef34deb5177 182 }
JonFreeman 1:8ef34deb5177 183 }
JonFreeman 1:8ef34deb5177 184 return true;
JonFreeman 1:8ef34deb5177 185 }
JonFreeman 1:8ef34deb5177 186
JonFreeman 1:8ef34deb5177 187 void update_SD_card () { // Hall pulse total updated once per sec and saved in blocks of 128 to SD card
JonFreeman 1:8ef34deb5177 188 static int index = 0;
JonFreeman 1:8ef34deb5177 189 static uint32_t buff[(SD_BLOCKSIZE >> 2) + 2];
JonFreeman 1:8ef34deb5177 190 // buff[index++] = speed.pulse_total(); // pulse_total for all time, add this to buffer to write to SD
JonFreeman 1:8ef34deb5177 191 buff[index++] = get_pulse_total(); // pulse_total for all time, add this to buffer to write to SD
JonFreeman 1:8ef34deb5177 192 if (index >= (SD_BLOCKSIZE >> 2)) {
JonFreeman 1:8ef34deb5177 193 pc.printf ("Writing new SD block %d ... ", SD_blockptr);
JonFreeman 1:8ef34deb5177 194 SD_state = sd.WriteBlocks(buff, SD_BLOCKSIZE * SD_blockptr, SD_BLOCKSIZE, 1);
JonFreeman 1:8ef34deb5177 195 SD_blockptr++;
JonFreeman 1:8ef34deb5177 196 if (SD_state == SD_OK)
JonFreeman 1:8ef34deb5177 197 pc.printf ("OK, distance %d\r\n", buff[index - 1] / (int)PULSES_PER_METRE);
JonFreeman 1:8ef34deb5177 198 else
JonFreeman 1:8ef34deb5177 199 pc.printf ("ERROR\r\n");
JonFreeman 1:8ef34deb5177 200 index = 0;
JonFreeman 1:8ef34deb5177 201 }
JonFreeman 1:8ef34deb5177 202 }
JonFreeman 1:8ef34deb5177 203
JonFreeman 1:8ef34deb5177 204