Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
mbed_usbserial.cpp
Go to the documentation of this file.
1
35#include <algorithm>
36
37#include "mbed.h"
38#include "USBSerial.h"
39#include "Serial.hxx"
40#include "os/os.h"
41#include "utils/macros.h"
42#include "portmacro.h"
43
44#ifdef TARGET_LPC2368
45#endif
46
48#define TX_DATA_SIZE 64
50#define RX_DATA_SIZE 64
51
52#include <stdlib.h>
53
55void* operator new(size_t size);
57void* operator new[](size_t size);
59void operator delete(void* ptr);
61void operator delete[](void* ptr);
62
64__extension__ typedef int __guard __attribute__((mode(__DI__)));
65
67extern "C" int __cxa_guard_acquire(__guard*);
69extern "C" void __cxa_guard_release(__guard*);
71extern "C" void __cxa_guard_abort(__guard*);
73extern "C" void __cxa_pure_virtual(void);
74
85class MbedRawUSBSerial : public USBCDC, public ::Serial
86{
87public:
93 MbedRawUSBSerial(const char* name, uint16_t vendor_id = 0x1f00,
94 uint16_t product_id = 0x2012,
95 uint16_t product_release = 0x0001)
96 : USBCDC(vendor_id, product_id, product_release),
97 Serial(name),
98 txPending(false)
99 {
100 os_sem_init(&rxSem, 0);
101 os_thread_t thread;
102 os_thread_create(&thread, "usbserial.rx", 3, 1024, &_RxThread, this);
103 }
104
106 {
108 }
109
110protected:
112 bool EP2_OUT_callback() override
113 {
114 //HASSERT(IsEpPending());
115 // and wake up the RX thread.
116 int woken;
117 os_sem_post_from_isr(&rxSem, &woken);
118 return false;
119 }
120
122 bool EP2_IN_callback() override
123 {
124 configASSERT(txPending);
125 int woken = 0;
126 if (TxHelper()) {
128 }
129 if (woken)
130 {
131#ifdef TARGET_LPC1768
132 portYIELD();
133#elif defined(TARGET_LPC2368)
137#else
138#error define how to yield on your CPU.
139#endif
140 }
141 return true;
142 }
143
144private:
145 void enable() override
146 {
147 }
148 void disable() override
149 {
150 }
153 void tx_char() override
154 {
155 // Without this critical section there were cases when we deadlocked
156 // with txPending == true but no interrupt coming in to clear it.
157 taskENTER_CRITICAL();
158 if (txPending)
159 {
160 taskEXIT_CRITICAL();
161 return;
162 }
163 txPending = true;
164 if (TxHelper()) {
166 }
167 taskEXIT_CRITICAL();
168 }
169
171 static const unsigned MAX_TX_PACKET_LENGTH = 64;
173 static const unsigned MAX_RX_PACKET_LENGTH = 64;
174
178 bool TxHelper()
179 {
180 size_t count;
181 bool signal = false;
182 for (count = 0; count < MAX_TX_PACKET_LENGTH;)
183 {
184 uint8_t *data;
185 size_t max_count = std::min(txBuf->data_read_pointer(&data),
186 MAX_TX_PACKET_LENGTH - count);
187 if (max_count)
188 {
189 memcpy(&txData[count], data, max_count);
190 count += max_count;
191 txBuf->consume(max_count);
192 signal = true;
193 }
194 else
195 {
196 break;
197 }
198 }
199 if (!count)
200 {
201 txPending = false;
202 return signal;
203 }
204 if (!configured())
205 {
206 // An error occured, data was lost.
207 txPending = false;
208 overrunCount += count;
209 return signal;
210 }
211 txPending = true;
212 sendNB(txData, count);
213 return signal;
214 }
215
216 void RxThread()
217 {
218 while (1)
219 {
221 portENTER_CRITICAL();
222 // we read the packet received to our assembly buffer
223 bool result = readEP_NB(rxData, &rxSize);
224 portEXIT_CRITICAL();
225 if (!result)
226 {
227 diewith(0x80000CCC);
228 }
229 for (uint32_t i = 0; i < rxSize; i++)
230 {
233 //os_mq_send(rxQ, rxData + i);
234 }
235 rxSize = 0;
236 // We reactivate the endpoint to receive next characters
237 // readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
238 }
239 }
240
243 static void* _RxThread(void* arg)
244 {
245 ((MbedRawUSBSerial*)arg)->RxThread();
246 return NULL;
247 }
248
250 uint32_t rxSize;
251 uint8_t rxData
255 os_sem_t rxSem;
256};
257
258void* operator new(size_t size)
259{
260 return malloc(size);
261}
262
263void* operator new [](size_t size)
264{ return malloc(size); } void
265operator delete(void* ptr) noexcept(true)
266{
267 free(ptr);
268}
269
270void operator delete [](void* ptr) noexcept(true)
271{ free(ptr); } int __cxa_guard_acquire(__guard* g)
272{
273 return !*(char*)(g);
274};
276{
277 *(char*)g = 1;
278};
280
281void __cxa_pure_virtual(void) {};
282
283
void diewith(uint32_t pattern)
Sets a blinking pattern and never returns.
void signal_condition()
Signal the wakeup condition.
size_t consume(size_t items)
Remove a number of items from the buffer by advancing the readIndex.
void signal_condition_from_isr()
Signal the wakeup condition from an ISR context.
size_t data_read_pointer(T **buf)
Get a reference to the current location in the buffer for read.
const char * name
device name
Definition Devtab.hxx:266
This class is an empty wrapper around MBed's USB CDC class.
static const unsigned MAX_TX_PACKET_LENGTH
What's the maximum packet length for transmit.
MbedRawUSBSerial(const char *name, uint16_t vendor_id=0x1f00, uint16_t product_id=0x2012, uint16_t product_release=0x0001)
Constructor.
uint8_t rxData[MAX_RX_PACKET_LENGTH]
packet assembly buffer from host
uint32_t rxSize
number of valid characters in rxData
bool EP2_IN_callback() override
Callback when EP2_IN is active.
void enable() override
function to enable device
void tx_char() override
function to try and transmit a character
void disable() override
function to disable device
bool TxHelper()
Transmits count bytes from the txData buffer.
uint8_t txData[MAX_TX_PACKET_LENGTH]
packet assemby buffer to host
static void * _RxThread(void *arg)
Entry point to receiving thread.
bool txPending
transmission currently pending
os_sem_t rxSem
Semaphore to wake up receiving thread.
bool EP2_OUT_callback() override
Callback when EP2_OUT is active.
static const unsigned MAX_RX_PACKET_LENGTH
What's the maximum packet length for receive.
Private data for a serial device.
Definition Serial.hxx:46
DeviceBuffer< uint8_t > * txBuf
transmit buffer
Definition Serial.hxx:84
unsigned int overrunCount
overrun count
Definition Serial.hxx:86
int __cxa_guard_acquire(__guard *)
C++ operator (not sure why this is needed).
void __cxa_guard_abort(__guard *)
C++ operator (not sure why this is needed).
void __cxa_pure_virtual(void)
C++ operator (not sure why this is needed).
void __cxa_guard_release(__guard *)
C++ operator (not sure why this is needed).
__extension__ typedef int __guard
not sure why this is needed.
MbedRawUSBSerial g_mbed_usb_serial("/dev/serUSB0")
Global object for the mbed usb serial.
int os_thread_create(os_thread_t *thread, const char *name, int priority, size_t stack_size, void *(*start_routine)(void *), void *arg)
Create a thread.
Definition os.c:450
OS_INLINE int os_sem_init(os_sem_t *sem, unsigned int value)
Initialize a semaphore.
Definition os.h:604
OS_INLINE int os_sem_wait(os_sem_t *sem)
Wait on a semaphore.
Definition os.h:681
OS_INLINE int os_sem_destroy(os_sem_t *sem)
Destroy a semaphore.
Definition os.h:627