30
30
#include " wiring_digital.h"
31
31
#include " variant.h"
32
32
33
- #define CDCACM_FIXED_DELAY 120
33
+ #define CDC_MAILBOX_TX_CHANNEL 7
34
+ #define CDC_MAILBOX_RX_CHANNEL 6
34
35
35
36
extern void CDCSerial_Handler (void );
36
37
extern void serialEventRun1 (void ) __attribute__((weak));
37
38
extern void serialEvent1 (void ) __attribute__((weak));
38
39
40
+ static void cdc_mbox_isr (CurieMailboxMsg msg)
41
+ {
42
+ char *rxbuffptr = (char *)msg.data ;
43
+ int new_head;
44
+ for (int i = 0 ; i < MBOX_BYTES; i++)
45
+ {
46
+ if ((uint8_t )(*(rxbuffptr+i)) != ' \0 ' )
47
+ {
48
+ new_head = (Serial._rx_buffer ->head +1 ) % CDCACM_BUFFER_SIZE;
49
+ if (new_head != Serial._rx_buffer ->tail )
50
+ {
51
+ Serial._rx_buffer ->data [Serial._rx_buffer ->head ] = *(rxbuffptr+i);
52
+ Serial._rx_buffer ->head = new_head;
53
+ }
54
+ }
55
+ else
56
+ {
57
+ break ;
58
+ }
59
+ }
60
+ }
61
+
39
62
// Constructors ////////////////////////////////////////////////////////////////
40
63
41
64
CDCSerialClass::CDCSerialClass (uart_init_info *info)
@@ -47,9 +70,9 @@ CDCSerialClass::CDCSerialClass(uart_init_info *info)
47
70
48
71
void CDCSerialClass::setSharedData (struct cdc_acm_shared_data *cdc_acm_shared_data)
49
72
{
50
- this -> _shared_data = cdc_acm_shared_data;
51
- this -> _rx_buffer = cdc_acm_shared_data->rx_buffer ;
52
- this -> _tx_buffer = cdc_acm_shared_data->tx_buffer ;
73
+ _shared_data = cdc_acm_shared_data;
74
+ _rx_buffer = cdc_acm_shared_data->rx_buffer ;
75
+ _tx_buffer = cdc_acm_shared_data->tx_buffer ;
53
76
}
54
77
55
78
void CDCSerialClass::begin (const uint32_t dwBaudRate)
@@ -73,7 +96,9 @@ void CDCSerialClass::init(const uint32_t dwBaudRate, const uint8_t modeReg)
73
96
* Empty the Rx buffer but don't touch Tx buffer: it is drained by the
74
97
* LMT one way or another */
75
98
_rx_buffer->tail = _rx_buffer->head ;
76
-
99
+
100
+ mailbox_register (CDC_MAILBOX_RX_CHANNEL, cdc_mbox_isr);
101
+ mailbox_enable_receive (CDC_MAILBOX_RX_CHANNEL);
77
102
_shared_data->device_open = true ;
78
103
}
79
104
@@ -84,12 +109,10 @@ void CDCSerialClass::end( void )
84
109
85
110
int CDCSerialClass::available ( void )
86
111
{
87
- #define SBS CDCACM_BUFFER_SIZE
88
-
89
112
if (!_shared_data->device_open )
90
113
return (0 );
91
114
else
92
- return (int )(SBS + _rx_buffer->head - _rx_buffer->tail ) % SBS ;
115
+ return (int )(CDCACM_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail ) % CDCACM_BUFFER_SIZE ;
93
116
}
94
117
95
118
int CDCSerialClass::availableForWrite (void )
@@ -131,28 +154,61 @@ void CDCSerialClass::flush( void )
131
154
}
132
155
}
133
156
134
- size_t CDCSerialClass::write ( const uint8_t uc_data )
157
+ size_t CDCSerialClass::write (uint8_t uc_data )
135
158
{
136
- uint32_t retries = 2 ;
159
+ CurieMailboxMsg cdcacm_msg ;
137
160
138
161
if (!_shared_data->device_open || !_shared_data->host_open )
139
162
return (0 );
140
163
141
- do {
142
- int i = (uint32_t )(_tx_buffer->head + 1 ) % CDCACM_BUFFER_SIZE;
143
- // if we should be storing the received character into the location
144
- // just before the tail (meaning that the head would advance to the
145
- // current location of the tail), we're about to overflow the buffer
146
- // and so we don't write the character or advance the head.
147
- if (i != _tx_buffer->tail ) {
148
- _tx_buffer->data [_tx_buffer->head ] = uc_data;
149
- _tx_buffer->head = i;
150
-
151
- // Just use a fixed delay to make it compatible with the CODK-M based firmware
152
- delayMicroseconds (CDCACM_FIXED_DELAY);
153
- break ;
164
+ cdcacm_msg.channel = CDC_MAILBOX_TX_CHANNEL;
165
+ cdcacm_msg.data [0 ] = uc_data;
166
+ mailbox_write (cdcacm_msg);
167
+ delayMicroseconds (_writeDelayUsec);
168
+ return 1 ;
169
+ }
170
+
171
+ size_t CDCSerialClass::write (const uint8_t *buffer, size_t size)
172
+ {
173
+ CurieMailboxMsg cdcacm_msg;
174
+ cdcacm_msg.channel = CDC_MAILBOX_TX_CHANNEL;
175
+ if (!_shared_data->device_open || !_shared_data->host_open )
176
+ return (0 );
177
+
178
+ int msg_len = size;
179
+
180
+ for (int i = 0 ;msg_len > 0 ; msg_len -= MBOX_BYTES, i += MBOX_BYTES)
181
+ {
182
+ /* Copy data into mailbox message */
183
+ memset (cdcacm_msg.data , 0 , MBOX_BYTES);
184
+ if (msg_len >= MBOX_BYTES)
185
+ {
186
+ memcpy (cdcacm_msg.data , buffer+i, MBOX_BYTES);
154
187
}
155
- } while (retries--);
188
+ else
189
+ {
190
+ memcpy (cdcacm_msg.data , buffer+i, msg_len);
191
+ }
192
+ /* Write to mailbox*/
193
+ mailbox_write (cdcacm_msg);
194
+ }
156
195
157
- return 1 ;
196
+ // Mimick the throughput of a typical UART by throttling the data
197
+ // flow according to the configured baud rate
198
+ delayMicroseconds (_writeDelayUsec * size);
199
+
200
+ return size;
201
+ }
202
+
203
+ size_t CDCSerialClass::write (const char *str)
204
+ {
205
+ if (str == NULL ) return 0 ;
206
+ CurieMailboxMsg cdcacm_msg;
207
+ cdcacm_msg.channel = CDC_MAILBOX_TX_CHANNEL;
208
+ if (!_shared_data->device_open || !_shared_data->host_open )
209
+ return (0 );
210
+
211
+ int msg_len = strlen (str);
212
+
213
+ return write ((const uint8_t *)str, msg_len);
158
214
}
0 commit comments