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

PCConnector/SWUSBServer.cpp

Committer:
Bobymicjohn
Date:
2017-02-07
Revision:
11:676ea42afd56
Child:
13:7dcb1642ef99

File content as of revision 11:676ea42afd56:

#include "SWUSBServer.h"

#define THREAD_SIGNAL_QUEUE 0xa
#define UNRELIABLE_QUEUE_MAX_SIZE 5

#include "USBSerial.h"

namespace SW{

USBServer::USBServer(uint16_t vendor_id, uint16_t product_id) : 
    //m_hid(HID_REPORT_LENGTH, HID_REPORT_LENGTH, vendor_id, product_id),
    m_shouldTerminate(false),
    m_stat(HID_SER_STAT_STOPPED),
    m_usbThread(NULL),
    m_usb(NULL)
{
    
}

USBServer::~USBServer()
{
    Terminate();
}

void USBServer::Terminate()
{
    m_shouldTerminate = true;
    m_usbThread->signal_set(THREAD_SIGNAL_QUEUE);
    m_usbThread->signal_set(0xffff);
    //m_usbThread->join();
    m_usbThread->terminate();
    delete m_usbThread;
    delete m_usb;
}

void USBServer::Update(float deltaTime)
{
    
    if(!m_shouldTerminate && m_stat == HID_SER_STAT_STOPPED)
    {
        if(m_usbThread)
        {
            delete m_usbThread;
        }
        m_usbThread = new Thread(callback(this, &USBServer::ConnectingThread));
        //m_hidThread.start(callback(this, &USBServer::HIDConnectingThread));
    }
    
    if(!m_shouldTerminate && m_stat == HID_SER_STAT_CONNECTED)
    {
        if(m_usbThread)
        {
            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 == HID_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 != HID_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 == HID_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 = HID_SER_STAT_RUNNING;
    
    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);
        }
        //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();
        }
        
        m_usb->printf("%s\n", msg.c_str());
    }
}
    
void USBServer::ConnectingThread()
{
    m_stat = HID_SER_STAT_CONNECTING;
    
    m_usb = new Serial(USBTX, USBRX, "SmartWheels");
    
    m_usb->printf("%s\n", HANDSHAKE_MSG_TER);
    
    m_stat = HID_SER_STAT_CONNECTED;
    
}

}