posilani dat

Dependencies:   FatFileSystemCpp mbed PowerControl USBHostLite

Committer:
legwinskij
Date:
Tue Mar 07 13:30:34 2017 +0000
Revision:
20:66ecb2f0e307
Parent:
19:c2476c0ea3e0
Child:
21:d1569911500a
Updated project to support new hw revision v1r2 (BETA)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
legwinskij 15:baa2672a9b38 1 /* BRIEF:
jkaderka 9:8839ecc02e0e 2 * Connects to wifi and listen on ip given by dhcp on port 2000
jkaderka 9:8839ecc02e0e 3 *
legwinskij 18:7acae34b518d 4 * Commands are send in for #X where X is from {S,E,T,B,R}, all commands are
jkaderka 9:8839ecc02e0e 5 * confirmed by mbed by sending #A
jkaderka 9:8839ecc02e0e 6 *
jkaderka 9:8839ecc02e0e 7 * Use #S to start saving data, #E to stop saving. This can be done repeatedly,
jkaderka 9:8839ecc02e0e 8 * mbed saves the data into separated files and generates new swimmer id
jkaderka 9:8839ecc02e0e 9 * At the end, use #T to start data transfer, the format of transmitted data is:
jkaderka 9:8839ecc02e0e 10 *
jkaderka 9:8839ecc02e0e 11 * Header for each swimmer:
jkaderka 9:8839ecc02e0e 12 * (int) -1 (int) -1 (int) swimmer_id
jkaderka 9:8839ecc02e0e 13 * Data itself
jkaderka 9:8839ecc02e0e 14 * (char) 0xAA (int) count 3*(short) acc 3*(float) gyro
jkaderka 9:8839ecc02e0e 15 * End of swimmer block
jkaderka 9:8839ecc02e0e 16 * (int) -1 (int) -1
jkaderka 9:8839ecc02e0e 17 *
jkaderka 9:8839ecc02e0e 18 * where count is number starting on 0, incremented on every packet
jkaderka 9:8839ecc02e0e 19 * 0xAA is a sync byte used to avoid confusion when some bytes are lost during
jkaderka 9:8839ecc02e0e 20 * transmission (UART on faster reates seems to be unstable)
legwinskij 15:baa2672a9b38 21 *
legwinskij 15:baa2672a9b38 22 * CHANGELOG 22/10/2015
legwinskij 15:baa2672a9b38 23 * - Refactored code
legwinskij 15:baa2672a9b38 24 * - Now using USB flash instead of SD card
legwinskij 15:baa2672a9b38 25 * - SIZE of packets to be saved at once changed to 32 (from 1000, saving took too much time, effectively loosing measurements)
legwinskij 15:baa2672a9b38 26 * - Using fwrite to write 32 packets at once (packet size = 16 bytes -> 32*16 = 512 bytes -> USB flash sector size is 512 bytes, thus maximizing fwrite effectivity
legwinskij 15:baa2672a9b38 27 * - Saving of 32 packets takes about 3,5 ms
legwinskij 15:baa2672a9b38 28 * KNOWN ISSUES:
legwinskij 15:baa2672a9b38 29 * - Opening USB disk takes some time, couple first measurements not valid (perhaps open next file right when saving stops ?)
legwinskij 18:7acae34b518d 30 *
legwinskij 18:7acae34b518d 31 * CHANGELOG 13/11/2015
legwinskij 18:7acae34b518d 32 * - Focused on data acquisition
legwinskij 18:7acae34b518d 33 * - #T commands now requires one byte after ACK to pick which swimmer data to send
legwinskij 18:7acae34b518d 34 * - When board resets, it deletes all files on root, to make sure old data won't get send
legwinskij 18:7acae34b518d 35 * - Added new command #B which represents begining of unified scope of data and should be sent right after connecting (clears all files and resets swimmerid)
legwinskij 18:7acae34b518d 36 *
legwinskij 18:7acae34b518d 37 * CHANGELOG 7/1/2016
legwinskij 18:7acae34b518d 38 * - Integrated MPU6000 IMU library
legwinskij 18:7acae34b518d 39 * - Rewritten data acquisition to support new IMU
legwinskij 18:7acae34b518d 40 * - Edited usbhost library to support sandisk flash disk
legwinskij 18:7acae34b518d 41 *
legwinskij 18:7acae34b518d 42 * CHANGELOG 12/1/2016
legwinskij 18:7acae34b518d 43 * - Added delay after chipselect deselection between device bursts (solved gyro data inconsistency)
legwinskij 18:7acae34b518d 44 *
legwinskij 19:c2476c0ea3e0 45 * CHANGELOG 6/5/2016
legwinskij 19:c2476c0ea3e0 46 * - Moved to first real HW (rev 1.0)
legwinskij 19:c2476c0ea3e0 47 * - Added multipurpose button functionality
legwinskij 19:c2476c0ea3e0 48 *
legwinskij 20:66ecb2f0e307 49 * CHANGELOG 19/10/2016
legwinskij 20:66ecb2f0e307 50 * - Added status message
legwinskij 20:66ecb2f0e307 51 * - Changed button behaviour
legwinskij 20:66ecb2f0e307 52 * - Added background battery monitoring
legwinskij 20:66ecb2f0e307 53 * - Added background filesystem monitoring
legwinskij 20:66ecb2f0e307 54 *
legwinskij 20:66ecb2f0e307 55 * CHANGELOG 22/10/2016
legwinskij 20:66ecb2f0e307 56 * - Slightly adjusted wifly communication (added timeouts)
legwinskij 20:66ecb2f0e307 57 * - Disabled TCP autoretransmission on wifly
legwinskij 20:66ecb2f0e307 58 * - Added send log feature
legwinskij 20:66ecb2f0e307 59 *
legwinskij 20:66ecb2f0e307 60 * CHANGELOG 05/03/2017
legwinskij 20:66ecb2f0e307 61 * - Added define switch for new revision of hardware
legwinskij 20:66ecb2f0e307 62 * - HW v1r2 only supports single MPU
legwinskij 20:66ecb2f0e307 63 *
jkaderka 9:8839ecc02e0e 64 */
legwinskij 15:baa2672a9b38 65
legwinskij 15:baa2672a9b38 66 // Includes ====================================================================
legwinskij 15:baa2672a9b38 67
jkaderka 0:16fd37cf4a7c 68 #include "mbed.h"
legwinskij 18:7acae34b518d 69 #include "EthernetPowerControl.h"
legwinskij 18:7acae34b518d 70 #include "MSCFileSystem.h"
legwinskij 14:6bd7d1fff6af 71 #include "PowerControl.h"
legwinskij 18:7acae34b518d 72 #include "DirHandle.h"
legwinskij 18:7acae34b518d 73 #include "mpu6000.h"
jkaderka 0:16fd37cf4a7c 74 #include "stdint.h"
legwinskij 18:7acae34b518d 75 #include "stdio.h"
jkaderka 2:f623d1815dc4 76 #include "utils.h"
jkaderka 4:030c7726c7dc 77 #include "wifi.h"
legwinskij 18:7acae34b518d 78 #include "math.h"
legwinskij 18:7acae34b518d 79
legwinskij 20:66ecb2f0e307 80 // Revision ====================================================================
legwinskij 20:66ecb2f0e307 81
legwinskij 20:66ecb2f0e307 82 // Revision define, it's important to select proper version! (pinmuxes differ)
legwinskij 20:66ecb2f0e307 83 #define REVISION 2
legwinskij 20:66ecb2f0e307 84
legwinskij 15:baa2672a9b38 85 // Defines =====================================================================
legwinskij 15:baa2672a9b38 86
legwinskij 19:c2476c0ea3e0 87 /* Data acquisition related stuff */
legwinskij 18:7acae34b518d 88 //#define SAMPLE_RATE 700000 // Sample rate for ADC conversion
legwinskij 18:7acae34b518d 89 #define SAMPLE_RATE 10000
legwinskij 19:c2476c0ea3e0 90 #define SAMPLE_PERIOD 0.01 // Setting the period of measuring, 0.01 means 100 times per second
legwinskij 15:baa2672a9b38 91 #define SIZE 32 // Setting number of instance in array - for saving to SD card
legwinskij 15:baa2672a9b38 92 #define BUFFER_SIZE (sizeof(int) + sizeof(short)*6) //size of one data block
jkaderka 2:f623d1815dc4 93
legwinskij 19:c2476c0ea3e0 94 /* Battery related defines */
legwinskij 19:c2476c0ea3e0 95 #define UVLO_THRESHOLD 140U // Battery low threshold
legwinskij 19:c2476c0ea3e0 96 #define BATTERY_PERIOD 30U // How often to measure voltage in seconds
legwinskij 19:c2476c0ea3e0 97
legwinskij 19:c2476c0ea3e0 98 /* Button press defines */
legwinskij 19:c2476c0ea3e0 99 #define PRESS_PERIOD_SHUTDOWN 2000U
legwinskij 20:66ecb2f0e307 100 #define PRESS_PERIOD_LOW 250U
legwinskij 20:66ecb2f0e307 101 #define PRESS_PERIOD_HIGH 450U
legwinskij 19:c2476c0ea3e0 102
legwinskij 19:c2476c0ea3e0 103 /* Mass storage realted stuff */
legwinskij 15:baa2672a9b38 104 #define FSNAME "usb"
legwinskij 20:66ecb2f0e307 105 #define LOG_FILE "/usb/log.txt"
legwinskij 19:c2476c0ea3e0 106 #define SPACE_LOW_THRESHOLD 100 // USB Flash disk free threshold
legwinskij 19:c2476c0ea3e0 107 #define SPACE_PERIOD 300U // How often to measure free space in seconds
jkaderka 1:3ec5f7df2410 108
legwinskij 19:c2476c0ea3e0 109 /* Commands swimfly understands */
legwinskij 15:baa2672a9b38 110 #define SAVING_START 'S'
legwinskij 15:baa2672a9b38 111 #define SAVING_STOP 'E'
legwinskij 18:7acae34b518d 112 #define TRANSFER_REQUEST 'T'
legwinskij 18:7acae34b518d 113 #define SCOPE_BEGIN 'B'
legwinskij 15:baa2672a9b38 114 #define CHECK_READY 'R'
legwinskij 20:66ecb2f0e307 115 #define SEND_LOG 'L'
legwinskij 20:66ecb2f0e307 116 #define HALT 'H'
legwinskij 15:baa2672a9b38 117
legwinskij 19:c2476c0ea3e0 118 /* Comm stuff */
legwinskij 19:c2476c0ea3e0 119 #define SOH 0x01
legwinskij 19:c2476c0ea3e0 120
legwinskij 19:c2476c0ea3e0 121 /* Test mode define (undefine to disable) */
legwinskij 19:c2476c0ea3e0 122 //#define LOG_TEST_MODE
legwinskij 19:c2476c0ea3e0 123
legwinskij 15:baa2672a9b38 124 /* Function like macros for leds (bleh) */
jkaderka 1:3ec5f7df2410 125 #define leds_off() { led_measuring = led_sending = led_working = led_saving = 0; }
jkaderka 1:3ec5f7df2410 126 #define leds_error() { led_measuring = led_sending = led_working = led_saving = 1; }
jkaderka 0:16fd37cf4a7c 127
legwinskij 19:c2476c0ea3e0 128 // Function to power down magic USB interface chip with new firmware
legwinskij 19:c2476c0ea3e0 129 #define USR_POWERDOWN (0x104)
legwinskij 19:c2476c0ea3e0 130 int semihost_powerdown() {
legwinskij 19:c2476c0ea3e0 131 uint32_t arg;
legwinskij 19:c2476c0ea3e0 132 return __semihost(USR_POWERDOWN, &arg);
legwinskij 19:c2476c0ea3e0 133 }
legwinskij 19:c2476c0ea3e0 134
legwinskij 20:66ecb2f0e307 135 // Function prototypes =========================================================
legwinskij 20:66ecb2f0e307 136
legwinskij 20:66ecb2f0e307 137 /* File handling */
legwinskij 20:66ecb2f0e307 138 void clearRoot(void);
legwinskij 20:66ecb2f0e307 139 void appendLog(char textToAppend[]);
legwinskij 20:66ecb2f0e307 140 bool doesFileExist(const char *filename);
legwinskij 20:66ecb2f0e307 141 void spaceMeas(void);
legwinskij 20:66ecb2f0e307 142
legwinskij 20:66ecb2f0e307 143 /* Button handlers */
legwinskij 20:66ecb2f0e307 144 void btnPressCallback(void);
legwinskij 20:66ecb2f0e307 145 void btnReleaseCallback(void);
legwinskij 20:66ecb2f0e307 146
legwinskij 20:66ecb2f0e307 147 /* Power management */
legwinskij 20:66ecb2f0e307 148 void pllInit(void);
legwinskij 20:66ecb2f0e307 149 void battMeas(void);
legwinskij 20:66ecb2f0e307 150 void shutdownHandler(void);
legwinskij 20:66ecb2f0e307 151
legwinskij 20:66ecb2f0e307 152 /* Init */
legwinskij 20:66ecb2f0e307 153 void boardInit(void);
legwinskij 20:66ecb2f0e307 154
legwinskij 20:66ecb2f0e307 155 /* Measurement */
legwinskij 20:66ecb2f0e307 156 void measure(void);
legwinskij 20:66ecb2f0e307 157 void setMeasuringFlag(void);
legwinskij 20:66ecb2f0e307 158
legwinskij 20:66ecb2f0e307 159 /* Command functions */
legwinskij 20:66ecb2f0e307 160 void startSaving(void);
legwinskij 20:66ecb2f0e307 161 void stopSaving(void);
legwinskij 20:66ecb2f0e307 162 void transfer(void);
legwinskij 20:66ecb2f0e307 163 void sendLog(void);
legwinskij 20:66ecb2f0e307 164 void halt(void);
legwinskij 20:66ecb2f0e307 165 void beginScope(void);
legwinskij 20:66ecb2f0e307 166 void sendStatus(void);
legwinskij 20:66ecb2f0e307 167
legwinskij 20:66ecb2f0e307 168 /* Generic functions */
legwinskij 20:66ecb2f0e307 169 void blink(void);
legwinskij 20:66ecb2f0e307 170
legwinskij 15:baa2672a9b38 171 // Watchdog class ==============================================================
jkaderka 0:16fd37cf4a7c 172
jkaderka 0:16fd37cf4a7c 173 class Watchdog {
jkaderka 0:16fd37cf4a7c 174 public:
legwinskij 15:baa2672a9b38 175 /* Kick the watchdog with time period setting */
legwinskij 19:c2476c0ea3e0 176 void setKick(float s) {
legwinskij 15:baa2672a9b38 177 LPC_WDT->WDCLKSEL = 0x1; // Set CLK src to PCLK
legwinskij 15:baa2672a9b38 178 uint32_t clk = SystemCoreClock / 16; // WD has a fixed /4 prescaler, PCLK default is /4
legwinskij 15:baa2672a9b38 179 LPC_WDT->WDTC = s * (float)clk;
legwinskij 15:baa2672a9b38 180 LPC_WDT->WDMOD = 0x3; // Enabled and Reset
jkaderka 0:16fd37cf4a7c 181 kick();
jkaderka 0:16fd37cf4a7c 182 }
legwinskij 15:baa2672a9b38 183
legwinskij 15:baa2672a9b38 184 /* Kick the watchdog */
jkaderka 0:16fd37cf4a7c 185 void kick() {
jkaderka 0:16fd37cf4a7c 186 LPC_WDT->WDFEED = 0xAA;
jkaderka 0:16fd37cf4a7c 187 LPC_WDT->WDFEED = 0x55;
jkaderka 0:16fd37cf4a7c 188 }
jkaderka 0:16fd37cf4a7c 189 };
jkaderka 0:16fd37cf4a7c 190
legwinskij 15:baa2672a9b38 191 // Objects & vars ==============================================================
legwinskij 15:baa2672a9b38 192
legwinskij 20:66ecb2f0e307 193 /* Objects */
legwinskij 19:c2476c0ea3e0 194 Watchdog wdt; // Initialize watchdog
legwinskij 19:c2476c0ea3e0 195 Ticker Saving_Ticker; // Ticker for interrupts on measuring
legwinskij 19:c2476c0ea3e0 196 Ticker Battery_Ticker; // Ticker for voltage measurement
legwinskij 19:c2476c0ea3e0 197 Ticker Space_Ticker; // Ticker for free space measurement
legwinskij 20:66ecb2f0e307 198 Wifi wifi(p13, p14, p12, p23); // Wifly module
legwinskij 18:7acae34b518d 199 SPI spi(p5, p6, p7); // NEW MPU6000 SPI connection
legwinskij 19:c2476c0ea3e0 200 MPU6000 mpu(spi, p8); // NEW MPU6000
legwinskij 19:c2476c0ea3e0 201 Timer button_timer; // Button press time counter
legwinskij 20:66ecb2f0e307 202 Serial pc(USBTX, USBRX); // USB Serial port
jkaderka 0:16fd37cf4a7c 203
legwinskij 15:baa2672a9b38 204 /* LED indicators */
legwinskij 20:66ecb2f0e307 205 #if REVISION == 1
legwinskij 20:66ecb2f0e307 206 DigitalOut led_system(p30);
legwinskij 20:66ecb2f0e307 207 #elif REVISION == 2
legwinskij 20:66ecb2f0e307 208 DigitalOut led_system(p27);
legwinskij 20:66ecb2f0e307 209 DigitalOut cs_2(p26);
legwinskij 20:66ecb2f0e307 210 #endif
legwinskij 15:baa2672a9b38 211 DigitalOut led_measuring(LED1);
legwinskij 15:baa2672a9b38 212 DigitalOut led_sending(LED2);
legwinskij 15:baa2672a9b38 213 DigitalOut led_working(LED3);
legwinskij 15:baa2672a9b38 214 DigitalOut led_saving(LED4);
jkaderka 0:16fd37cf4a7c 215
legwinskij 19:c2476c0ea3e0 216 /* System LED notification patterns */
legwinskij 19:c2476c0ea3e0 217 //typedef enum {USER_BOOT, UVLO, DISK_FULL, AOK} blink_t;
legwinskij 19:c2476c0ea3e0 218
legwinskij 19:c2476c0ea3e0 219 /* Power related stuff */
legwinskij 19:c2476c0ea3e0 220 DigitalOut wifly_enable_n(p9);
legwinskij 19:c2476c0ea3e0 221 DigitalOut flash_enable_n(p10);
legwinskij 19:c2476c0ea3e0 222 DigitalOut btn_latch_n(p28);
legwinskij 19:c2476c0ea3e0 223 InterruptIn btn_input(p29);
legwinskij 19:c2476c0ea3e0 224 AnalogIn batt_vol(p15);
legwinskij 19:c2476c0ea3e0 225 volatile uint8_t systemRequest = 0;
legwinskij 19:c2476c0ea3e0 226 volatile bool userShutdownFlag = 0;
legwinskij 19:c2476c0ea3e0 227 volatile bool UVLOShutdownFlag = 0;
legwinskij 19:c2476c0ea3e0 228 volatile uint8_t battLevel = 150U; // Batt level between 136U/3.4816V and 165U/4.2240V (High byte of 16bit voltage measurement)
legwinskij 19:c2476c0ea3e0 229 volatile uint32_t curTime = 0;
legwinskij 19:c2476c0ea3e0 230 volatile uint32_t oldTime = 0;
legwinskij 19:c2476c0ea3e0 231
legwinskij 19:c2476c0ea3e0 232 /* Added for test purposes */
legwinskij 19:c2476c0ea3e0 233 #ifdef LOG_TEST_MODE
legwinskij 20:66ecb2f0e307 234 DigitalOut flagSetNotify(p19);
legwinskij 20:66ecb2f0e307 235 DigitalOut measureNotify(p20);
legwinskij 19:c2476c0ea3e0 236 #endif
legwinskij 15:baa2672a9b38 237
legwinskij 18:7acae34b518d 238 /* USB && saving related stuffs */
legwinskij 15:baa2672a9b38 239 FILE *gfp; // Global file pointer
legwinskij 15:baa2672a9b38 240 MSCFileSystem logger(FSNAME); // Initialize USB flash disk
legwinskij 15:baa2672a9b38 241 char fname[40]; // Variable for name of Text file saved on USB flash disk
legwinskij 19:c2476c0ea3e0 242 static volatile uint64_t absolute = 0; // Variable for numbering saved data
legwinskij 19:c2476c0ea3e0 243 volatile int relative = 0; // Relative packtets saved number
legwinskij 19:c2476c0ea3e0 244 volatile short swimmer_id = 0; // Global swimmer ID
legwinskij 19:c2476c0ea3e0 245 volatile bool measuringFlag = 0; // Flag that is set with interrupt and indicates measurement is to be done
legwinskij 19:c2476c0ea3e0 246 volatile bool savingFlag = 0; // Flag that is set and indicates data is being saved periodically
legwinskij 19:c2476c0ea3e0 247 volatile bool lowSpaceFlag = 0; // Flag that is set when below SPACE_THRESHOLD MB's remain free
legwinskij 19:c2476c0ea3e0 248 volatile uint16_t mbFree = 0; // Variable to store remaining space on USB flash disk
legwinskij 19:c2476c0ea3e0 249
legwinskij 15:baa2672a9b38 250 /* Accelerometer buffers */
jkaderka 5:83f69916e571 251 short int acc_x[SIZE];
jkaderka 5:83f69916e571 252 short int acc_y[SIZE];
jkaderka 5:83f69916e571 253 short int acc_z[SIZE];
jkaderka 0:16fd37cf4a7c 254
legwinskij 15:baa2672a9b38 255 /* Gyroscope buffers */
jkaderka 13:d00c8a6a2e8c 256 short int gyro_x[SIZE];
jkaderka 13:d00c8a6a2e8c 257 short int gyro_y[SIZE];
jkaderka 13:d00c8a6a2e8c 258 short int gyro_z[SIZE];
jkaderka 0:16fd37cf4a7c 259
legwinskij 18:7acae34b518d 260 // Functions -> File handling ==================================================
legwinskij 15:baa2672a9b38 261
legwinskij 18:7acae34b518d 262 /* Clear all files in root directory */
legwinskij 18:7acae34b518d 263 void clearRoot(void)
legwinskij 15:baa2672a9b38 264 {
legwinskij 18:7acae34b518d 265 char buf[40]; // Buffer for string building
legwinskij 18:7acae34b518d 266
legwinskij 18:7acae34b518d 267 /* Dir related structs & vars */
legwinskij 18:7acae34b518d 268 DIR *dir; // Prepare directory handle
legwinskij 18:7acae34b518d 269 struct dirent *file; // Directory entry structure
legwinskij 18:7acae34b518d 270 dir = opendir("/usb"); // Open root of usb flash disk
legwinskij 18:7acae34b518d 271
legwinskij 18:7acae34b518d 272 /* Iterate all files beside log file in root directory and delete them */
legwinskij 18:7acae34b518d 273 while((file = readdir(dir)) != NULL) // Incrementally points to next files, until NULL is reached
legwinskij 18:7acae34b518d 274 {
legwinskij 18:7acae34b518d 275 if (strcmp(file->d_name, "log.txt") != 0) // Only dele non-log files
legwinskij 18:7acae34b518d 276 {
legwinskij 18:7acae34b518d 277 sprintf(buf, "/usb/");
legwinskij 18:7acae34b518d 278 sprintf(buf+5, file->d_name);
legwinskij 18:7acae34b518d 279 remove(buf); // Remove file that is currently being pointed to
legwinskij 18:7acae34b518d 280 }
legwinskij 18:7acae34b518d 281 }
legwinskij 18:7acae34b518d 282
legwinskij 18:7acae34b518d 283 /* If file is not present */
legwinskij 18:7acae34b518d 284 closedir(dir); // Close dir & return false
legwinskij 15:baa2672a9b38 285 }
legwinskij 15:baa2672a9b38 286
legwinskij 20:66ecb2f0e307 287 /* Append line to log file */
legwinskij 18:7acae34b518d 288 void appendLog(char textToAppend[])
legwinskij 18:7acae34b518d 289 {
legwinskij 18:7acae34b518d 290 printf("Writing to log file...\r\n");
jkaderka 0:16fd37cf4a7c 291
legwinskij 18:7acae34b518d 292 /* Append line to log file */
legwinskij 20:66ecb2f0e307 293 FILE *log;
legwinskij 20:66ecb2f0e307 294 log = fopen(LOG_FILE, "a"); // Open file with log name
legwinskij 20:66ecb2f0e307 295 fprintf(log, "%s\r\n", textToAppend); // Append line
legwinskij 20:66ecb2f0e307 296 fclose(log); // Close file
legwinskij 15:baa2672a9b38 297 }
legwinskij 15:baa2672a9b38 298
legwinskij 17:ca53e6d36163 299 /* Sees whether giver file exists on flash disk */
legwinskij 17:ca53e6d36163 300 bool doesFileExist(const char *filename)
legwinskij 17:ca53e6d36163 301 {
legwinskij 17:ca53e6d36163 302 /* Dir related structs & vars */
legwinskij 17:ca53e6d36163 303 DIR *dir; // Prepare directory handle
legwinskij 17:ca53e6d36163 304 struct dirent *file; // Directory entry structure
legwinskij 17:ca53e6d36163 305 dir = opendir("/usb"); // Open root of usb flash disk
legwinskij 17:ca53e6d36163 306
legwinskij 17:ca53e6d36163 307 /* Iterate all available files in root directory */
legwinskij 17:ca53e6d36163 308 while((file = readdir(dir)) != NULL) // Incrementally points to next files, until NULL is reached
legwinskij 17:ca53e6d36163 309 {
legwinskij 17:ca53e6d36163 310 /* Check if it's file we are looking for */
legwinskij 17:ca53e6d36163 311 if(strcmp(filename+5, file->d_name) == 0) // +5 moves us beyond /usb/, not cool I know...
legwinskij 17:ca53e6d36163 312 {
legwinskij 17:ca53e6d36163 313 closedir(dir); // Close dir & return true
legwinskij 17:ca53e6d36163 314 return true;
legwinskij 17:ca53e6d36163 315 }
legwinskij 17:ca53e6d36163 316 }
legwinskij 17:ca53e6d36163 317
legwinskij 17:ca53e6d36163 318 /* If file is not present */
legwinskij 17:ca53e6d36163 319 closedir(dir); // Close dir & return false
legwinskij 17:ca53e6d36163 320 return false; // If not, return false
legwinskij 19:c2476c0ea3e0 321 }
legwinskij 19:c2476c0ea3e0 322
legwinskij 19:c2476c0ea3e0 323 /* Measures space left and updates global variable value */
legwinskij 19:c2476c0ea3e0 324 void spaceMeas(void)
legwinskij 19:c2476c0ea3e0 325 {
legwinskij 19:c2476c0ea3e0 326 FATFS* fs;
legwinskij 19:c2476c0ea3e0 327 DWORD fre_clust;
legwinskij 19:c2476c0ea3e0 328 f_getfree("0:",&fre_clust,&fs);
legwinskij 19:c2476c0ea3e0 329 mbFree = (uint16_t)((fs->csize * fs->free_clust) >> 11);
legwinskij 20:66ecb2f0e307 330 }
legwinskij 17:ca53e6d36163 331
legwinskij 19:c2476c0ea3e0 332 // Functions -> Power management ===============================================
legwinskij 19:c2476c0ea3e0 333
legwinskij 20:66ecb2f0e307 334 void pllInit(void)
legwinskij 20:66ecb2f0e307 335 {
legwinskij 20:66ecb2f0e307 336 LPC_SC->PLL0CON = 0x00; /* PLL0 Disable */
legwinskij 20:66ecb2f0e307 337 LPC_SC->PLL0FEED = 0xAA;
legwinskij 20:66ecb2f0e307 338 LPC_SC->PLL0FEED = 0x55;
legwinskij 20:66ecb2f0e307 339
legwinskij 20:66ecb2f0e307 340 LPC_SC->CCLKCFG = 0x00000005; /* Select Clock Divisor = 6 */
legwinskij 20:66ecb2f0e307 341 LPC_SC->PLL0CFG = 0x0000000B; /* configure PLL0 */
legwinskij 20:66ecb2f0e307 342 LPC_SC->PLL0FEED = 0xAA; /* divide by 1 then multiply by 12 */
legwinskij 20:66ecb2f0e307 343 LPC_SC->PLL0FEED = 0x55; /* PLL0 frequency = 288,000,000 */
legwinskij 20:66ecb2f0e307 344
legwinskij 20:66ecb2f0e307 345 LPC_SC->PLL0CON = 0x01; /* PLL0 Enable */
legwinskij 20:66ecb2f0e307 346 LPC_SC->PLL0FEED = 0xAA;
legwinskij 20:66ecb2f0e307 347 LPC_SC->PLL0FEED = 0x55;
legwinskij 20:66ecb2f0e307 348 while (!(LPC_SC->PLL0STAT & (1<<26)));/* Wait for PLOCK0 */
legwinskij 20:66ecb2f0e307 349
legwinskij 20:66ecb2f0e307 350 LPC_SC->PLL0CON = 0x03; /* PLL0 Enable & Connect */
legwinskij 20:66ecb2f0e307 351 LPC_SC->PLL0FEED = 0xAA;
legwinskij 20:66ecb2f0e307 352 LPC_SC->PLL0FEED = 0x55;
legwinskij 20:66ecb2f0e307 353 while (!(LPC_SC->PLL0STAT & ((1<<25) | (1<<24))));/* Wait for PLLC0_STAT & PLLE0_STAT */
legwinskij 20:66ecb2f0e307 354
legwinskij 20:66ecb2f0e307 355 SystemCoreClockUpdate(); /* Should now be at 48,000,000 */
legwinskij 20:66ecb2f0e307 356 SystemCoreClock = (12000000 * 2 /
legwinskij 20:66ecb2f0e307 357 (((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1) *
legwinskij 20:66ecb2f0e307 358 ((LPC_SC->PLL0STAT & 0x7FFF) + 1) /
legwinskij 20:66ecb2f0e307 359 ((LPC_SC->CCLKCFG & 0xFF)+ 1));
legwinskij 20:66ecb2f0e307 360 }
legwinskij 20:66ecb2f0e307 361
legwinskij 19:c2476c0ea3e0 362 /* Callback for button press */
legwinskij 19:c2476c0ea3e0 363 void btnPressCallback(void)
legwinskij 19:c2476c0ea3e0 364 {
legwinskij 19:c2476c0ea3e0 365 /* Resets and starts timer */
legwinskij 19:c2476c0ea3e0 366 button_timer.reset();
legwinskij 19:c2476c0ea3e0 367 button_timer.start();
legwinskij 19:c2476c0ea3e0 368 }
legwinskij 19:c2476c0ea3e0 369
legwinskij 19:c2476c0ea3e0 370 /* Callback for button release */
legwinskij 19:c2476c0ea3e0 371 void btnReleaseCallback(void)
legwinskij 19:c2476c0ea3e0 372 {
legwinskij 19:c2476c0ea3e0 373 /* Stop timer */
legwinskij 19:c2476c0ea3e0 374 button_timer.stop();
legwinskij 19:c2476c0ea3e0 375 /* See whether user is trying to shutdown */
legwinskij 20:66ecb2f0e307 376 uint32_t buf = button_timer.read_ms();
legwinskij 20:66ecb2f0e307 377 if((buf < PRESS_PERIOD_HIGH) && (buf > PRESS_PERIOD_LOW))
legwinskij 19:c2476c0ea3e0 378 {
legwinskij 19:c2476c0ea3e0 379 systemRequest += 1;
legwinskij 19:c2476c0ea3e0 380 }
legwinskij 19:c2476c0ea3e0 381 else
legwinskij 19:c2476c0ea3e0 382 {
legwinskij 19:c2476c0ea3e0 383 led_system = !led_system;
legwinskij 19:c2476c0ea3e0 384 systemRequest = 0;
legwinskij 19:c2476c0ea3e0 385 }
legwinskij 19:c2476c0ea3e0 386 }
legwinskij 19:c2476c0ea3e0 387
legwinskij 19:c2476c0ea3e0 388 /* Does single battery voltage measurement, and sets UVLO flag if voltage too low */
legwinskij 19:c2476c0ea3e0 389 void battMeas(void)
legwinskij 19:c2476c0ea3e0 390 {
legwinskij 19:c2476c0ea3e0 391 battLevel = batt_vol.read_u16() >> 8; // Store High byte of voltage measurement to global variable
legwinskij 19:c2476c0ea3e0 392 if(battLevel < UVLO_THRESHOLD) // Determine whether we have enough juice
legwinskij 19:c2476c0ea3e0 393 {
legwinskij 19:c2476c0ea3e0 394 UVLOShutdownFlag = 1; // Raise Under Voltage Lock Out flag if necessary
legwinskij 19:c2476c0ea3e0 395 }
legwinskij 19:c2476c0ea3e0 396 }
legwinskij 19:c2476c0ea3e0 397
legwinskij 19:c2476c0ea3e0 398 /* Checkes whether UVLO flag is set and halts board if necessary */
legwinskij 19:c2476c0ea3e0 399 void shutdownHandler(void)
legwinskij 19:c2476c0ea3e0 400 {
legwinskij 19:c2476c0ea3e0 401 /* Button shutdown handler */
legwinskij 19:c2476c0ea3e0 402 if(3 == systemRequest)
legwinskij 19:c2476c0ea3e0 403 {
legwinskij 20:66ecb2f0e307 404 halt(); // Halt
legwinskij 19:c2476c0ea3e0 405 }
legwinskij 19:c2476c0ea3e0 406 /* UVLO shutdown handler */
legwinskij 19:c2476c0ea3e0 407 if(1 == UVLOShutdownFlag) // Control of flag that is being set asynchronously if battLevel drops below threshold
legwinskij 19:c2476c0ea3e0 408 {
legwinskij 19:c2476c0ea3e0 409 if (1 == savingFlag) // If saving's in progress stop it, to make sure file system won't get corrupted
legwinskij 19:c2476c0ea3e0 410 {
legwinskij 19:c2476c0ea3e0 411 stopSaving();
legwinskij 19:c2476c0ea3e0 412 }
legwinskij 19:c2476c0ea3e0 413 UVLOShutdownFlag = 0;
legwinskij 19:c2476c0ea3e0 414 blink();
legwinskij 19:c2476c0ea3e0 415 blink();
legwinskij 20:66ecb2f0e307 416 appendLog("Battery low halting");
legwinskij 19:c2476c0ea3e0 417 printf("Battery low, halting.\r\n");
legwinskij 19:c2476c0ea3e0 418 btn_latch_n = 1; // Halt
legwinskij 19:c2476c0ea3e0 419 }
legwinskij 19:c2476c0ea3e0 420 }
legwinskij 19:c2476c0ea3e0 421
legwinskij 18:7acae34b518d 422 // Functions -> Init ===========================================================
legwinskij 18:7acae34b518d 423
legwinskij 18:7acae34b518d 424 /* Prepares board for operation (adc's, gyroscope etc.) */
legwinskij 18:7acae34b518d 425 void boardInit (void)
legwinskij 20:66ecb2f0e307 426 {
legwinskij 20:66ecb2f0e307 427 //pllInit();
legwinskij 20:66ecb2f0e307 428 pc.baud(9600);
legwinskij 20:66ecb2f0e307 429 pc.printf("\r\nBooting...\r\n"); // Notify user that board is booting
legwinskij 20:66ecb2f0e307 430 pc.printf("SystemCoreClock = %d Hz\r\n", SystemCoreClock);
legwinskij 20:66ecb2f0e307 431
legwinskij 19:c2476c0ea3e0 432 /* Watchdog */
legwinskij 19:c2476c0ea3e0 433 if ((LPC_WDT->WDMOD >> 2) & 1)
legwinskij 19:c2476c0ea3e0 434 {
legwinskij 19:c2476c0ea3e0 435 led_system = 1;
legwinskij 19:c2476c0ea3e0 436 wait(1);
legwinskij 19:c2476c0ea3e0 437 led_system = 0;
legwinskij 19:c2476c0ea3e0 438 }
legwinskij 19:c2476c0ea3e0 439 wdt.setKick(15.0);
legwinskij 18:7acae34b518d 440
legwinskij 19:c2476c0ea3e0 441 /* Power related stuff */
legwinskij 19:c2476c0ea3e0 442 btn_latch_n = 0; // This latch holds power P-MOS opened in order to provide power to whole board
legwinskij 19:c2476c0ea3e0 443 wait_ms(20);
legwinskij 19:c2476c0ea3e0 444 flash_enable_n = 0;
legwinskij 19:c2476c0ea3e0 445 wait_ms(20);
legwinskij 19:c2476c0ea3e0 446 wifly_enable_n = 0;
legwinskij 20:66ecb2f0e307 447 wifi.init(); // Initialize wifly
legwinskij 19:c2476c0ea3e0 448 led_measuring = 1; // Use incremental LED's to notify user about boot stages
legwinskij 20:66ecb2f0e307 449 #if REVISION == 2
legwinskij 20:66ecb2f0e307 450 cs_2 = 1;
legwinskij 20:66ecb2f0e307 451 #endif
legwinskij 19:c2476c0ea3e0 452 /* IMU init */
legwinskij 20:66ecb2f0e307 453 uint8_t name = mpu.init(); // Initializes both gyro and accelerometer
legwinskij 20:66ecb2f0e307 454 printf("0x%02X MPUID\r\n", name);
legwinskij 19:c2476c0ea3e0 455 wait_ms(40); // Wait for settings to stabilize
legwinskij 18:7acae34b518d 456 led_sending = 1; // Light up second LED to notify mpu init ok
legwinskij 20:66ecb2f0e307 457
legwinskij 19:c2476c0ea3e0 458 /* Power saving features */
legwinskij 18:7acae34b518d 459 PHY_PowerDown(); // Disable ETH PHY to conserve power (about 40mA)
legwinskij 19:c2476c0ea3e0 460 semihost_powerdown(); // Disable USB Host to conserve power (about 30mA)
legwinskij 18:7acae34b518d 461 clearRoot(); // Clear all files that remain from previous sessions
legwinskij 19:c2476c0ea3e0 462 wait_ms(40); // Wait a bit
legwinskij 19:c2476c0ea3e0 463 led_working = 1; // Light up third LED
legwinskij 19:c2476c0ea3e0 464
legwinskij 19:c2476c0ea3e0 465 /* Measure voltage */
legwinskij 19:c2476c0ea3e0 466 battMeas();
legwinskij 19:c2476c0ea3e0 467 printf("%d mV\r\n", (battLevel << 8) / 10);
legwinskij 19:c2476c0ea3e0 468 spaceMeas();
legwinskij 19:c2476c0ea3e0 469 printf("%d MB\r\n", mbFree);
legwinskij 19:c2476c0ea3e0 470 shutdownHandler();
legwinskij 19:c2476c0ea3e0 471 wait_ms(40);
legwinskij 19:c2476c0ea3e0 472 led_saving = 1;
legwinskij 19:c2476c0ea3e0 473
legwinskij 19:c2476c0ea3e0 474 /* Timers & Tickers init */
legwinskij 19:c2476c0ea3e0 475 Battery_Ticker.attach(&battMeas, BATTERY_PERIOD);
legwinskij 19:c2476c0ea3e0 476 Space_Ticker.attach(&spaceMeas, SPACE_PERIOD);
legwinskij 19:c2476c0ea3e0 477 button_timer.start(); // Start timer that counts lengths of button presses
legwinskij 19:c2476c0ea3e0 478 btn_input.fall(&btnPressCallback); // Attach button press callback
legwinskij 19:c2476c0ea3e0 479 btn_input.rise(&btnReleaseCallback); // Attach button release callback
legwinskij 19:c2476c0ea3e0 480 wait_ms(40);
legwinskij 18:7acae34b518d 481
legwinskij 18:7acae34b518d 482 /* End of init */
legwinskij 19:c2476c0ea3e0 483 appendLog("Booted"); // Append line to log file
legwinskij 18:7acae34b518d 484 leds_off(); // Turn all LEDs off
legwinskij 19:c2476c0ea3e0 485 blink(); // Blink system led to notify user
legwinskij 20:66ecb2f0e307 486 wdt.setKick(5);
legwinskij 20:66ecb2f0e307 487 pc.printf("Ready...\r\n"); // Notify user of end init
legwinskij 18:7acae34b518d 488 }
legwinskij 18:7acae34b518d 489
legwinskij 18:7acae34b518d 490 // Functions -> Measuring ======================================================
legwinskij 18:7acae34b518d 491
legwinskij 18:7acae34b518d 492 /* Main measuring function */
legwinskij 19:c2476c0ea3e0 493 void measure(void)
legwinskij 18:7acae34b518d 494 {
legwinskij 18:7acae34b518d 495 /* Vars */
legwinskij 18:7acae34b518d 496 char buffer[SIZE][BUFFER_SIZE]; // Buffer
legwinskij 18:7acae34b518d 497 int pos = 0; // Position
legwinskij 18:7acae34b518d 498
legwinskij 18:7acae34b518d 499 /* Read IMU values */
legwinskij 18:7acae34b518d 500 mpu.valRead(ACCEL, acc_x[relative], acc_y[relative], acc_z[relative]); // Read Accelerometer values
legwinskij 18:7acae34b518d 501 mpu.valRead(GYRO, gyro_x[relative], gyro_y[relative],gyro_z[relative]); // Read Gyroscope values
legwinskij 18:7acae34b518d 502
legwinskij 18:7acae34b518d 503 /* Increment counters */
legwinskij 18:7acae34b518d 504 absolute++; // Increment absolute counter
legwinskij 18:7acae34b518d 505 relative++; // Increment relative counter
legwinskij 18:7acae34b518d 506
legwinskij 18:7acae34b518d 507 /* After our buffers are full save the data */
legwinskij 18:7acae34b518d 508 if ( absolute % SIZE == 0 )
legwinskij 18:7acae34b518d 509 {
legwinskij 18:7acae34b518d 510 /* Flip led_saving state */
legwinskij 18:7acae34b518d 511 led_saving = !led_saving;
legwinskij 18:7acae34b518d 512
legwinskij 18:7acae34b518d 513 /* Handle file error */
legwinskij 18:7acae34b518d 514 if (gfp == NULL) {
legwinskij 18:7acae34b518d 515 printf("Unable to append data to file %s\r\n", fname); // Notify user
legwinskij 18:7acae34b518d 516 return; // Return
legwinskij 18:7acae34b518d 517 }
legwinskij 18:7acae34b518d 518
legwinskij 18:7acae34b518d 519 /* Iterate all buffer elements */
legwinskij 18:7acae34b518d 520 for (int k = 0; k < SIZE; k++)
legwinskij 18:7acae34b518d 521 {
legwinskij 18:7acae34b518d 522 pos = absolute-SIZE+k; // Increment position
legwinskij 18:7acae34b518d 523 toBytes(buffer[k], &pos, sizeof(int)); // Append data to buffer in byte form
legwinskij 18:7acae34b518d 524 toBytes(buffer[k]+sizeof(int), &acc_x[k], sizeof(short));
legwinskij 18:7acae34b518d 525 toBytes(buffer[k]+sizeof(int) + sizeof(short), &acc_y[k], sizeof(short));
legwinskij 18:7acae34b518d 526 toBytes(buffer[k]+sizeof(int) + sizeof(short)*2, &acc_z[k], sizeof(short));
legwinskij 18:7acae34b518d 527 toBytes(buffer[k]+sizeof(int) + sizeof(short)*3, &gyro_x[k], sizeof(short));
legwinskij 18:7acae34b518d 528 toBytes(buffer[k]+sizeof(int) + sizeof(short)*4, &gyro_y[k], sizeof(short));
legwinskij 18:7acae34b518d 529 toBytes(buffer[k]+sizeof(int) + sizeof(short)*5, &gyro_z[k], sizeof(short));
legwinskij 18:7acae34b518d 530 }
legwinskij 18:7acae34b518d 531
legwinskij 18:7acae34b518d 532 /* Write */
legwinskij 19:c2476c0ea3e0 533 #ifdef LOG_TEST_MODE
legwinskij 19:c2476c0ea3e0 534 measureNotify = 1; // Used for saving debug
legwinskij 19:c2476c0ea3e0 535 #endif
legwinskij 18:7acae34b518d 536 fwrite(buffer, SIZE, BUFFER_SIZE, gfp); // Write 32 buffer lines (16 bytes) to file (512 bytes total -> one block)
legwinskij 18:7acae34b518d 537 fflush(gfp); // Flush to make sure nothing is left in buffer
legwinskij 19:c2476c0ea3e0 538 #ifdef LOG_TEST_MODE
legwinskij 19:c2476c0ea3e0 539 measureNotify = 0; // Used for saving debug
legwinskij 19:c2476c0ea3e0 540 #endif
legwinskij 18:7acae34b518d 541
legwinskij 18:7acae34b518d 542 /* Reset relative counter */
legwinskij 18:7acae34b518d 543 relative = 0;
legwinskij 18:7acae34b518d 544 }
legwinskij 18:7acae34b518d 545 }
legwinskij 18:7acae34b518d 546
legwinskij 18:7acae34b518d 547 /* Sets the measuring flag */
legwinskij 18:7acae34b518d 548 void setMeasuringFlag(void)
legwinskij 18:7acae34b518d 549 {
legwinskij 19:c2476c0ea3e0 550 #ifdef LOG_TEST_MODE
legwinskij 19:c2476c0ea3e0 551 flagSetNotify = 1; // Used for saving debug
legwinskij 19:c2476c0ea3e0 552 #endif
legwinskij 18:7acae34b518d 553 measuringFlag = 1; // Set measuring flag
legwinskij 19:c2476c0ea3e0 554 #ifdef LOG_TEST_MODE
legwinskij 19:c2476c0ea3e0 555 flagSetNotify = 0; // Used for saving debug
legwinskij 19:c2476c0ea3e0 556 #endif
legwinskij 18:7acae34b518d 557 }
legwinskij 18:7acae34b518d 558
legwinskij 17:ca53e6d36163 559 // Functions -> Commands =======================================================
legwinskij 17:ca53e6d36163 560
legwinskij 15:baa2672a9b38 561 /* Starts to acquire data from sensors */
legwinskij 15:baa2672a9b38 562 void startSaving(void)
legwinskij 15:baa2672a9b38 563 {
legwinskij 19:c2476c0ea3e0 564 savingFlag = 1; // Set saving flag
legwinskij 15:baa2672a9b38 565 /* Open global file with current swimmer ID */
legwinskij 15:baa2672a9b38 566 gfp = fopen(fname, "wb"); // Try to open that file
legwinskij 15:baa2672a9b38 567 if(gfp == NULL) {
legwinskij 15:baa2672a9b38 568 leds_error(); // Turn on all leds
legwinskij 18:7acae34b518d 569 printf("Unable to open file %s for writing\r\n", fname); // Notify user
legwinskij 15:baa2672a9b38 570 return; // Exit function
legwinskij 15:baa2672a9b38 571 }
legwinskij 15:baa2672a9b38 572
legwinskij 15:baa2672a9b38 573 /* Prepare file & vars for data acquisition */
legwinskij 15:baa2672a9b38 574 fprintf(gfp, "%c%c%c", -1, -1, swimmer_id); // Append header to current swimmer output file
legwinskij 18:7acae34b518d 575 fflush(gfp);
legwinskij 15:baa2672a9b38 576
legwinskij 15:baa2672a9b38 577 /* Reset counters */
legwinskij 15:baa2672a9b38 578 absolute = 0; // Reset absolute counter
legwinskij 15:baa2672a9b38 579 relative = 0; // Reset relative counter
legwinskij 15:baa2672a9b38 580
legwinskij 15:baa2672a9b38 581 /* Set timer */
legwinskij 19:c2476c0ea3e0 582 Saving_Ticker.attach(&setMeasuringFlag, SAMPLE_PERIOD); // Attach function that periodically sets the flag
legwinskij 15:baa2672a9b38 583 }
legwinskij 15:baa2672a9b38 584
legwinskij 19:c2476c0ea3e0 585 /* Stops acquiring data, and save data left in buffers to USB */
legwinskij 15:baa2672a9b38 586 void stopSaving(void)
legwinskij 15:baa2672a9b38 587 {
legwinskij 19:c2476c0ea3e0 588 savingFlag = 0; // Clear saving flag
legwinskij 15:baa2672a9b38 589 /* Stop saving */
legwinskij 15:baa2672a9b38 590 Saving_Ticker.detach(); // Stop setting measuring flag
jkaderka 1:3ec5f7df2410 591
legwinskij 15:baa2672a9b38 592 /* Try to append data left in buffers */
legwinskij 15:baa2672a9b38 593 if(gfp == NULL) {
legwinskij 15:baa2672a9b38 594 leds_error(); // Turn on all leds
legwinskij 18:7acae34b518d 595 printf("Unable to open file %s before sending data\r\n", fname); // Notify user
legwinskij 15:baa2672a9b38 596 return; // Exit function
legwinskij 15:baa2672a9b38 597 }
legwinskij 15:baa2672a9b38 598
legwinskij 15:baa2672a9b38 599 /* Append data left to buffer */
legwinskij 15:baa2672a9b38 600 int base = ((absolute - (absolute%SIZE)) < 0) ? 0 : absolute - (absolute%SIZE);
legwinskij 15:baa2672a9b38 601 char buffer[relative][BUFFER_SIZE]; // packet array
legwinskij 15:baa2672a9b38 602
legwinskij 15:baa2672a9b38 603 /* Iterate all array elements */
legwinskij 15:baa2672a9b38 604 for (int k = 0; k < relative; k++) {
legwinskij 15:baa2672a9b38 605 int pos = base+k;
legwinskij 15:baa2672a9b38 606 toBytes(buffer[k], &pos, sizeof(int));
legwinskij 15:baa2672a9b38 607 toBytes(buffer[k]+sizeof(int), &acc_x[k], sizeof(short));
legwinskij 15:baa2672a9b38 608 toBytes(buffer[k]+sizeof(int) + sizeof(short), &acc_y[k], sizeof(short));
legwinskij 15:baa2672a9b38 609 toBytes(buffer[k]+sizeof(int) + sizeof(short)*2, &acc_z[k], sizeof(short));
legwinskij 15:baa2672a9b38 610 toBytes(buffer[k]+sizeof(int) + sizeof(short)*3, &gyro_x[k], sizeof(short));
legwinskij 15:baa2672a9b38 611 toBytes(buffer[k]+sizeof(int) + sizeof(short)*4, &gyro_y[k], sizeof(short));
legwinskij 15:baa2672a9b38 612 toBytes(buffer[k]+sizeof(int) + sizeof(short)*5, &gyro_z[k], sizeof(short));
legwinskij 15:baa2672a9b38 613 }
legwinskij 15:baa2672a9b38 614
legwinskij 15:baa2672a9b38 615 /* Write what's left */
legwinskij 15:baa2672a9b38 616 fwrite(buffer, relative, BUFFER_SIZE, gfp); // Write all data at once
legwinskij 18:7acae34b518d 617 fflush(gfp);
legwinskij 15:baa2672a9b38 618
legwinskij 15:baa2672a9b38 619 /* Append EOF and close file */
legwinskij 15:baa2672a9b38 620 fprintf(gfp, "%c%c", -1,-1); // Write EOF characters
legwinskij 18:7acae34b518d 621 fflush(gfp);
legwinskij 15:baa2672a9b38 622 fclose(gfp); // Close file
jkaderka 1:3ec5f7df2410 623
legwinskij 15:baa2672a9b38 624 /* Prepare for next swimmer */
legwinskij 15:baa2672a9b38 625 swimmer_id++; // Increment swimmer ID
legwinskij 15:baa2672a9b38 626 sprintf(fname, "/usb/swimmer%d.txt", swimmer_id); // Update current file name
legwinskij 15:baa2672a9b38 627 remove(fname); // If file with such ID exists remove it to avoid reading old data
legwinskij 15:baa2672a9b38 628 }
legwinskij 15:baa2672a9b38 629
legwinskij 15:baa2672a9b38 630 /* Sends acquired data via Wi-Fi */
legwinskij 15:baa2672a9b38 631 void transfer(void)
legwinskij 15:baa2672a9b38 632 {
legwinskij 17:ca53e6d36163 633 /* Vars */
legwinskij 17:ca53e6d36163 634 char name[30]; // File name buffer
legwinskij 17:ca53e6d36163 635
legwinskij 17:ca53e6d36163 636 /* File transfer prerequisites */
legwinskij 20:66ecb2f0e307 637 fclose(gfp);
legwinskij 20:66ecb2f0e307 638 int requested_id = wifi.readByte(); // Get byte containing requested file ID
legwinskij 20:66ecb2f0e307 639 sprintf(name, "/usb/swimmer%d.txt", requested_id); // Create file name based on current swimmer ID
legwinskij 15:baa2672a9b38 640
legwinskij 17:ca53e6d36163 641 /* Handle transfer */
legwinskij 20:66ecb2f0e307 642 if(doesFileExist(name)) // At first check whether file exists (fopen used to freeze mbed)
legwinskij 20:66ecb2f0e307 643 {
legwinskij 20:66ecb2f0e307 644 /* Send ACK */
legwinskij 20:66ecb2f0e307 645 wifi.sendAck();
legwinskij 20:66ecb2f0e307 646 wait_ms(50); // Timeout is used to make sure C# gets ready (sockets are messy, flushing is pain)
legwinskij 20:66ecb2f0e307 647 /* Actually try to send file */
legwinskij 20:66ecb2f0e307 648 printf("Sending %s\r\n", name); // Notify user which user is being sent
legwinskij 20:66ecb2f0e307 649 if (wifi.sendFile(name)) // Send !
legwinskij 20:66ecb2f0e307 650 {
legwinskij 20:66ecb2f0e307 651 leds_error(); // Handle error
legwinskij 20:66ecb2f0e307 652 printf("Unable to send data (ID:%d)\r\n", requested_id); // Notify user via text also
legwinskij 20:66ecb2f0e307 653 }
legwinskij 20:66ecb2f0e307 654 else
legwinskij 20:66ecb2f0e307 655 {
legwinskij 20:66ecb2f0e307 656 printf("Swimmer %d finished\r\n", requested_id); // Otherwise all is AOK
legwinskij 20:66ecb2f0e307 657 }
legwinskij 20:66ecb2f0e307 658 }
legwinskij 20:66ecb2f0e307 659 else
legwinskij 20:66ecb2f0e307 660 {
legwinskij 20:66ecb2f0e307 661 /* In case file doest not exist send NACK */
legwinskij 20:66ecb2f0e307 662 wifi.sendByte('#');
legwinskij 20:66ecb2f0e307 663 wifi.sendByte('F');
legwinskij 20:66ecb2f0e307 664 printf("Requested non-existing file...\r\n");
legwinskij 20:66ecb2f0e307 665 }
legwinskij 20:66ecb2f0e307 666 }
legwinskij 20:66ecb2f0e307 667
legwinskij 20:66ecb2f0e307 668 /* Sends log file*/
legwinskij 20:66ecb2f0e307 669 void sendLog(void)
legwinskij 20:66ecb2f0e307 670 {
legwinskij 20:66ecb2f0e307 671 /* Vars */
legwinskij 20:66ecb2f0e307 672 char name[30]; // File name buffer
legwinskij 20:66ecb2f0e307 673
legwinskij 20:66ecb2f0e307 674 /* File transfer prerequisites */
legwinskij 20:66ecb2f0e307 675 sprintf(name, LOG_FILE); // Create file name from log name
legwinskij 20:66ecb2f0e307 676 /* Handle transfer */
legwinskij 17:ca53e6d36163 677 if(doesFileExist(name)) // At first check whether file exists (fopen used to freeze mbed)
legwinskij 15:baa2672a9b38 678 {
legwinskij 17:ca53e6d36163 679 /* Send ACK (should make this more abstract) */
legwinskij 20:66ecb2f0e307 680 wifi.sendAck();
legwinskij 17:ca53e6d36163 681 wait_ms(50); // Timeout is used to make sure C# gets ready (sockets are messy, flushing is pain)
legwinskij 17:ca53e6d36163 682 /* Actually try to send file */
legwinskij 18:7acae34b518d 683 printf("Sending %s\r\n", name); // Notify user which user is being sent
legwinskij 20:66ecb2f0e307 684 if (wifi.sendFile(name)) // Send !
legwinskij 15:baa2672a9b38 685 {
legwinskij 15:baa2672a9b38 686 leds_error(); // Handle error
legwinskij 20:66ecb2f0e307 687 printf("Unable to send log file\r\n"); // Notify user via text also
legwinskij 15:baa2672a9b38 688 }
legwinskij 15:baa2672a9b38 689 else
legwinskij 15:baa2672a9b38 690 {
legwinskij 20:66ecb2f0e307 691 printf("Log file sent!\r\n"); // Otherwise all is AOK
legwinskij 17:ca53e6d36163 692 }
legwinskij 17:ca53e6d36163 693 }
legwinskij 17:ca53e6d36163 694 else
legwinskij 17:ca53e6d36163 695 {
legwinskij 17:ca53e6d36163 696 /* In case file doest not exist send NACK */
legwinskij 17:ca53e6d36163 697 wifi.sendByte('#');
legwinskij 17:ca53e6d36163 698 wifi.sendByte('F');
legwinskij 18:7acae34b518d 699 printf("Requested non-existing file...\r\n");
legwinskij 18:7acae34b518d 700 }
legwinskij 18:7acae34b518d 701 }
legwinskij 18:7acae34b518d 702
legwinskij 20:66ecb2f0e307 703 /* Halts board */
legwinskij 20:66ecb2f0e307 704 void halt(void)
legwinskij 20:66ecb2f0e307 705 {
legwinskij 20:66ecb2f0e307 706 if (1 == savingFlag) // If saving's in progress stop it, to make sure file system won't get corrupted
legwinskij 20:66ecb2f0e307 707 {
legwinskij 20:66ecb2f0e307 708 stopSaving();
legwinskij 20:66ecb2f0e307 709 }
legwinskij 20:66ecb2f0e307 710 systemRequest = 0;
legwinskij 20:66ecb2f0e307 711 blink();
legwinskij 20:66ecb2f0e307 712 btn_latch_n = 1;
legwinskij 20:66ecb2f0e307 713 }
legwinskij 20:66ecb2f0e307 714
legwinskij 19:c2476c0ea3e0 715 /* Begins new scope (clears all data && rests swimmer_id counder) */
legwinskij 18:7acae34b518d 716 void beginScope(void)
legwinskij 18:7acae34b518d 717 {
legwinskij 18:7acae34b518d 718 /* Clear all files and reset swimmer_id only when not after reset */
legwinskij 18:7acae34b518d 719 if(swimmer_id != 0) // Redundancy check
legwinskij 18:7acae34b518d 720 {
legwinskij 18:7acae34b518d 721 appendLog("New scope");
legwinskij 18:7acae34b518d 722 clearRoot(); // Clears all files on root of USB flash disk
legwinskij 18:7acae34b518d 723 swimmer_id = 0; // Resets simmer_id counter
legwinskij 18:7acae34b518d 724 sprintf(fname, "/usb/swimmer%d.txt", swimmer_id); // Update current file name
jkaderka 0:16fd37cf4a7c 725 }
jkaderka 0:16fd37cf4a7c 726 }
jkaderka 0:16fd37cf4a7c 727
legwinskij 19:c2476c0ea3e0 728 // Functions -> Generic functions ==============================================
legwinskij 19:c2476c0ea3e0 729
legwinskij 19:c2476c0ea3e0 730 /* Sends status */
legwinskij 19:c2476c0ea3e0 731 void sendStatus(void)
legwinskij 19:c2476c0ea3e0 732 {
legwinskij 19:c2476c0ea3e0 733 uint8_t checksum = SOH + savingFlag + battLevel; // Calculate checksum
legwinskij 19:c2476c0ea3e0 734 wifi.sendByte(SOH); // Send start of heading
legwinskij 19:c2476c0ea3e0 735 wifi.sendByte(savingFlag); // Send state of saving
legwinskij 19:c2476c0ea3e0 736 wifi.sendByte(battLevel); // Sends current battery level
legwinskij 19:c2476c0ea3e0 737 wifi.sendByte(checksum); // Send checksum
legwinskij 19:c2476c0ea3e0 738 }
legwinskij 19:c2476c0ea3e0 739
legwinskij 19:c2476c0ea3e0 740 void blink(void)
legwinskij 19:c2476c0ea3e0 741 {
legwinskij 19:c2476c0ea3e0 742 if(led_system)
legwinskij 19:c2476c0ea3e0 743 {
legwinskij 19:c2476c0ea3e0 744 led_system = 0;
legwinskij 19:c2476c0ea3e0 745 }
legwinskij 19:c2476c0ea3e0 746 wait_ms(200);
legwinskij 19:c2476c0ea3e0 747 led_system = 1;
legwinskij 19:c2476c0ea3e0 748 wait_ms(200);
legwinskij 19:c2476c0ea3e0 749 led_system = 0;
legwinskij 19:c2476c0ea3e0 750 }
legwinskij 19:c2476c0ea3e0 751
legwinskij 15:baa2672a9b38 752 // Main ========================================================================
legwinskij 15:baa2672a9b38 753
jkaderka 0:16fd37cf4a7c 754 int main()
jkaderka 0:16fd37cf4a7c 755 {
legwinskij 20:66ecb2f0e307 756 /* Begin by initialization */
legwinskij 19:c2476c0ea3e0 757 boardInit(); // Initialize board
jkaderka 0:16fd37cf4a7c 758
legwinskij 15:baa2672a9b38 759 /* Set zeroth swimmer name */
legwinskij 15:baa2672a9b38 760 sprintf(fname, "/usb/swimmer%d.txt", swimmer_id); // Prepare zeroth swimmer filename
jkaderka 10:fdf9ca254549 761
legwinskij 15:baa2672a9b38 762 /* Main while */
legwinskij 15:baa2672a9b38 763 while (1)
legwinskij 15:baa2672a9b38 764 {
legwinskij 19:c2476c0ea3e0 765 /* Shutdown handler */
legwinskij 19:c2476c0ea3e0 766 shutdownHandler();
legwinskij 15:baa2672a9b38 767 /* Read command from wifly */
jkaderka 4:030c7726c7dc 768 char cmd = wifi.getCmd();
legwinskij 15:baa2672a9b38 769 /* Master switch */
jkaderka 1:3ec5f7df2410 770 switch (cmd) {
legwinskij 15:baa2672a9b38 771 /* start measuring data periodically and save them info file */
legwinskij 15:baa2672a9b38 772 case SAVING_START:
legwinskij 15:baa2672a9b38 773 {
legwinskij 20:66ecb2f0e307 774 wifi.sendAck();
legwinskij 15:baa2672a9b38 775 leds_off(); // Turn off all leds
legwinskij 15:baa2672a9b38 776 startSaving(); // Actually start saving
legwinskij 18:7acae34b518d 777 printf("Saving swimmer %d...\r\n", swimmer_id); // Notify user
legwinskij 15:baa2672a9b38 778 led_measuring = 1; // Turn on led_measuring
legwinskij 15:baa2672a9b38 779 break; // Break from switch
jkaderka 1:3ec5f7df2410 780 }
jkaderka 1:3ec5f7df2410 781
legwinskij 15:baa2672a9b38 782 /* stop saving data */
legwinskij 15:baa2672a9b38 783 case SAVING_STOP:
legwinskij 15:baa2672a9b38 784 {
legwinskij 20:66ecb2f0e307 785 wifi.sendAck();
legwinskij 15:baa2672a9b38 786 leds_off(); // Turn off all leds
legwinskij 15:baa2672a9b38 787 stopSaving(); // Actually stop saving
legwinskij 18:7acae34b518d 788 printf("Stopped...\r\n"); // Notify user
legwinskij 15:baa2672a9b38 789 break; // Break from switch
jkaderka 1:3ec5f7df2410 790 }
legwinskij 15:baa2672a9b38 791
legwinskij 15:baa2672a9b38 792 /* Send all data */
legwinskij 18:7acae34b518d 793 case TRANSFER_REQUEST:
legwinskij 15:baa2672a9b38 794 {
legwinskij 20:66ecb2f0e307 795 wifi.sendAck();
legwinskij 15:baa2672a9b38 796 leds_off(); // Turn off all leds
legwinskij 15:baa2672a9b38 797 led_sending = 1; // Turn on led_sending
legwinskij 18:7acae34b518d 798 printf("Sending data...\r\n"); // Notify user that data is being sent
legwinskij 15:baa2672a9b38 799 transfer(); // Actually transfer data
legwinskij 18:7acae34b518d 800 printf("Sending finished...\r\n"); // Notify user that data was sent successfully
legwinskij 15:baa2672a9b38 801 leds_off(); // Turn off all leds again
legwinskij 15:baa2672a9b38 802 break; // Break from switch
jkaderka 1:3ec5f7df2410 803 }
jkaderka 1:3ec5f7df2410 804
legwinskij 18:7acae34b518d 805 /* Begin new scope */
legwinskij 18:7acae34b518d 806 case SCOPE_BEGIN:
legwinskij 18:7acae34b518d 807 {
legwinskij 20:66ecb2f0e307 808 wifi.sendAck();
legwinskij 18:7acae34b518d 809 leds_off(); // Turn off all leds
legwinskij 18:7acae34b518d 810 led_measuring = led_saving = 1; // Turn on two leds to depict special behaviour
legwinskij 18:7acae34b518d 811 printf("Starting new scope...\r\n"); // Notify user that new scope is beginning
legwinskij 18:7acae34b518d 812 beginScope(); // Begin scope ! (clear all data && reset swimmer_id counter)
legwinskij 18:7acae34b518d 813 leds_off(); // Turn off all leds
legwinskij 18:7acae34b518d 814 break; // Break
legwinskij 18:7acae34b518d 815 }
legwinskij 18:7acae34b518d 816
legwinskij 20:66ecb2f0e307 817 /* Send log file */
legwinskij 20:66ecb2f0e307 818 case SEND_LOG:
legwinskij 20:66ecb2f0e307 819 {
legwinskij 20:66ecb2f0e307 820 wifi.sendAck();
legwinskij 20:66ecb2f0e307 821 leds_off(); // Turn off all leds
legwinskij 20:66ecb2f0e307 822 led_measuring = led_saving = 1; // Turn on two leds to depict special behaviour
legwinskij 20:66ecb2f0e307 823 printf("Sending log...\r\n"); // Notify user that new scope is beginning
legwinskij 20:66ecb2f0e307 824 sendLog(); // Send log file
legwinskij 20:66ecb2f0e307 825 leds_off(); // Turn off all leds
legwinskij 20:66ecb2f0e307 826 break; // Break
legwinskij 20:66ecb2f0e307 827 }
legwinskij 20:66ecb2f0e307 828
legwinskij 20:66ecb2f0e307 829 /* Halt swimfly */
legwinskij 20:66ecb2f0e307 830 case HALT:
legwinskij 20:66ecb2f0e307 831 {
legwinskij 20:66ecb2f0e307 832 wifi.sendAck();
legwinskij 20:66ecb2f0e307 833 leds_off(); // Turn off all leds
legwinskij 20:66ecb2f0e307 834 led_measuring = led_saving = 1; // Turn on two leds to depict special behaviour
legwinskij 20:66ecb2f0e307 835 halt(); // Halt swimfly
legwinskij 20:66ecb2f0e307 836 leds_off(); // Turn off all leds
legwinskij 20:66ecb2f0e307 837 break; // Break
legwinskij 20:66ecb2f0e307 838 }
legwinskij 20:66ecb2f0e307 839
legwinskij 19:c2476c0ea3e0 840 /* Ready */
legwinskij 18:7acae34b518d 841 case CHECK_READY:
legwinskij 19:c2476c0ea3e0 842 {
legwinskij 20:66ecb2f0e307 843 wifi.sendAck();
legwinskij 19:c2476c0ea3e0 844 leds_off(); // Turn off all leds
legwinskij 19:c2476c0ea3e0 845 sendStatus(); // Sends status message
legwinskij 19:c2476c0ea3e0 846 break; // Break
legwinskij 19:c2476c0ea3e0 847 }
legwinskij 19:c2476c0ea3e0 848 /* Nothing on serial */
legwinskij 15:baa2672a9b38 849 case 'N':
legwinskij 15:baa2672a9b38 850 {
legwinskij 15:baa2672a9b38 851 /* Handle data measuring */
legwinskij 15:baa2672a9b38 852 if(measuringFlag) // Wait for timer to set the flag again and again
legwinskij 15:baa2672a9b38 853 {
legwinskij 19:c2476c0ea3e0 854 measure(); // Measure !
legwinskij 15:baa2672a9b38 855 measuringFlag = 0; // Reset flag
legwinskij 15:baa2672a9b38 856 }
legwinskij 15:baa2672a9b38 857 break; // Break from switch
legwinskij 15:baa2672a9b38 858 }
legwinskij 15:baa2672a9b38 859
legwinskij 15:baa2672a9b38 860 /* Everything else is ballast */
legwinskij 15:baa2672a9b38 861 default :
legwinskij 15:baa2672a9b38 862 {
legwinskij 20:66ecb2f0e307 863 wifi.sendNack();
legwinskij 15:baa2672a9b38 864 leds_error(); // Turn on all leds
legwinskij 18:7acae34b518d 865 printf("Command %c is unknown!\r\n", cmd); // Notify user
legwinskij 15:baa2672a9b38 866 break; // Break from switch
legwinskij 15:baa2672a9b38 867 }
jkaderka 0:16fd37cf4a7c 868 }
legwinskij 19:c2476c0ea3e0 869 wdt.kick(); // Kick watchdog each iteration
jkaderka 0:16fd37cf4a7c 870 }
jkaderka 0:16fd37cf4a7c 871 }