Skip to content

Commit 53851a6

Browse files
committed
lpc1756 USB added support for isochronous endpoints
1 parent eaaf66d commit 53851a6

File tree

1 file changed

+71
-8
lines changed

1 file changed

+71
-8
lines changed

targets/core/nxp/lpc17xx/usb.hpp

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -429,13 +429,17 @@ namespace klib::core::lpc17xx::io {
429429
}
430430
}
431431

432+
template <bool Isochronous>
432433
static void endpoint_out_callback(const uint8_t endpoint) {
433-
// check if we are busy.
434-
if (!state[endpoint].is_busy) {
435-
// set the flag we have a out interrupt pending
436-
state[endpoint].interrupt_pending = true;
437-
438-
return;
434+
// only check if we are busy if we are not a iso endpoint
435+
if constexpr (Isochronous) {
436+
// check if we are busy.
437+
if (!state[endpoint].is_busy) {
438+
// set the flag we have a out interrupt pending
439+
state[endpoint].interrupt_pending = true;
440+
441+
return;
442+
}
439443
}
440444

441445
// receive more data
@@ -467,6 +471,50 @@ namespace klib::core::lpc17xx::io {
467471
}
468472
}
469473

474+
static void isochronous_irq_handler() {
475+
// we have a frame interrupt. Mark all the isochronous
476+
// endpoints as not busy
477+
for (uint32_t i = 0; i < (endpoint_count / 4); i++) {
478+
// get a iso endpoint
479+
const uint8_t ep = (i + 1) * 3;
480+
481+
// check if we are busy transmitting or receiving data
482+
if (!state[ep].is_busy) {
483+
continue;
484+
}
485+
486+
// get the current realized endpoints. If we allow
487+
// in and out on the same endpoint this wont work
488+
// but as we do not support that we can use this to
489+
// determine if we are a in or a out endpoint
490+
const uint32_t reep = (Usb::port->REEP >> (ep * 2)) & 0x3;
491+
492+
// check what direction is enabled. We check for in
493+
// and out and if we do not have a match we call it
494+
// disabled
495+
const klib::usb::usb::endpoint_mode mode = (
496+
(reep == 0b01) ? klib::usb::usb::endpoint_mode::out : (
497+
(reep == 0b10) ? klib::usb::usb::endpoint_mode::in :
498+
klib::usb::usb::endpoint_mode::disabled
499+
)
500+
);
501+
502+
// check what to do based on the mode
503+
if (mode == klib::usb::usb::endpoint_mode::disabled) {
504+
// not something we can handle. Skip the endpoint
505+
continue;
506+
}
507+
508+
// check how we need to handle the endpoint
509+
if (mode == klib::usb::usb::endpoint_mode::out) {
510+
endpoint_out_callback<true>(ep);
511+
}
512+
else {
513+
endpoint_in_callback(ep);
514+
}
515+
}
516+
}
517+
470518
static void data_irq_handler() {
471519
// get the endpoints we should handle
472520
uint32_t status = Usb::port->EPINTST;
@@ -531,7 +579,7 @@ namespace klib::core::lpc17xx::io {
531579
endpoint_in_callback(ep);
532580
break;
533581
case klib::usb::usb::endpoint_mode::out:
534-
endpoint_out_callback(ep);
582+
endpoint_out_callback<false>(ep);
535583
break;
536584
}
537585
}
@@ -626,10 +674,18 @@ namespace klib::core::lpc17xx::io {
626674
// we have a device status interrupt
627675
device_status_irq();
628676
}
629-
else if (masked_status & (0x1 << 2)) {
677+
678+
// check for a endpoint interrupt
679+
if (masked_status & (0x1 << 2)) {
630680
// we have a endpoint interrupt. Handle it in the data irq
631681
data_irq_handler();
632682
}
683+
684+
// check for a frame interrupt
685+
if (masked_status & 0x1) {
686+
// we have a frame interrupt. Handle it in the iso irq
687+
isochronous_irq_handler();
688+
}
633689
}
634690

635691
public:
@@ -814,6 +870,13 @@ namespace klib::core::lpc17xx::io {
814870
// clear the interrupt flag
815871
Usb::port->DEVINTCLR = 0x100;
816872

873+
// make sure the frame interrupt is enabled when a iso
874+
// endpoint is confiugred
875+
if (type == klib::usb::descriptor::transfer_type::isochronous) {
876+
// enable the frame interrupt
877+
Usb::port->DEVINTEN |= 0x1;
878+
}
879+
817880
// enable the endpoint
818881
write_command(command_phase::command,
819882
static_cast<uint8_t>(endpoint_command::select_endpoint) | ep, 0

0 commit comments

Comments
 (0)