posilani dat
Dependencies: FatFileSystemCpp mbed PowerControl USBHostLite
Revision 26:5674b8978551, committed 2017-05-23
- Comitter:
- PavelKumpan
- Date:
- Tue May 23 18:42:14 2017 +0000
- Parent:
- 25:2f964ebcdfd8
- Commit message:
- Recreated communication protocol.
Changed in this revision
--- a/main.cpp Mon Mar 13 15:58:42 2017 +0000 +++ b/main.cpp Tue May 23 18:42:14 2017 +0000 @@ -70,6 +70,9 @@ * - Removed clearRoot() call from init. * - Change representation of the records file to binary. * - Add Prepare command - first send prepare, wait for a file open and then send Start. + * + * CHANGELOG 20/05/2017 + * - Changed communication protocol - each message have header with its size. */ // Includes ==================================================================== @@ -175,7 +178,7 @@ void startSaving(void); void stopSaving(void); void transfer(void); -void sendLog(void); +void sendFile(char* name); void halt(void); void beginScope(void); void sendStatus(void); @@ -273,6 +276,11 @@ short int gyro_y[SIZE]; short int gyro_z[SIZE]; +/* Command buffers */ +char cmd_header[FRAME_HEADER_LEN]; +char cmd_data[256]; +int cmd_len; + // Functions -> File handling ================================================== /* Clear all files in root directory */ @@ -295,9 +303,13 @@ remove(buf); // Remove file that is currently being pointed to } } - + /* If file is not present */ closedir(dir); // Close dir & return false + + FILE *records; + records = fopen(RECORDS_FILE, "w"); // Create new file for records + fclose(records); } /* Append line to log file */ @@ -330,7 +342,7 @@ recordbuffer[i+1] = timestamp[i]; } - fwrite(recordbuffer, 1, 9, records); // Write 32 buffer lines (16 bytes) to file (512 bytes total -> one block) + fwrite(recordbuffer, 1, 9, records); // Write 9 bytes of record fflush(records); fclose(records); // Close file } @@ -339,18 +351,21 @@ void readSwimmerID(void) { size_t fileSize; - + FILE *records; + if(false == doesFileExist(RECORDS_FILE)) { swimmer_id = 0; printf("File with records does not exists, so ID set to 0...\r\n"); + swimmer_id = 0; + printf("New records file created...\r\n"); + records = fopen(RECORDS_FILE, "a"); } else { printf("Reading last swimmer ID from records file...\r\n"); /* Append line to records file */ - FILE *records; records = fopen(RECORDS_FILE, "r"); // Open file with records name fseek(records, 0L, SEEK_END); @@ -366,9 +381,10 @@ fseek(records, -9, SEEK_END); swimmer_id = (uint8_t)fgetc(records) + 1; } - fclose(records); - printf("Actual index is %d...\r\n", swimmer_id); - } + } + + printf("Actual index is %d...\r\n", swimmer_id); + fclose(records); } /* Sees whether giver file exists on flash disk */ @@ -637,13 +653,11 @@ /* Prepares all to acquire data from sensors */ void prepareSaving(void) { - for (int i = 0; i < 8; i++) + for(int i = 0; i < 8; i++) { - timestamp[i] = wifi.readByte(); // Get bytes containing timestamp for the current record + timestamp[i] = cmd_data[i]; } - wifi.sendAck(); - savingFlag = 1; // Set saving flag /* Open global file with current swimmer ID */ gfp = fopen(fname, "wb"); // Try to open that file @@ -723,98 +737,14 @@ char name[30]; // File name buffer /* File transfer prerequisites */ - fclose(gfp); - int requested_id = wifi.readByte(); // Get byte containing requested file ID - sprintf(name, "/usb/swimmer%d.txt", requested_id); // Create file name based on current swimmer ID - - /* Handle transfer */ - if(doesFileExist(name)) // At first check whether file exists (fopen used to freeze mbed) - { - /* Send ACK */ - wifi.sendAck(); - wait_ms(50); // Timeout is used to make sure C# gets ready (sockets are messy, flushing is pain) - /* Actually try to send file */ - printf("Sending %s\r\n", name); // Notify user which user is being sent - if (wifi.sendFile(name)) // Send ! - { - leds_error(); // Handle error - printf("Unable to send data (ID:%d)\r\n", requested_id); // Notify user via text also - } - else - { - printf("Swimmer %d finished\r\n", requested_id); // Otherwise all is AOK - } + printf("closing"); + if (gfp != NULL) { + fclose(gfp); } - else - { - /* In case file doest not exist send NACK */ - wifi.sendByte('#'); - wifi.sendByte('F'); - printf("Requested non-existing file...\r\n"); - } -} - -/* Sends log file*/ -void sendLog(void) -{ - /* Vars */ - char name[30]; // File name buffer - - /* File transfer prerequisites */ - sprintf(name, LOG_FILE); // Create file name from log name - /* Handle transfer */ - if(doesFileExist(name)) // At first check whether file exists (fopen used to freeze mbed) - { - /* Send ACK (should make this more abstract) */ - wifi.sendAck(); - wait_ms(50); // Timeout is used to make sure C# gets ready (sockets are messy, flushing is pain) - /* Actually try to send file */ - printf("Sending %s\r\n", name); // Notify user which user is being sent - if (wifi.sendFile(name)) // Send ! - { - leds_error(); // Handle error - printf("Unable to send log file\r\n"); // Notify user via text also - } - else - { - printf("Log file sent!\r\n"); // Otherwise all is AOK - } - } - else - { - /* In case file doest not exist send NACK */ - wifi.sendByte('#'); - wifi.sendByte('F'); - printf("Requested non-existing file...\r\n"); - } -} - -/* Sends records file*/ -void sendRecords(void) -{ - /* Handle transfer */ - if(doesFileExist(RECORDS_FILE)) // At first check whether file exists (fopen used to freeze mbed) - { - wait_ms(50); // Timeout is used to make sure C# gets ready (sockets are messy, flushing is pain) - /* Actually try to send file */ - printf("Sending %s\r\n", RECORDS_FILE); // Notify user which user is being sent - if (wifi.sendFile(RECORDS_FILE)) // Send ! - { - leds_error(); // Handle error - printf("Unable to send records file\r\n"); // Notify user via text also - } - else - { - printf("Records file sent!\r\n"); // Otherwise all is AOK - } - } - else - { - /* In case file doest not exist send NACK */ - wifi.sendByte('#'); - wifi.sendByte('F'); - printf("Requested non-existing file...\r\n"); - } + printf(" file %d", cmd_data[0]); + sprintf(name, "/usb/swimmer%d.txt", cmd_data[0]); // Create file name based on current swimmer ID + printf(name); + sendFile(name); } /* Halts board */ @@ -844,15 +774,50 @@ // Functions -> Generic functions ============================================== +/* Sends acquired data via Wi-Fi */ +void sendFile(char* name) +{ + /* Handle transfer */ + if(doesFileExist(name)) // At first check whether file exists (fopen used to freeze mbed) + { // Timeout is used to make sure C# gets ready (sockets are messy, flushing is pain) + /* Actually try to send file */ + printf("Sending %s...\r\n", name); // Notify user which user is being sent + if (wifi.sendFile(name) != 0) // Send ! + { + leds_error(); // Handle error + wifi.sendFail(); + printf("Unable to send file.\r\n"); // Notify user via text also + } + else + { + printf("File transfer finished.\r\n"); // Otherwise all is AOK + } + } + else + { + /* In case file doest not exist send NACK */ + wifi.sendNack(); + printf("Requested non-existing file.\r\n"); + } +} + /* Sends status */ void sendStatus(void) { uint8_t checksum = SOH + savingFlag + battLevel + swimmer_id; // Calculate checksum + wifi.sendByte('#'); // # + wifi.sendByte('A'); // A + wifi.sendByte(5); // Send count of the data + wifi.sendByte(0); + wifi.sendByte(0); + wifi.sendByte(0); wifi.sendByte(SOH); // Send start of heading wifi.sendByte(savingFlag); // Send state of saving wifi.sendByte(battLevel); // Sends current battery level wifi.sendByte(swimmer_id); // Sends current swimmer id index wifi.sendByte(checksum); // Send checksum + + wifi.waitForAck(); } void blink(void) @@ -873,19 +838,25 @@ { /* Begin by initialization */ boardInit(); // Initialize board - + /* Set zeroth swimmer name */ sprintf(fname, "/usb/swimmer%d.txt", swimmer_id); // Prepare zeroth swimmer filename - + /* Main while */ while (1) { /* Shutdown handler */ shutdownHandler(); /* Read command from wifly */ - char cmd = wifi.getCmd(); + cmd_len = wifi.getCmd(cmd_header, cmd_data); + + if(cmd_header[1] != 'N') + { + printf(">> #%c and %d bytes\r\n", cmd_header[1], cmd_len); + } + /* Master switch */ - switch (cmd) { + switch (cmd_header[1]) { /* start measuring data periodically and save them info file */ case PREPARE_SAVING: { @@ -910,9 +881,9 @@ /* stop saving data */ case SAVING_STOP: { - wifi.sendAck(); leds_off(); // Turn off all leds stopSaving(); // Actually stop saving + wifi.sendAck(); printf("Stopped...\r\n"); // Notify user break; // Break from switch } @@ -920,7 +891,6 @@ /* Send all data */ case TRANSFER_REQUEST: { - wifi.sendAck(); leds_off(); // Turn off all leds led_sending = 1; // Turn on led_sending printf("Sending data...\r\n"); // Notify user that data is being sent @@ -949,7 +919,7 @@ leds_off(); // Turn off all leds led_measuring = led_saving = 1; // Turn on two leds to depict special behaviour printf("Sending log...\r\n"); // Notify user that new scope is beginning - sendLog(); // Send log file + sendFile(LOG_FILE); // Send log file leds_off(); // Turn off all leds break; // Break } @@ -957,11 +927,10 @@ /* Send records file */ case SEND_RECORDS: { - wifi.sendAck(); leds_off(); // Turn off all leds led_measuring = led_saving = 1; // Turn on two leds to depict special behaviour printf("Sending records...\r\n"); // Notify user that new scope is beginning - sendRecords(); // Send records file + sendFile(RECORDS_FILE); // Send records file leds_off(); // Turn off all leds break; // Break } @@ -980,7 +949,7 @@ /* Ready */ case CHECK_READY: { - wifi.sendAck(); + printf("Sending status...\r\n"); // leds_off(); // Turn off all leds sendStatus(); // Sends status message break; // Break @@ -998,12 +967,24 @@ break; // Break from switch } + /* Fail (should be handled in some inner function */ + case 'F': + { + break; // Break from switch + } + + /* Nothing on serial */ + case 'A': + { + break; // Break from switch + } + /* Everything else is ballast */ default : { wifi.sendNack(); leds_error(); // Turn on all leds - printf("Command %c is unknown!\r\n", cmd); // Notify user + printf("Command %c is unknown!\r\n", cmd_header[1]); // Notify user break; // Break from switch } }
--- a/wifi.cpp Mon Mar 13 15:58:42 2017 +0000 +++ b/wifi.cpp Tue May 23 18:42:14 2017 +0000 @@ -3,7 +3,6 @@ #define BAUDR 460800 //#define BAUDR 1100000 -#define SEND_SIZE 1024 Wifi::Wifi (PinName tx, PinName rx, PinName cts, PinName reset): wifi_(tx, rx) { @@ -26,7 +25,6 @@ * many times (int) count 3*(short) acc 3*(float)gyro * (int) -1 (int) -1 up to 1023 zeros */ -//int Wifi::sendFile(const char *fname, int swimmer_id) int Wifi::sendFile(const char *fname) { char c; @@ -37,6 +35,26 @@ printf("Unable to open %s\r\n", fname); return -1; } + + fseek(file, 0, SEEK_END); // seek to end of file + int size = ftell(file); // get current file pointer + fseek(file, 0, SEEK_SET); // seek back to beginning of file + + wifi_.putc('#'); // send ACK + wifi_.putc('A'); + for(int i = 0; i < FRAME_HEADER_LEN - 2; i++) // send num of bytes in the message + { + wifi_.putc((char)((size >> (i * 8)) & 0xFF)); + } + + printf("Ack sended...\r\n"); + printf("Transfer of %d bytes initialized...\r\n", size); + + if(size == 0) // when nothing to send, terminated here + { + return 0; + } + in_buf = 0; while (fread(&c, sizeof(char), 1, file) != 0) { if ((last = bufferSendVerify(c)) == -1) { @@ -44,57 +62,65 @@ return -1; } } - - //fill the last data to SEND_SIZE with zeros - if (last == 1) { - while (bufferSendVerify(0x00) != 0) - ; + fclose(file); + + if (bufferFlush() == -1) { + return -1; } - fclose(file); return 0; } /* - * Returns 'N' if no command was recieved - * or the command + * Returns length of command data received, load the command into the cmd array and the data into the data array. */ -char Wifi::getCmd(void) +int Wifi::getCmd(char* cmd, char* data) { + short dataLength = 0u; + cmd[0] = '#'; + cmd[1] = 'N'; + + /* Read the command */ if (wifi_.readable() && wifi_.getc() == '#') { + for(int i = 1; i < FRAME_HEADER_LEN; i++) + { + wait_ms(20); + if (wifi_.readable()) + { + cmd[i] = wifi_.getc(); + } + else + { + cmd[1] = 'N'; + } + } + } + + /* Read count of data */ + if(cmd[1] == 'N') + { + return 0; + } + + for(int i = 0; i < FRAME_HEADER_LEN - 2; i++) + { + dataLength += (int)cmd[i+2] << (i * 8); + } + + /* Read data */ + for(int i = 0; i < dataLength; i++) + { wait_ms(20); if (wifi_.readable()) { - return wifi_.getc(); + data[i] = wifi_.getc(); } - else - { - return 'N'; - } } - else - { - return 'N'; - } + + return dataLength; } -//char Wifi::getCmd(void) -//{ -// // Needs to be done properly -// //if (wifi_.readable() || wifi_.getc() == '#'); -// if (wifi_.readable() && wifi_.getc() == '#') -// { -// wifi_.putc('#'); -// wifi_.putc('A'); -// return wifi_.getc(); -// } -// else -// { -// return 'N'; -// } -//d} - /* * Sends given byte to wifly */ @@ -135,6 +161,10 @@ { wifi_.putc('#'); wifi_.putc('A'); + for(int i = 0; i < FRAME_HEADER_LEN - 2; i++) + { + wifi_.putc(0x0); + } } /* @@ -144,12 +174,58 @@ { wifi_.putc('#'); wifi_.putc('N'); + for(int i = 0; i < FRAME_HEADER_LEN - 2; i++) + { + wifi_.putc(0x0); + } +} + +/* + * Sends NACK to wiflys UART + */ +void Wifi::sendFail(void) +{ + wifi_.putc('#'); + wifi_.putc('F'); + for(int i = 0; i < FRAME_HEADER_LEN - 2; i++) + { + wifi_.putc(0x0); + } +} + +int Wifi::waitForAck() +{ + char cmd[FRAME_HEADER_LEN]; + char data[256]; + + for (int i=0; i<64; i++) + { + getCmd(cmd, data); + + if ('A' == cmd[1]) + { + return 1; + } + else if ('F' == cmd[1]) + { + return 0; + } + else + { + wait_ms(5); + } + } + return -1; + + //if (wifi_.getc() == 'A') + // break; } /* ******************************** * private * *******************************/ -void Wifi::bufferSend(char *buffer, size_t size) + +void Wifi::bufferSend(size_t size) { int i; for (i = 0; i < size; i++) { @@ -157,50 +233,91 @@ } } +int Wifi::bufferFlush() +{ + LPC_WDT->WDFEED = 0xAA; + LPC_WDT->WDFEED = 0x55; + int counter = 0; + int result = 0; + + if (in_buf == 0) + { + return 1; + } + + while (counter++ < 10) + { + bufferSend(in_buf); + result = waitForAck(); + + if(result == 1) + { + /* Ack - break, no need to send it again */ + break; + } + else if (result == -1) + { + /* Fail - transmition faild, terminate sending */ + return -1; + } + else + { + /* Nack - send it again*/ + } + } + + if (counter >= 10) + { + return -1; + } + else + { + return 0; + } +} + int Wifi::bufferSendVerify(char c) { LPC_WDT->WDFEED = 0xAA; LPC_WDT->WDFEED = 0x55; - static char buffer[SEND_SIZE]; int counter = 0; - + int result = 0; buffer[in_buf] = c; in_buf++; if (in_buf != SEND_SIZE) + { return 1; + } in_buf = 0; - while (counter++ < 10) { - bufferSend(buffer, SEND_SIZE); - //while (!wifi_.readable()); - for (int i=0; i<50; i++) + while (counter++ < 16) + { + bufferSend(SEND_SIZE); + result = waitForAck(); + + if(result == 1) + { + /* Ack - break, no need to send it again */ + break; + } + else if (result == -1) { - if (wifi_.readable()) - { - char buf = wifi_.getc(); - if ('A' == buf) - { - return 0; - } - else if ('F' == buf) - { - break; - } - else - { - return -1; - } - } - else - { - wait_ms(5); - } + /* Fail - transmition faild, terminate sending */ + return -1; + } + else + { + /* Nack - send it again*/ } - //if (wifi_.getc() == 'A') - // break; } + if (counter >= 10) + { return -1; - return 0; + } + else + { + return 0; + } } \ No newline at end of file
--- a/wifi.h Mon Mar 13 15:58:42 2017 +0000 +++ b/wifi.h Tue May 23 18:42:14 2017 +0000 @@ -9,6 +9,8 @@ #include "mbed.h" //#include "WiflyInterface.h" +#define FRAME_HEADER_LEN 6 +#define SEND_SIZE 1024 class Wifi { public: @@ -20,7 +22,7 @@ /* * Returns received command (without #), just the one char */ - char getCmd(void); + int getCmd(char* cmd_header, char* cmd_data); /* * Sends one char to wifly @@ -42,12 +44,16 @@ bool readable(void); void sendAck(void); void sendNack(void); + void sendFail(void); + int waitForAck(void); private: Serial wifi_; int in_buf; - void bufferSend(char *buffer, size_t size); - int bufferSendVerify(char buffer); + char buffer[SEND_SIZE]; + void bufferSend(size_t size); + int bufferSendVerify(char byte); + int bufferFlush(void); }; #endif \ No newline at end of file