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
RemovedSources/PCConnector/SWUSBServer.cpp.txt
- Committer:
- hazheng
- Date:
- 2017-04-19
- Branch:
- Drift
- Revision:
- 87:15fcf7891bf9
- Parent:
- PCConnector/SWUSBServer.cpp@ 26:5814404856e2
File content as of revision 87:15fcf7891bf9:
#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; } }