Advanced Operating Systems - Final Project A @ Tokyo Tech ////////////// Author: Chu Van Thiem and Sidik Soleman ////////////// A WAVE file player on the MBED Application Board with an interface to a software on PC via a TCP connection. ////////////// Main functions: 1. Browse files of an attached USB flash 2. The list of the files of the attached USB are displayed on the LCD 3. Use an joystick to select a WAVE file and give an instruction to play that file 4. Adjust the volume using a potentiometer 5. Output audio to the analog audio out jack ////////////// Software (https://github.com/thiemcv/VS/tree/master/Terminal): 1. Connect with the MBED application board via Ethernet connection 2. Read the list of files stored on the USB flash 3. Write files to the USB flash
Dependencies: C12832_lcd EthernetInterface USBHost mbed-rtos mbed wave_player
src/tcp_task.cpp@1:3b567aa3b09e, 2014-02-02 (annotated)
- Committer:
- aos
- Date:
- Sun Feb 02 10:49:19 2014 +0000
- Revision:
- 1:3b567aa3b09e
- Child:
- 2:5bc47e544b8d
Final Project V1: Integrated WAV player + USB file management via ethernet connection
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
aos | 1:3b567aa3b09e | 1 | #include "tcp_task.h" |
aos | 1:3b567aa3b09e | 2 | |
aos | 1:3b567aa3b09e | 3 | TCPSocketConnection connect; |
aos | 1:3b567aa3b09e | 4 | Queue<char, QUEUE_MAX_LEN> tcp_queue; |
aos | 1:3b567aa3b09e | 5 | TCPSocketServer sock; |
aos | 1:3b567aa3b09e | 6 | char tcp_buf[256]; |
aos | 1:3b567aa3b09e | 7 | char data_frame[DATA_MAX_LEN]; |
aos | 1:3b567aa3b09e | 8 | char ack[ACK_MAX_LEN]; |
aos | 1:3b567aa3b09e | 9 | char fname[NAME_MAX_LEN]; |
aos | 1:3b567aa3b09e | 10 | const char ack_wdata[4] = {ACK_1, ACK_2, ACK_MBED, ACK_WDATA}; |
aos | 1:3b567aa3b09e | 11 | osEvent evt; |
aos | 1:3b567aa3b09e | 12 | extern volatile int cmd_en; |
aos | 1:3b567aa3b09e | 13 | extern volatile int play_en; |
aos | 1:3b567aa3b09e | 14 | |
aos | 1:3b567aa3b09e | 15 | void tcp_thread(void const *args) |
aos | 1:3b567aa3b09e | 16 | { |
aos | 1:3b567aa3b09e | 17 | int n; |
aos | 1:3b567aa3b09e | 18 | |
aos | 1:3b567aa3b09e | 19 | sock.bind(TCP_PORT); |
aos | 1:3b567aa3b09e | 20 | sock.listen(); |
aos | 1:3b567aa3b09e | 21 | while (1) |
aos | 1:3b567aa3b09e | 22 | { |
aos | 1:3b567aa3b09e | 23 | sock.accept(connect); |
aos | 1:3b567aa3b09e | 24 | printf("New connection\n"); |
aos | 1:3b567aa3b09e | 25 | // Handle incoming connection |
aos | 1:3b567aa3b09e | 26 | while (connect.is_connected()) |
aos | 1:3b567aa3b09e | 27 | { |
aos | 1:3b567aa3b09e | 28 | n = connect.receive(tcp_buf, 256); |
aos | 1:3b567aa3b09e | 29 | if (n < 0) // Error or disconnected |
aos | 1:3b567aa3b09e | 30 | { |
aos | 1:3b567aa3b09e | 31 | printf("Connection error\n"); |
aos | 1:3b567aa3b09e | 32 | break; |
aos | 1:3b567aa3b09e | 33 | } |
aos | 1:3b567aa3b09e | 34 | if (cmd_en) |
aos | 1:3b567aa3b09e | 35 | { |
aos | 1:3b567aa3b09e | 36 | for (int i = 0; i < n; i++) |
aos | 1:3b567aa3b09e | 37 | { |
aos | 1:3b567aa3b09e | 38 | tcp_queue.put(&tcp_buf[i]); |
aos | 1:3b567aa3b09e | 39 | } |
aos | 1:3b567aa3b09e | 40 | } |
aos | 1:3b567aa3b09e | 41 | } |
aos | 1:3b567aa3b09e | 42 | connect.close(); |
aos | 1:3b567aa3b09e | 43 | play_en = 1; |
aos | 1:3b567aa3b09e | 44 | } |
aos | 1:3b567aa3b09e | 45 | } |
aos | 1:3b567aa3b09e | 46 | |
aos | 1:3b567aa3b09e | 47 | void cmd_thread(void const *args) |
aos | 1:3b567aa3b09e | 48 | { |
aos | 1:3b567aa3b09e | 49 | char *c; |
aos | 1:3b567aa3b09e | 50 | int cmd_state; |
aos | 1:3b567aa3b09e | 51 | char d; |
aos | 1:3b567aa3b09e | 52 | int i = 0; |
aos | 1:3b567aa3b09e | 53 | int idx = 0; |
aos | 1:3b567aa3b09e | 54 | char last_frame = 0; |
aos | 1:3b567aa3b09e | 55 | |
aos | 1:3b567aa3b09e | 56 | int data_len = 0; |
aos | 1:3b567aa3b09e | 57 | int cnt = 0; |
aos | 1:3b567aa3b09e | 58 | int fname_len = 0; |
aos | 1:3b567aa3b09e | 59 | FILE *fp = NULL; |
aos | 1:3b567aa3b09e | 60 | usb *u = (usb *)args; |
aos | 1:3b567aa3b09e | 61 | |
aos | 1:3b567aa3b09e | 62 | cmd_state = STATE_IDLE; |
aos | 1:3b567aa3b09e | 63 | |
aos | 1:3b567aa3b09e | 64 | while (1) |
aos | 1:3b567aa3b09e | 65 | { |
aos | 1:3b567aa3b09e | 66 | if (cmd_en && connect.is_connected()) |
aos | 1:3b567aa3b09e | 67 | { |
aos | 1:3b567aa3b09e | 68 | while (connect.is_connected()) |
aos | 1:3b567aa3b09e | 69 | { |
aos | 1:3b567aa3b09e | 70 | evt = tcp_queue.get(); |
aos | 1:3b567aa3b09e | 71 | if (evt.status == osEventMessage) |
aos | 1:3b567aa3b09e | 72 | { |
aos | 1:3b567aa3b09e | 73 | c = (char *)evt.value.p; |
aos | 1:3b567aa3b09e | 74 | d = *c; |
aos | 1:3b567aa3b09e | 75 | switch (cmd_state) |
aos | 1:3b567aa3b09e | 76 | { |
aos | 1:3b567aa3b09e | 77 | case STATE_IDLE: |
aos | 1:3b567aa3b09e | 78 | if (d == CMD_1) |
aos | 1:3b567aa3b09e | 79 | { |
aos | 1:3b567aa3b09e | 80 | cmd_state = STATE_1; |
aos | 1:3b567aa3b09e | 81 | } |
aos | 1:3b567aa3b09e | 82 | break; |
aos | 1:3b567aa3b09e | 83 | |
aos | 1:3b567aa3b09e | 84 | case STATE_1: |
aos | 1:3b567aa3b09e | 85 | if (d == CMD_2) |
aos | 1:3b567aa3b09e | 86 | { |
aos | 1:3b567aa3b09e | 87 | cmd_state = STATE_2; |
aos | 1:3b567aa3b09e | 88 | } |
aos | 1:3b567aa3b09e | 89 | else |
aos | 1:3b567aa3b09e | 90 | { |
aos | 1:3b567aa3b09e | 91 | cmd_state = STATE_IDLE; |
aos | 1:3b567aa3b09e | 92 | } |
aos | 1:3b567aa3b09e | 93 | break; |
aos | 1:3b567aa3b09e | 94 | |
aos | 1:3b567aa3b09e | 95 | case STATE_2: |
aos | 1:3b567aa3b09e | 96 | if (d == CMD_PC) |
aos | 1:3b567aa3b09e | 97 | { |
aos | 1:3b567aa3b09e | 98 | cmd_state = STATE_CMD; |
aos | 1:3b567aa3b09e | 99 | } |
aos | 1:3b567aa3b09e | 100 | else |
aos | 1:3b567aa3b09e | 101 | { |
aos | 1:3b567aa3b09e | 102 | cmd_state = STATE_IDLE; |
aos | 1:3b567aa3b09e | 103 | } |
aos | 1:3b567aa3b09e | 104 | break; |
aos | 1:3b567aa3b09e | 105 | |
aos | 1:3b567aa3b09e | 106 | case STATE_CMD: |
aos | 1:3b567aa3b09e | 107 | if (d == CMD_READ) |
aos | 1:3b567aa3b09e | 108 | { |
aos | 1:3b567aa3b09e | 109 | play_en = 0; |
aos | 1:3b567aa3b09e | 110 | // Read filenames |
aos | 1:3b567aa3b09e | 111 | u->listdir("/"); |
aos | 1:3b567aa3b09e | 112 | ack[0] = ACK_1; |
aos | 1:3b567aa3b09e | 113 | ack[1] = ACK_2; |
aos | 1:3b567aa3b09e | 114 | ack[2] = ACK_MBED; |
aos | 1:3b567aa3b09e | 115 | ack[3] = ACK_READ; |
aos | 1:3b567aa3b09e | 116 | ack[4] = (char)(u->filenames.size()); |
aos | 1:3b567aa3b09e | 117 | cnt = 5; |
aos | 1:3b567aa3b09e | 118 | for(vector<string>::iterator it = u->filenames.begin(); it < u->filenames.end(); it++) |
aos | 1:3b567aa3b09e | 119 | { |
aos | 1:3b567aa3b09e | 120 | //printf("%s\n", it->c_str()); |
aos | 1:3b567aa3b09e | 121 | for (i = 0; i < it->length(); i++) |
aos | 1:3b567aa3b09e | 122 | { |
aos | 1:3b567aa3b09e | 123 | ack[cnt] = (*it)[i]; |
aos | 1:3b567aa3b09e | 124 | cnt++; |
aos | 1:3b567aa3b09e | 125 | if (cnt == ACK_MAX_LEN) |
aos | 1:3b567aa3b09e | 126 | { |
aos | 1:3b567aa3b09e | 127 | // Send |
aos | 1:3b567aa3b09e | 128 | connect.send_all(ack, cnt); |
aos | 1:3b567aa3b09e | 129 | // Reset counter |
aos | 1:3b567aa3b09e | 130 | cnt = 0; |
aos | 1:3b567aa3b09e | 131 | } |
aos | 1:3b567aa3b09e | 132 | } |
aos | 1:3b567aa3b09e | 133 | ack[cnt] = SPR_CHAR; |
aos | 1:3b567aa3b09e | 134 | cnt++; |
aos | 1:3b567aa3b09e | 135 | if (cnt == ACK_MAX_LEN) |
aos | 1:3b567aa3b09e | 136 | { |
aos | 1:3b567aa3b09e | 137 | // Send |
aos | 1:3b567aa3b09e | 138 | connect.send_all(ack, cnt); |
aos | 1:3b567aa3b09e | 139 | // Reset counter |
aos | 1:3b567aa3b09e | 140 | cnt = 0; |
aos | 1:3b567aa3b09e | 141 | } |
aos | 1:3b567aa3b09e | 142 | } |
aos | 1:3b567aa3b09e | 143 | connect.send_all(ack, cnt); |
aos | 1:3b567aa3b09e | 144 | cmd_state = STATE_IDLE; |
aos | 1:3b567aa3b09e | 145 | play_en = 1; |
aos | 1:3b567aa3b09e | 146 | } |
aos | 1:3b567aa3b09e | 147 | else if (d == CMD_WFILE) |
aos | 1:3b567aa3b09e | 148 | { |
aos | 1:3b567aa3b09e | 149 | cmd_state = STATE_WFILE; |
aos | 1:3b567aa3b09e | 150 | i = 0; |
aos | 1:3b567aa3b09e | 151 | play_en = 0; |
aos | 1:3b567aa3b09e | 152 | } |
aos | 1:3b567aa3b09e | 153 | else if (d == CMD_WDATA) |
aos | 1:3b567aa3b09e | 154 | { |
aos | 1:3b567aa3b09e | 155 | cmd_state = STATE_WDATA; |
aos | 1:3b567aa3b09e | 156 | idx = 0; |
aos | 1:3b567aa3b09e | 157 | } |
aos | 1:3b567aa3b09e | 158 | else |
aos | 1:3b567aa3b09e | 159 | { |
aos | 1:3b567aa3b09e | 160 | cmd_state = STATE_IDLE; |
aos | 1:3b567aa3b09e | 161 | } |
aos | 1:3b567aa3b09e | 162 | break; |
aos | 1:3b567aa3b09e | 163 | |
aos | 1:3b567aa3b09e | 164 | case STATE_WFILE: |
aos | 1:3b567aa3b09e | 165 | if (i == 0) |
aos | 1:3b567aa3b09e | 166 | { |
aos | 1:3b567aa3b09e | 167 | // Length of the filename |
aos | 1:3b567aa3b09e | 168 | fname_len = d; |
aos | 1:3b567aa3b09e | 169 | i++; |
aos | 1:3b567aa3b09e | 170 | fname[0] = '/'; |
aos | 1:3b567aa3b09e | 171 | fname[1] = 'u'; |
aos | 1:3b567aa3b09e | 172 | fname[2] = 's'; |
aos | 1:3b567aa3b09e | 173 | fname[3] = 'b'; |
aos | 1:3b567aa3b09e | 174 | fname[4] = '/'; |
aos | 1:3b567aa3b09e | 175 | } |
aos | 1:3b567aa3b09e | 176 | else |
aos | 1:3b567aa3b09e | 177 | { |
aos | 1:3b567aa3b09e | 178 | if (i <= fname_len) |
aos | 1:3b567aa3b09e | 179 | { |
aos | 1:3b567aa3b09e | 180 | fname[i + 4] = d; |
aos | 1:3b567aa3b09e | 181 | } |
aos | 1:3b567aa3b09e | 182 | if (i == fname_len) |
aos | 1:3b567aa3b09e | 183 | { |
aos | 1:3b567aa3b09e | 184 | // Create a file named fname |
aos | 1:3b567aa3b09e | 185 | fp = fopen(fname, "wb"); |
aos | 1:3b567aa3b09e | 186 | //fprintf(fp, "Hello World!"); |
aos | 1:3b567aa3b09e | 187 | // Send ACK to PC |
aos | 1:3b567aa3b09e | 188 | ack[0] = ACK_1; |
aos | 1:3b567aa3b09e | 189 | ack[1] = ACK_2; |
aos | 1:3b567aa3b09e | 190 | ack[2] = ACK_MBED; |
aos | 1:3b567aa3b09e | 191 | ack[3] = ACK_WFILE; |
aos | 1:3b567aa3b09e | 192 | // Send |
aos | 1:3b567aa3b09e | 193 | connect.send_all(ack, 4); |
aos | 1:3b567aa3b09e | 194 | cmd_state = STATE_IDLE; |
aos | 1:3b567aa3b09e | 195 | } |
aos | 1:3b567aa3b09e | 196 | else |
aos | 1:3b567aa3b09e | 197 | { |
aos | 1:3b567aa3b09e | 198 | i++; |
aos | 1:3b567aa3b09e | 199 | } |
aos | 1:3b567aa3b09e | 200 | } |
aos | 1:3b567aa3b09e | 201 | break; |
aos | 1:3b567aa3b09e | 202 | |
aos | 1:3b567aa3b09e | 203 | case STATE_WDATA: |
aos | 1:3b567aa3b09e | 204 | if (idx == 0) |
aos | 1:3b567aa3b09e | 205 | { |
aos | 1:3b567aa3b09e | 206 | // Is last frame? |
aos | 1:3b567aa3b09e | 207 | last_frame = d; |
aos | 1:3b567aa3b09e | 208 | data_len = 0; |
aos | 1:3b567aa3b09e | 209 | } |
aos | 1:3b567aa3b09e | 210 | else if (idx == 1) |
aos | 1:3b567aa3b09e | 211 | { |
aos | 1:3b567aa3b09e | 212 | data_len = d * 256; |
aos | 1:3b567aa3b09e | 213 | } |
aos | 1:3b567aa3b09e | 214 | else if (idx == 2) |
aos | 1:3b567aa3b09e | 215 | { |
aos | 1:3b567aa3b09e | 216 | data_len = data_len + d; |
aos | 1:3b567aa3b09e | 217 | cnt = 0; |
aos | 1:3b567aa3b09e | 218 | } |
aos | 1:3b567aa3b09e | 219 | else |
aos | 1:3b567aa3b09e | 220 | { |
aos | 1:3b567aa3b09e | 221 | data_frame[cnt] = d; |
aos | 1:3b567aa3b09e | 222 | cnt++; |
aos | 1:3b567aa3b09e | 223 | if (cnt == data_len) |
aos | 1:3b567aa3b09e | 224 | { |
aos | 1:3b567aa3b09e | 225 | fwrite(data_frame, sizeof(char), data_len, fp); |
aos | 1:3b567aa3b09e | 226 | connect.send_all((char*)ack_wdata, 4); |
aos | 1:3b567aa3b09e | 227 | if (last_frame) |
aos | 1:3b567aa3b09e | 228 | { |
aos | 1:3b567aa3b09e | 229 | fclose(fp); |
aos | 1:3b567aa3b09e | 230 | play_en = 1; |
aos | 1:3b567aa3b09e | 231 | } |
aos | 1:3b567aa3b09e | 232 | cmd_state = STATE_IDLE; |
aos | 1:3b567aa3b09e | 233 | } |
aos | 1:3b567aa3b09e | 234 | } |
aos | 1:3b567aa3b09e | 235 | idx++; |
aos | 1:3b567aa3b09e | 236 | break; |
aos | 1:3b567aa3b09e | 237 | |
aos | 1:3b567aa3b09e | 238 | default: |
aos | 1:3b567aa3b09e | 239 | cmd_state = STATE_IDLE; |
aos | 1:3b567aa3b09e | 240 | break; |
aos | 1:3b567aa3b09e | 241 | } |
aos | 1:3b567aa3b09e | 242 | } |
aos | 1:3b567aa3b09e | 243 | } |
aos | 1:3b567aa3b09e | 244 | } |
aos | 1:3b567aa3b09e | 245 | else |
aos | 1:3b567aa3b09e | 246 | { |
aos | 1:3b567aa3b09e | 247 | cmd_state = STATE_IDLE; |
aos | 1:3b567aa3b09e | 248 | Thread::wait(5); |
aos | 1:3b567aa3b09e | 249 | } |
aos | 1:3b567aa3b09e | 250 | } |
aos | 1:3b567aa3b09e | 251 | } |