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