Touch screen drivers control dashboard for miniature locomotive. Features meters for speed, volts, power. Switches for lights, horns. Drives multiple STM3_ESC brushless motor controllers for complete brushless loco system as used in "The Brute" - www.jons-workshop.com

Dependencies:   TS_DISCO_F746NG mbed Servo LCD_DISCO_F746NG BSP_DISCO_F746NG QSPI_DISCO_F746NG AsyncSerial FastPWM

Committer:
JonFreeman
Date:
Wed May 09 15:42:43 2018 +0000
Revision:
7:3b1f44cd4735
Parent:
5:21a8ac83142c
Child:
9:644867052318
Panic recovery from updating mbed lib causing total wipeout

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JonFreeman 4:67478861c670 1 #include "mbed.h"
JonFreeman 4:67478861c670 2 #include "Electric_Loco.h"
JonFreeman 4:67478861c670 3
JonFreeman 4:67478861c670 4 #ifdef QSPI // Defined in Electric_Loco.h
JonFreeman 4:67478861c670 5 #include "QSPI_DISCO_F746NG.h"
JonFreeman 4:67478861c670 6
JonFreeman 4:67478861c670 7 struct log_element {
JonFreeman 4:67478861c670 8 uint32_t pulsetot; // Total distance ever in pulse count
JonFreeman 4:67478861c670 9 uint16_t powerW; // during previous second
JonFreeman 4:67478861c670 10 uint16_t volts; // during previous second
JonFreeman 4:67478861c670 11 } ;
JonFreeman 4:67478861c670 12
JonFreeman 4:67478861c670 13 static const int START_BANK = 97; // Which 4k segment to start at
JonFreeman 4:67478861c670 14 static const int BANKS_4K = 4; // Numof 4k byte pages used to store recent records
JonFreeman 4:67478861c670 15
JonFreeman 4:67478861c670 16 QSPI_DISCO_F746NG qspi;
JonFreeman 4:67478861c670 17 extern Serial pc;
JonFreeman 5:21a8ac83142c 18 //extern uint32_t historic_distance; no longer exkists Apr 2018
JonFreeman 4:67478861c670 19
JonFreeman 4:67478861c670 20 QSPI_Info pQSPI_Info;
JonFreeman 4:67478861c670 21
JonFreeman 4:67478861c670 22 bool qspimemcheck () {
JonFreeman 4:67478861c670 23 qspi.GetInfo(&pQSPI_Info);
JonFreeman 4:67478861c670 24 if ((pQSPI_Info.FlashSize != N25Q128A_FLASH_SIZE) ||
JonFreeman 4:67478861c670 25 (pQSPI_Info.EraseSectorSize != N25Q128A_SUBSECTOR_SIZE) ||
JonFreeman 4:67478861c670 26 (pQSPI_Info.ProgPageSize != N25Q128A_PAGE_SIZE) ||
JonFreeman 4:67478861c670 27 (pQSPI_Info.EraseSectorsNumber != N25Q128A_SUBSECTOR_SIZE) ||
JonFreeman 4:67478861c670 28 (pQSPI_Info.ProgPagesNumber != N25Q128A_SECTOR_SIZE))
JonFreeman 4:67478861c670 29 {
JonFreeman 4:67478861c670 30 error("Get informations FAILED\r\n");
JonFreeman 4:67478861c670 31 return false;
JonFreeman 4:67478861c670 32 }
JonFreeman 4:67478861c670 33 else
JonFreeman 4:67478861c670 34 {
JonFreeman 4:67478861c670 35 pc.printf("Get informations PASSED\r\n");
JonFreeman 4:67478861c670 36 pc.printf ("FLASH_SIZE\t\t%d\r\n", N25Q128A_FLASH_SIZE);
JonFreeman 4:67478861c670 37 pc.printf ("ERASE_SECTOR_SIZE\t%d\r\n", N25Q128A_SUBSECTOR_SIZE);
JonFreeman 4:67478861c670 38 pc.printf ("PROG_PAGE_SIZE\t\t%d\r\n", N25Q128A_PAGE_SIZE);
JonFreeman 4:67478861c670 39 pc.printf ("Erase sectors number\t%d\r\n", N25Q128A_SUBSECTOR_SIZE);
JonFreeman 4:67478861c670 40 pc.printf ("N25Q128A_SECTOR_SIZE\t%d\r\n", N25Q128A_SECTOR_SIZE);
JonFreeman 4:67478861c670 41 return true;
JonFreeman 4:67478861c670 42 }
JonFreeman 4:67478861c670 43 }
JonFreeman 4:67478861c670 44
JonFreeman 4:67478861c670 45 int ask_QSPI_OK () {
JonFreeman 4:67478861c670 46 return QSPI_OK;
JonFreeman 4:67478861c670 47 }
JonFreeman 4:67478861c670 48
JonFreeman 4:67478861c670 49 int qspiinit () {
JonFreeman 4:67478861c670 50 int r = qspi.Init();
JonFreeman 4:67478861c670 51 if (r != QSPI_OK)
JonFreeman 4:67478861c670 52 pc.printf ("QSPI Init failed.\r\n");
JonFreeman 4:67478861c670 53 return r;
JonFreeman 4:67478861c670 54 }
JonFreeman 4:67478861c670 55
JonFreeman 4:67478861c670 56 void show_bank (uint32_t bank) {
JonFreeman 4:67478861c670 57 uint8_t bu[4096];
JonFreeman 4:67478861c670 58 struct log_element * p = (log_element *)bu;
JonFreeman 4:67478861c670 59 if (qspi.Read(bu, bank << 12, 4096) != QSPI_OK) {
JonFreeman 4:67478861c670 60 pc.printf ("Error reading qspi mem in show_bank\r\n");
JonFreeman 4:67478861c670 61 return ;
JonFreeman 4:67478861c670 62 }
JonFreeman 4:67478861c670 63 pc.printf ("Listing records in bank %d\r\n", bank);
JonFreeman 4:67478861c670 64 for (int i = 0; i < 4095 / sizeof(struct log_element); i++) {
JonFreeman 4:67478861c670 65 pc.printf ("p->pulsetot%ld, powerW %d, volts %d, addr %lx\r\n", p->pulsetot, p->powerW, p->volts, (uint32_t)p++);
JonFreeman 4:67478861c670 66 }
JonFreeman 4:67478861c670 67 }
JonFreeman 4:67478861c670 68
JonFreeman 4:67478861c670 69 void show_all_banks ();
JonFreeman 4:67478861c670 70 void show_all_banks () {
JonFreeman 4:67478861c670 71 for (int bank = START_BANK; bank < START_BANK + BANKS_4K; bank++)
JonFreeman 4:67478861c670 72 show_bank (bank);
JonFreeman 4:67478861c670 73 }
JonFreeman 4:67478861c670 74
JonFreeman 4:67478861c670 75 class distance_measurement {
JonFreeman 7:3b1f44cd4735 76 uint32_t total_distance; // Replaces historic_distance from previous iterations
JonFreeman 4:67478861c670 77 uint32_t bank;
JonFreeman 4:67478861c670 78 uint32_t ptr;
JonFreeman 4:67478861c670 79 uint8_t buff[4096]; // Reqd qspi ram 4k at a time into here
JonFreeman 4:67478861c670 80
JonFreeman 4:67478861c670 81 bool test_element_free (uint8_t* p) ;
JonFreeman 4:67478861c670 82 bool test_bank_free (uint32_t addr) ;
JonFreeman 4:67478861c670 83 bool test_buff_free () ;
JonFreeman 4:67478861c670 84 public:
JonFreeman 4:67478861c670 85 bool zero () ;
JonFreeman 7:3b1f44cd4735 86 uint32_t out () ;
JonFreeman 4:67478861c670 87 bool update (uint32_t pulsetot, uint16_t pow, uint16_t volt) ;
JonFreeman 4:67478861c670 88
JonFreeman 4:67478861c670 89 distance_measurement () { // Constructor
JonFreeman 4:67478861c670 90 uint32_t obank = 0, optr = 0, lptr = 0;
JonFreeman 4:67478861c670 91 bool free_elem_found = false;
JonFreeman 4:67478861c670 92 qspi.Init ();
JonFreeman 4:67478861c670 93
JonFreeman 4:67478861c670 94 bank = START_BANK;
JonFreeman 4:67478861c670 95 while (bank < START_BANK + BANKS_4K && !free_elem_found) {
JonFreeman 4:67478861c670 96 if (qspi.Read(buff, bank << 12, 4096) != QSPI_OK) {
JonFreeman 4:67478861c670 97 pc.printf ("Error reading qspi mem\r\n");
JonFreeman 4:67478861c670 98 }
JonFreeman 4:67478861c670 99 for (ptr = 0; !free_elem_found && ptr < 4096; ptr += sizeof(struct log_element)) {
JonFreeman 4:67478861c670 100 free_elem_found = test_element_free (&buff[ptr]);
JonFreeman 4:67478861c670 101 if (free_elem_found) {
JonFreeman 4:67478861c670 102 obank = bank;
JonFreeman 4:67478861c670 103 optr = ptr;
JonFreeman 4:67478861c670 104 pc.printf ("Found free element at bank %d, ptr %x\r\n", bank, ptr);
JonFreeman 4:67478861c670 105 }
JonFreeman 4:67478861c670 106 else { // Not free element found
JonFreeman 4:67478861c670 107 lptr = ptr;
JonFreeman 4:67478861c670 108 }
JonFreeman 4:67478861c670 109 }
JonFreeman 4:67478861c670 110 bank++;
JonFreeman 4:67478861c670 111 }
JonFreeman 4:67478861c670 112 bank = obank;
JonFreeman 4:67478861c670 113 ptr = optr;
JonFreeman 4:67478861c670 114 struct log_element * p = (log_element *)(buff + lptr);
JonFreeman 5:21a8ac83142c 115
JonFreeman 7:3b1f44cd4735 116 // historic_distance = p->pulsetot; // This needs replacing
JonFreeman 7:3b1f44cd4735 117 total_distance = p->pulsetot; // New May 2018, total_distance is metres. Update info arrives in mm.
JonFreeman 5:21a8ac83142c 118
JonFreeman 4:67478861c670 119 pc.printf ("Constructor found free elem at bank %d, position %d, previous total %ld, volts %.3f\r\n", bank, ptr, p->pulsetot, ((double)p->volts) / 500.0);
JonFreeman 4:67478861c670 120 } // endof constructor
JonFreeman 4:67478861c670 121 } odometer;
JonFreeman 4:67478861c670 122
JonFreeman 4:67478861c670 123
JonFreeman 4:67478861c670 124 bool distance_measurement::test_element_free (uint8_t* p) {
JonFreeman 4:67478861c670 125 for (int i = 0; i < sizeof(log_element); i++)
JonFreeman 4:67478861c670 126 if (*(p + i) != 0xff)
JonFreeman 4:67478861c670 127 return false;
JonFreeman 4:67478861c670 128 return true;
JonFreeman 4:67478861c670 129 }
JonFreeman 4:67478861c670 130
JonFreeman 4:67478861c670 131 bool distance_measurement::test_buff_free () {
JonFreeman 4:67478861c670 132 for (int i = 0; i < 4096; i++)
JonFreeman 4:67478861c670 133 if (buff[i] != 0xff)
JonFreeman 4:67478861c670 134 return false;
JonFreeman 4:67478861c670 135 return true;
JonFreeman 4:67478861c670 136 }
JonFreeman 4:67478861c670 137
JonFreeman 4:67478861c670 138 bool distance_measurement::test_bank_free (uint32_t addr) {
JonFreeman 4:67478861c670 139 if (qspi.Read (buff, addr & 0xfffff000, 4096) != QSPI_OK) {
JonFreeman 4:67478861c670 140 pc.printf ("Read error in test_bank_free\r\n");
JonFreeman 4:67478861c670 141 return false;
JonFreeman 4:67478861c670 142 }
JonFreeman 4:67478861c670 143 return test_buff_free ();
JonFreeman 4:67478861c670 144 }
JonFreeman 4:67478861c670 145
JonFreeman 4:67478861c670 146 bool distance_measurement::zero () {
JonFreeman 4:67478861c670 147 bool rv = true;
JonFreeman 7:3b1f44cd4735 148 total_distance = 0;
JonFreeman 4:67478861c670 149 for (int i = START_BANK; i < START_BANK + BANKS_4K; i++) {
JonFreeman 4:67478861c670 150 if (qspi.Erase_Block(i << 12) != QSPI_OK) {
JonFreeman 4:67478861c670 151 pc.printf ("Error zeroing odometer!\r\n");
JonFreeman 4:67478861c670 152 rv = false;
JonFreeman 4:67478861c670 153 }
JonFreeman 4:67478861c670 154 if (!test_bank_free (i << 12))
JonFreeman 4:67478861c670 155 pc.printf ("Bank [%d] not freed in zero\r\n", i);
JonFreeman 4:67478861c670 156 else
JonFreeman 4:67478861c670 157 pc.printf ("Cleared bank [%d] in zero\r\n", i);
JonFreeman 4:67478861c670 158 }
JonFreeman 4:67478861c670 159 bank = START_BANK;
JonFreeman 4:67478861c670 160 ptr = 0;
JonFreeman 4:67478861c670 161 return rv;
JonFreeman 4:67478861c670 162 }
JonFreeman 4:67478861c670 163
JonFreeman 7:3b1f44cd4735 164 bool distance_measurement::update (uint32_t new_metres_travelled, uint16_t powr, uint16_t volt) {
JonFreeman 4:67478861c670 165 bool rv = true;
JonFreeman 7:3b1f44cd4735 166 total_distance += new_metres_travelled;
JonFreeman 4:67478861c670 167 struct log_element d;
JonFreeman 7:3b1f44cd4735 168 d.pulsetot = total_distance;
JonFreeman 4:67478861c670 169 d.powerW = powr;
JonFreeman 4:67478861c670 170 d.volts = volt;
JonFreeman 4:67478861c670 171 uint32_t addr = ptr + (bank << 12);
JonFreeman 4:67478861c670 172 if (qspi.Write ((uint8_t*)&d, addr, sizeof(struct log_element)) != QSPI_OK) {
JonFreeman 4:67478861c670 173 pc.printf ("Write error in odometer update\r\n");
JonFreeman 4:67478861c670 174 qspi.Init(); // Attempt error recovery
JonFreeman 4:67478861c670 175 return false;
JonFreeman 4:67478861c670 176 }
JonFreeman 4:67478861c670 177 ptr += sizeof(struct log_element);
JonFreeman 4:67478861c670 178 if (ptr >= 4096) {
JonFreeman 4:67478861c670 179 ptr -= 4096;
JonFreeman 4:67478861c670 180 bank++;
JonFreeman 4:67478861c670 181 if (bank >= START_BANK + BANKS_4K)
JonFreeman 4:67478861c670 182 bank = START_BANK;
JonFreeman 4:67478861c670 183 //erase bank
JonFreeman 4:67478861c670 184 pc.printf ("About to erase bank %d\r\n", bank);
JonFreeman 4:67478861c670 185 if (qspi.Erase_Block(bank << 12) != QSPI_OK) {
JonFreeman 4:67478861c670 186 pc.printf ("Erase error in odometer update\r\n");
JonFreeman 4:67478861c670 187 rv = false;
JonFreeman 4:67478861c670 188 }
JonFreeman 4:67478861c670 189 }
JonFreeman 4:67478861c670 190 return rv;
JonFreeman 4:67478861c670 191 }
JonFreeman 4:67478861c670 192
JonFreeman 7:3b1f44cd4735 193 uint32_t distance_measurement::out () {
JonFreeman 7:3b1f44cd4735 194 return total_distance;
JonFreeman 7:3b1f44cd4735 195 }
JonFreeman 7:3b1f44cd4735 196
JonFreeman 7:3b1f44cd4735 197
JonFreeman 4:67478861c670 198 bool odometer_zero () ; // Returns true on success
JonFreeman 4:67478861c670 199 bool odometer_zero () { // Returns true on success
JonFreeman 4:67478861c670 200 return odometer.zero ();
JonFreeman 4:67478861c670 201 }
JonFreeman 4:67478861c670 202
JonFreeman 4:67478861c670 203 bool odometer_update (uint32_t pulsetot, uint16_t pow, uint16_t volt) ; // Hall pulse total updated once per sec and saved in blocks of 4096 bytes on QSPI onboard memory
JonFreeman 4:67478861c670 204 bool odometer_update (uint32_t pulsetot, uint16_t pow, uint16_t volt) { // Hall pulse total updated once per sec and saved in blocks of 4096 bytes on QSPI onboard memory
JonFreeman 4:67478861c670 205 return odometer.update (pulsetot, pow, volt);
JonFreeman 4:67478861c670 206 }
JonFreeman 4:67478861c670 207
JonFreeman 7:3b1f44cd4735 208 uint32_t odometer_out () {
JonFreeman 7:3b1f44cd4735 209 return odometer.out();
JonFreeman 7:3b1f44cd4735 210 }
JonFreeman 4:67478861c670 211 #endif