@@ -89,6 +89,8 @@ void WDT_IRQHandler() {
89
89
#include "nrf_drv_clock.h"
90
90
#include "nrf_drv_power.h"
91
91
92
+ // TODO: It'd be nice if APP_USBD_CONFIG_EVENT_QUEUE_ENABLE could be 0 but it seems cdc_acm_user_ev_handler isn't called if it is
93
+
92
94
/**
93
95
* @brief Enable power USB detection
94
96
*
@@ -130,6 +132,7 @@ static char m_tx_buffer[NRF_DRV_USBD_EPSIZE];
130
132
* */
131
133
static bool m_usb_connected = false;
132
134
static bool m_usb_open = false;
135
+ static bool m_usb_transmitting = false;
133
136
134
137
/**
135
138
* @brief User event handler @ref app_usbd_cdc_acm_user_ev_handler_t (headphones)
@@ -142,38 +145,50 @@ static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
142
145
143
146
switch (event )
144
147
{
145
- case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN :
146
- {
147
- jsiConsolePrintf ("APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN\n" );
148
+ case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN : {
149
+ //jsiConsolePrintf("APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN\n");
148
150
m_usb_open = true;
151
+ m_usb_transmitting = false;
149
152
/*Setup first transfer*/
150
153
ret_code_t ret = app_usbd_cdc_acm_read (& m_app_cdc_acm ,
151
154
m_rx_buffer ,
152
155
sizeof (m_rx_buffer ));
153
156
UNUSED_VARIABLE (ret );
157
+ // USB connected - so move console device over to it
158
+ if (jsiGetConsoleDevice ()!= EV_LIMBO ) {
159
+ if (!jsiIsConsoleDeviceForced ())
160
+ jsiSetConsoleDevice (EV_USBSERIAL , false);
161
+ }
154
162
break ;
155
163
}
156
- case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE :
157
- jsiConsolePrintf ("APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE\n" );
164
+ case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE : {
165
+ // jsiConsolePrintf("APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE\n");
158
166
m_usb_open = false;
167
+ m_usb_transmitting = false;
168
+ // USB disconnected, move device back to the default
169
+ if (!jsiIsConsoleDeviceForced () && jsiGetConsoleDevice ()== EV_USBSERIAL )
170
+ jsiSetConsoleDevice (jsiGetPreferredConsoleDevice (), false);
171
+ jshTransmitClearDevice (EV_USBSERIAL ); // clear the transmit queue
159
172
break ;
160
- case APP_USBD_CDC_ACM_USER_EVT_TX_DONE :
161
- // TODO: queue extra transmit here
173
+ }
174
+ case APP_USBD_CDC_ACM_USER_EVT_TX_DONE : {
175
+ // TX finished - queue extra transmit here
176
+ m_usb_transmitting = false;
177
+ jshUSARTKick (EV_USBSERIAL );
162
178
break ;
163
- case APP_USBD_CDC_ACM_USER_EVT_RX_DONE :
164
- {
179
+ }
180
+ case APP_USBD_CDC_ACM_USER_EVT_RX_DONE : {
165
181
ret_code_t ret ;
166
- do
167
- {
168
- /*Get amount of data transfered*/
169
- size_t size = app_usbd_cdc_acm_rx_size (p_cdc_acm );
170
- jshPushIOCharEvents (EV_USBSERIAL , m_rx_buffer , size );
182
+ do {
183
+ /*Get amount of data transfered*/
184
+ size_t size = app_usbd_cdc_acm_rx_size (p_cdc_acm );
185
+ jshPushIOCharEvents (EV_USBSERIAL , m_rx_buffer , size );
171
186
172
187
173
- /*Setup next transfer*/
174
- ret = app_usbd_cdc_acm_read (& m_app_cdc_acm ,
175
- m_rx_buffer ,
176
- sizeof (m_rx_buffer ));
188
+ /*Setup next transfer*/
189
+ ret = app_usbd_cdc_acm_read (& m_app_cdc_acm ,
190
+ m_rx_buffer ,
191
+ sizeof (m_rx_buffer ));
177
192
} while (ret == NRF_SUCCESS );
178
193
break ;
179
194
}
@@ -185,42 +200,39 @@ static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
185
200
static void usbd_user_ev_handler (app_usbd_event_type_t event )
186
201
{
187
202
jshHadEvent ();
188
- switch (event )
189
- {
190
- case APP_USBD_EVT_DRV_SUSPEND :
191
- jsiConsolePrintf ("APP_USBD_EVT_DRV_SUSPEND\n" );
192
- break ;
193
- case APP_USBD_EVT_DRV_RESUME :
194
- jsiConsolePrintf ("APP_USBD_EVT_DRV_RESUME\n" );
195
- break ;
196
- case APP_USBD_EVT_STARTED :
197
- jsiConsolePrintf ("APP_USBD_EVT_STARTED\n" );
198
- break ;
199
- case APP_USBD_EVT_STOPPED :
200
- jsiConsolePrintf ("APP_USBD_EVT_STOPPED\n" );
201
- app_usbd_disable ();
202
- break ;
203
- case APP_USBD_EVT_POWER_DETECTED :
204
- jsiConsolePrintf ("APP_USBD_EVT_POWER_DETECTED\n" );
205
-
206
- if (!nrf_drv_usbd_is_enabled ())
207
- {
208
- app_usbd_enable ();
209
- }
210
- break ;
211
- case APP_USBD_EVT_POWER_REMOVED :
212
- jsiConsolePrintf ("APP_USBD_EVT_POWER_REMOVED\n" );
213
- m_usb_connected = false;
214
- app_usbd_stop ();
215
- break ;
216
- case APP_USBD_EVT_POWER_READY :
217
- jsiConsolePrintf ("APP_USBD_EVT_POWER_READY\n" );
218
- app_usbd_start ();
219
- m_usb_connected = true;
220
- break ;
221
- default :
222
- break ;
223
- }
203
+ switch (event )
204
+ {
205
+ case APP_USBD_EVT_DRV_SUSPEND :
206
+ //jsiConsolePrintf("APP_USBD_EVT_DRV_SUSPEND\n");
207
+ break ;
208
+ case APP_USBD_EVT_DRV_RESUME :
209
+ //jsiConsolePrintf("APP_USBD_EVT_DRV_RESUME\n");
210
+ break ;
211
+ case APP_USBD_EVT_STARTED :
212
+ //jsiConsolePrintf("APP_USBD_EVT_STARTED\n");
213
+ break ;
214
+ case APP_USBD_EVT_STOPPED :
215
+ //jsiConsolePrintf("APP_USBD_EVT_STOPPED\n");
216
+ app_usbd_disable ();
217
+ break ;
218
+ case APP_USBD_EVT_POWER_DETECTED :
219
+ //jsiConsolePrintf("APP_USBD_EVT_POWER_DETECTED\n");
220
+ if (!nrf_drv_usbd_is_enabled ())
221
+ app_usbd_enable ();
222
+ break ;
223
+ case APP_USBD_EVT_POWER_REMOVED :
224
+ //jsiConsolePrintf("APP_USBD_EVT_POWER_REMOVED\n");
225
+ m_usb_connected = false;
226
+ app_usbd_stop ();
227
+ break ;
228
+ case APP_USBD_EVT_POWER_READY :
229
+ //jsiConsolePrintf("APP_USBD_EVT_POWER_READY\n");
230
+ app_usbd_start ();
231
+ m_usb_connected = true;
232
+ break ;
233
+ default :
234
+ break ;
235
+ }
224
236
}
225
237
226
238
#endif
@@ -296,7 +308,7 @@ void SysTick_Handler(void) {
296
308
ticksSinceStart ++ ;
297
309
/* One second after start, call jsinteractive. This is used to swap
298
310
* to USB (if connected), or the Serial port. */
299
- if (ticksSinceStart == 5 ) {
311
+ if (ticksSinceStart == 6 ) {
300
312
jsiOneSecondAfterStartup ();
301
313
}
302
314
}
@@ -479,15 +491,11 @@ void jshInit() {
479
491
480
492
ret = nrf_drv_clock_init ();
481
493
APP_ERROR_CHECK (ret );
482
-
483
- jsiConsolePrintf ("USBD init\n" );
484
494
ret = app_usbd_init (& usbd_config );
485
495
APP_ERROR_CHECK (ret );
486
- jsiConsolePrintf ("ok\n" );
487
496
app_usbd_class_inst_t const * class_cdc_acm = app_usbd_cdc_acm_class_inst_get (& m_app_cdc_acm );
488
497
ret = app_usbd_class_append (class_cdc_acm );
489
498
APP_ERROR_CHECK (ret );
490
- jsiConsolePrintf ("cdc ok\n" );
491
499
#endif
492
500
493
501
jsble_init ();
@@ -516,21 +524,15 @@ void jshInit() {
516
524
#endif
517
525
518
526
#ifdef NRF_USB
519
- if (USBD_POWER_DETECTION )
520
- {
521
- jsiConsolePrintf ("app_usbd_power_events_enable\n" );
522
- ret = app_usbd_power_events_enable ();
523
- APP_ERROR_CHECK (ret );
524
- }
525
- else
526
- {
527
- jsiConsolePrintf ("No USB power detection enabled\nStarting USB now\n" );
528
-
529
- app_usbd_enable ();
530
- app_usbd_start ();
531
- }
532
-
533
- jsiConsolePrintf ("USB init done\n" );
527
+ if (USBD_POWER_DETECTION ) {
528
+ //jsiConsolePrintf("app_usbd_power_events_enable\n");
529
+ ret = app_usbd_power_events_enable ();
530
+ APP_ERROR_CHECK (ret );
531
+ } else {
532
+ //jsiConsolePrintf("No USB power detection enabled\nStarting USB now\n");
533
+ app_usbd_enable ();
534
+ app_usbd_start ();
535
+ }
534
536
#endif
535
537
536
538
@@ -551,18 +553,15 @@ void jshKill() {
551
553
552
554
// stuff to do on idle
553
555
void jshIdle () {
554
- #ifdef NRF_USB
556
+ #if defined( NRF_USB )
555
557
while (app_usbd_event_queue_process ()); /* Nothing to do */
558
+ #endif
559
+ }
556
560
557
- int l = 0 ;
558
- int c ;
559
- while ((l < sizeof (m_tx_buffer )) && ((c = jshGetCharToTransmit (EV_USBSERIAL ))>=0 ))
560
- m_tx_buffer [l ++ ] = c ;
561
- if (l ) {
562
- // TODO: check return value?
563
- // This is asynchronous call. User should wait for @ref APP_USBD_CDC_ACM_USER_EVT_TX_DONE event
564
- uint32_t ret = app_usbd_cdc_acm_write (& m_app_cdc_acm , m_tx_buffer , l );
565
- }
561
+ void jshBusyIdle () {
562
+ // When busy waiting for USB data to send we still have to poll USB :(
563
+ #if defined(NRF_USB )
564
+ while (app_usbd_event_queue_process ()); /* Nothing to do */
566
565
#endif
567
566
}
568
567
@@ -1296,6 +1295,20 @@ void jshUSARTKick(IOEventFlags device) {
1296
1295
while (jshGetCharToTransmit (EV_SERIAL1 )>=0 );
1297
1296
}
1298
1297
}
1298
+ #ifdef USB
1299
+ if (device == EV_USBSERIAL && m_usb_open && !m_usb_transmitting ) {
1300
+ int l = 0 ;
1301
+ int c ;
1302
+ while ((l < sizeof (m_tx_buffer )) && ((c = jshGetCharToTransmit (EV_USBSERIAL ))>=0 ))
1303
+ m_tx_buffer [l ++ ] = c ;
1304
+ if (l ) {
1305
+ // This is asynchronous call. We wait for @ref APP_USBD_CDC_ACM_USER_EVT_TX_DONE event
1306
+ uint32_t ret = app_usbd_cdc_acm_write (& m_app_cdc_acm , m_tx_buffer , l );
1307
+ APP_ERROR_CHECK (ret );
1308
+ m_usb_transmitting = true;
1309
+ }
1310
+ }
1311
+ #endif
1299
1312
}
1300
1313
1301
1314
@@ -1610,7 +1623,7 @@ bool jshSleep(JsSysTime timeUntilWake) {
1610
1623
while (!hadEvent ) {
1611
1624
sd_app_evt_wait (); // Go to sleep, wait to be woken up
1612
1625
jshGetSystemTime (); // check for RTC overflows
1613
- #ifdef NRF_USB
1626
+ #if defined( NRF_USB )
1614
1627
while (app_usbd_event_queue_process ()); /* Nothing to do */
1615
1628
#endif
1616
1629
}
0 commit comments