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

Revision:
1:3b567aa3b09e
Child:
2:5bc47e544b8d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tcp_task.cpp	Sun Feb 02 10:49:19 2014 +0000
@@ -0,0 +1,251 @@
+#include "tcp_task.h"
+
+TCPSocketConnection connect;
+Queue<char, QUEUE_MAX_LEN> tcp_queue;
+TCPSocketServer sock;
+char tcp_buf[256];
+char data_frame[DATA_MAX_LEN];
+char ack[ACK_MAX_LEN];
+char fname[NAME_MAX_LEN];
+const char ack_wdata[4] = {ACK_1, ACK_2, ACK_MBED, ACK_WDATA};
+osEvent evt;
+extern volatile int cmd_en;
+extern volatile int play_en;
+
+void tcp_thread(void const *args)
+{
+    int n;
+    
+    sock.bind(TCP_PORT);
+    sock.listen();
+    while (1)
+    {
+        sock.accept(connect);
+        printf("New connection\n");
+        // Handle incoming connection
+        while (connect.is_connected())
+        {
+            n = connect.receive(tcp_buf, 256);
+            if (n < 0) // Error or disconnected
+            {
+                printf("Connection error\n");
+                break;
+            }
+            if (cmd_en)
+            {
+                for (int i = 0; i < n; i++)
+                {
+                    tcp_queue.put(&tcp_buf[i]);
+                }
+            }
+        }
+        connect.close();
+        play_en = 1;
+    }
+}
+
+void cmd_thread(void const *args)
+{
+    char *c;
+    int cmd_state;
+    char d;
+    int i = 0;
+    int idx = 0;
+    char last_frame = 0;
+    
+    int data_len = 0;
+    int cnt = 0;
+    int fname_len = 0;
+    FILE *fp = NULL;
+    usb *u = (usb *)args;
+    
+    cmd_state = STATE_IDLE;
+    
+    while (1)
+    {
+        if (cmd_en && connect.is_connected())
+        {
+            while (connect.is_connected())
+            {
+                evt = tcp_queue.get();
+                if (evt.status == osEventMessage)
+                {
+                    c = (char *)evt.value.p;
+                    d = *c;
+                    switch (cmd_state)
+                    {
+                        case STATE_IDLE:
+                            if (d == CMD_1)
+                            {
+                                cmd_state = STATE_1;
+                            }
+                        break;
+                        
+                        case STATE_1:
+                            if (d == CMD_2)
+                            {
+                                cmd_state = STATE_2;
+                            }
+                            else
+                            {
+                                cmd_state = STATE_IDLE;
+                            }
+                        break;
+                        
+                        case STATE_2:
+                            if (d == CMD_PC)
+                            {
+                                cmd_state = STATE_CMD;
+                            }
+                            else
+                            {
+                                cmd_state = STATE_IDLE;
+                            }
+                        break;
+                        
+                        case STATE_CMD:
+                            if (d == CMD_READ)
+                            {
+                                play_en = 0;
+                                // Read filenames
+                                u->listdir("/");
+                                ack[0] = ACK_1;
+                                ack[1] = ACK_2;
+                                ack[2] = ACK_MBED;
+                                ack[3] = ACK_READ;
+                                ack[4] = (char)(u->filenames.size());
+                                cnt = 5;
+                                for(vector<string>::iterator it = u->filenames.begin(); it < u->filenames.end(); it++)
+                                {
+                                    //printf("%s\n", it->c_str());
+                                    for (i = 0; i < it->length(); i++)
+                                    {
+                                        ack[cnt] = (*it)[i];
+                                        cnt++;
+                                        if (cnt == ACK_MAX_LEN)
+                                        {
+                                            // Send
+                                            connect.send_all(ack, cnt);
+                                            // Reset counter
+                                            cnt = 0;
+                                        }
+                                    }
+                                    ack[cnt] = SPR_CHAR;
+                                    cnt++;
+                                    if (cnt == ACK_MAX_LEN)
+                                    {
+                                        // Send
+                                        connect.send_all(ack, cnt);
+                                        // Reset counter
+                                        cnt = 0;
+                                    }
+                                }
+                                connect.send_all(ack, cnt);
+                                cmd_state = STATE_IDLE;
+                                play_en = 1;
+                            }
+                            else if (d == CMD_WFILE)
+                            {
+                                cmd_state = STATE_WFILE;
+                                i = 0;
+                                play_en = 0;
+                            }
+                            else if (d == CMD_WDATA)
+                            {
+                                cmd_state = STATE_WDATA;
+                                idx = 0;
+                            }
+                            else
+                            {
+                                cmd_state = STATE_IDLE;
+                            }
+                        break;
+                        
+                        case STATE_WFILE:
+                            if (i == 0)
+                            {
+                                // Length of the filename
+                                fname_len = d;
+                                i++;
+                                fname[0] = '/';
+                                fname[1] = 'u';
+                                fname[2] = 's';
+                                fname[3] = 'b';
+                                fname[4] = '/';
+                            }
+                            else
+                            {
+                                if (i <= fname_len)
+                                {
+                                    fname[i + 4] = d;
+                                }
+                                if (i == fname_len)
+                                {
+                                    // Create a file named fname
+                                    fp = fopen(fname, "wb");
+                                    //fprintf(fp, "Hello World!");
+                                    // Send ACK to PC
+                                    ack[0] = ACK_1;
+                                    ack[1] = ACK_2;
+                                    ack[2] = ACK_MBED;
+                                    ack[3] = ACK_WFILE;
+                                    // Send
+                                    connect.send_all(ack, 4);
+                                    cmd_state = STATE_IDLE;
+                                }
+                                else
+                                {
+                                    i++;
+                                }
+                            }
+                        break;
+                        
+                        case STATE_WDATA:
+                            if (idx == 0)
+                            {
+                                // Is last frame?
+                                last_frame = d;
+                                data_len = 0;
+                            }
+                            else if (idx == 1)
+                            {
+                                data_len = d * 256;
+                            }
+                            else if (idx == 2)
+                            {
+                                data_len = data_len + d;
+                                cnt = 0;
+                            }
+                            else
+                            {
+                                data_frame[cnt] = d;
+                                cnt++;
+                                if (cnt == data_len)
+                                {
+                                    fwrite(data_frame, sizeof(char), data_len, fp);
+                                    connect.send_all((char*)ack_wdata, 4);
+                                    if (last_frame)
+                                    {
+                                        fclose(fp);
+                                        play_en = 1;
+                                    }
+                                    cmd_state = STATE_IDLE;
+                                }
+                            }
+                            idx++;
+                        break;
+                        
+                        default:
+                            cmd_state = STATE_IDLE;
+                        break;
+                    }
+                }
+            }
+        }
+        else
+        {
+            cmd_state = STATE_IDLE;
+            Thread::wait(5);
+        }
+    }
+}