3030#include " wiring_digital.h"
3131#include " variant.h"
3232
33- #define CDCACM_FIXED_DELAY 120
33+ #define CDC_MAILBOX_TX_CHANNEL 7
34+ #define CDC_MAILBOX_RX_CHANNEL 6
3435
3536extern void CDCSerial_Handler (void );
3637extern void serialEventRun1 (void ) __attribute__((weak));
3738extern void serialEvent1 (void ) __attribute__((weak));
3839
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+
3962// Constructors ////////////////////////////////////////////////////////////////
4063
4164CDCSerialClass::CDCSerialClass (uart_init_info *info)
@@ -47,9 +70,9 @@ CDCSerialClass::CDCSerialClass(uart_init_info *info)
4770
4871void CDCSerialClass::setSharedData (struct cdc_acm_shared_data *cdc_acm_shared_data)
4972{
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 ;
5376}
5477
5578void CDCSerialClass::begin (const uint32_t dwBaudRate)
@@ -73,7 +96,9 @@ void CDCSerialClass::init(const uint32_t dwBaudRate, const uint8_t modeReg)
7396 * Empty the Rx buffer but don't touch Tx buffer: it is drained by the
7497 * LMT one way or another */
7598 _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);
77102 _shared_data->device_open = true ;
78103}
79104
@@ -84,12 +109,10 @@ void CDCSerialClass::end( void )
84109
85110int CDCSerialClass::available ( void )
86111{
87- #define SBS CDCACM_BUFFER_SIZE
88-
89112 if (!_shared_data->device_open )
90113 return (0 );
91114 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 ;
93116}
94117
95118int CDCSerialClass::availableForWrite (void )
@@ -131,28 +154,61 @@ void CDCSerialClass::flush( void )
131154 }
132155}
133156
134- size_t CDCSerialClass::write ( const uint8_t uc_data )
157+ size_t CDCSerialClass::write (uint8_t uc_data )
135158{
136- uint32_t retries = 2 ;
159+ CurieMailboxMsg cdcacm_msg ;
137160
138161 if (!_shared_data->device_open || !_shared_data->host_open )
139162 return (0 );
140163
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);
154187 }
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+ }
156195
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);
158214}
0 commit comments