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
Diff: RemovedSources/PCConnector/SWUSBServer.cpp.txt
- 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