SmartWheels self-driving race car. Designed for NXP Cup. Uses FRDM-KL25Z, area-scan camera, and simple image processing to detect and navigate any NXP spec track.

Dependencies:   TSI USBDevice mbed-dev

Fork of SmartWheels by haofan Zheng

Branch:
Drift
Revision:
87:15fcf7891bf9
Parent:
26:5814404856e2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RemovedSources/PCConnector/SWUSBServer.cpp.txt	Wed Apr 19 04:06:01 2017 +0000
@@ -0,0 +1,256 @@
+#include "SWUSBServer.h"
+
+#define THREAD_SIGNAL_QUEUE 0xa
+#define UNRELIABLE_QUEUE_MAX_SIZE 5
+
+#define RECEIVE_BUF_SIZE 70
+
+#include "USBSerial.h"
+
+
+namespace SW{
+
+USBServer::USBServer(uint16_t vendor_id, uint16_t product_id) : 
+    Serial(USBTX, USBRX),
+    //m_hid(HID_REPORT_LENGTH, HID_REPORT_LENGTH, vendor_id, product_id),
+    m_shouldTerminate(false),
+    m_stat(SER_STAT_STOPPED),
+    m_usbThread(NULL),
+    m_recvBuf(new char[RECEIVE_BUF_SIZE]),
+    m_bufPos(0),
+    m_hasMsgIn(false),
+    m_isReading(false)
+{
+    this->attach(callback(this, &USBServer::RxCallback), RxIrq);
+}
+
+USBServer::~USBServer()
+{
+    Serial::~Serial();
+    Terminate();
+}
+
+void USBServer::Terminate()
+{
+    m_shouldTerminate = true;
+    m_usbThread->signal_set(THREAD_SIGNAL_QUEUE);
+    m_usbThread->signal_set(0xffff);
+    m_usbThread->terminate();
+    this->attach(NULL, RxIrq);
+    delete m_usbThread;
+    delete m_recvBuf;
+}
+
+
+
+void USBServer::Update(float deltaTime)
+{
+    if(!m_shouldTerminate && m_stat == SER_STAT_STOPPED)
+    {
+        if(m_usbThread)
+        {
+            m_usbThread->terminate();
+            delete m_usbThread;
+        }
+        m_usbThread = new Thread(callback(this, &USBServer::ConnectingThread));
+        //m_hidThread.start(callback(this, &USBServer::HIDConnectingThread));
+    }
+    
+    if(!m_shouldTerminate && m_stat == SER_STAT_CONNECTED)
+    {
+        
+        if(m_usbThread)
+        {
+            m_usbThread->terminate();
+            delete m_usbThread;
+        }
+        m_usbThread = new Thread(callback(this, &USBServer::RunningThread));
+        //m_hidThread.start(callback(this, &USBServer::HIDThread));
+    }
+}
+
+bool USBServer::PushReliableMsg(const char type, const std::string & msg)
+{
+    if(msg.length() <= HID_REPORT_LENGTH)
+    {
+        m_qlocker.lock();
+        m_msgQueue.push_back(type + msg);
+        if(m_stat == SER_STAT_RUNNING && m_usbThread)
+            m_usbThread->signal_set(THREAD_SIGNAL_QUEUE);
+        m_qlocker.unlock();
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+    
+bool USBServer::PushUnreliableMsg(const char type, const std::string & msg)
+{
+    if(m_stat != SER_STAT_RUNNING || m_msgQueue.size() >= UNRELIABLE_QUEUE_MAX_SIZE)
+        return false;
+    
+    if(msg.length() <= HID_REPORT_LENGTH)
+    {
+        m_qlocker.lock();
+        m_msgQueue.push_back(type + msg);
+        if(m_stat == SER_STAT_RUNNING && m_usbThread)
+            m_usbThread->signal_set(THREAD_SIGNAL_QUEUE);
+        m_qlocker.unlock();
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+void USBServer::RunningThread()
+{
+    m_stat = SER_STAT_RUNNING;
+    Timer tickTimer;
+    tickTimer.start();
+    while(!m_shouldTerminate)
+    {
+        //m_qlocker.lock(); m_uqlocker.lock();
+        if(m_msgQueue.size() <= 0)
+        {
+            //m_qlocker.unlock(); m_uqlocker.unlock();
+            Thread::signal_wait(THREAD_SIGNAL_QUEUE, 2000);
+        }
+        //m_qlocker.unlock(); m_uqlocker.unlock();
+        std::string msg = "";
+        if(m_msgQueue.size() > 0)
+        {
+            m_qlocker.lock();
+            msg = m_msgQueue.front();
+            m_msgQueue.pop_front();
+            m_qlocker.unlock();
+            
+            uint16_t size = static_cast<uint16_t>(msg.size());
+            this->putc('\x02');
+            this->write(&size, 2);
+            this->write(&(msg[0]), msg.size());
+            this->putc('\x03');
+            //this->printf("\x02%s\x03", msg.c_str());
+        }
+        
+        
+        
+        std::string tempStr;
+        if(m_hasMsgIn)
+        {
+            this->attach(NULL, RxIrq);
+            m_recvBuf[m_bufPos] = '\0';
+            tempStr = m_recvBuf;
+            m_bufPos = 0;
+            m_hasMsgIn = false;
+            this->attach(callback(this, &USBServer::RxCallback), RxIrq);
+            
+            if(tempStr.compare(TICK_MSG_PC) == 0)
+            {
+                //PushReliableMsg('D', "Got Tick!");
+                tickTimer.reset();
+            }
+        }
+        
+        if(tickTimer.read_ms() > 5000)
+        {
+            PushReliableMsg('D', "Time out!!");
+            m_stat = SER_STAT_STOPPED;
+            return;
+        }
+    }
+    
+}
+
+
+void USBServer::RxCallback()
+{
+    char ch = this->_getc();
+    if(m_bufPos >= RECEIVE_BUF_SIZE)
+    {
+        return;
+    }
+    
+    if(m_hasMsgIn)
+    {
+        return;
+    }
+    
+    if(!m_isReading)
+    {
+        //char ch = this->_getc();
+        if(ch == '\x02')
+        {
+            m_isReading = true;
+        }
+    }
+    else
+    {
+        //char ch = this->_getc();
+        if(ch == '\x03')
+        {
+            m_isReading = false;
+            m_hasMsgIn = true;
+        }
+        else
+        {
+            m_recvBuf[m_bufPos++] = ch;
+        }
+    }
+    
+    //fflush(_file);
+}
+    
+void USBServer::ConnectingThread()
+{
+    m_stat = SER_STAT_CONNECTING;
+    
+    while(m_stat != SER_STAT_CONNECTED)
+    {
+        
+        while(!m_hasMsgIn)
+        {
+            std::string strBuf = HANDSHAKE_MSG_TER;
+            uint16_t size = static_cast<uint16_t>(strBuf.size());
+            
+            this->putc('\x02');
+            this->write(&size, 2);
+            this->write(&(strBuf[0]), strBuf.size());
+            this->putc('\x03');
+            
+            //this->printf("\x02%s\x03", HANDSHAKE_MSG_TER);
+            wait(1.0);
+        }
+        
+        std::string tempStr;
+        if(m_hasMsgIn)
+        {
+            this->attach(NULL, RxIrq);
+            m_recvBuf[m_bufPos] = '\0';
+            tempStr = m_recvBuf;
+            m_bufPos = 0;
+            m_hasMsgIn = false;
+            this->attach(callback(this, &USBServer::RxCallback), RxIrq);
+        }
+        
+        if(tempStr.compare(HANDSHAKE_MSG_PC) == 0)
+        {
+            PushReliableMsg('D', "Terminal Connected!");
+            m_stat = SER_STAT_CONNECTED;
+        }
+        
+    }
+    
+    
+}
+
+
+uint8_t USBServer::GetStatus() const
+{
+    return m_stat;
+}
+
+}
\ No newline at end of file