Skip to content

Commit 1f0f183

Browse files
committed
continued with mb9bf560l usb driver (still WIP)
1 parent 33d55ca commit 1f0f183

File tree

1 file changed

+136
-3
lines changed
  • targets/core/cypress/mb9bf560l

1 file changed

+136
-3
lines changed

targets/core/cypress/mb9bf560l/usb.hpp

Lines changed: 136 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,76 @@ namespace klib::core::mb9bf560l::io {
9898
// struct with information about the state of a endpoint
9999
static inline volatile detail::usb::state state[endpoint_count] = {};
100100

101+
/**
102+
* @brief Convert a mode to the correct raw value for the usb hardware
103+
*
104+
* @param mode
105+
* @return uint8_t
106+
*/
107+
constexpr static uint8_t transfer_type_to_raw(const klib::usb::descriptor::transfer_type type) {
108+
// convert the type to raw data
109+
switch (type) {
110+
case klib::usb::descriptor::transfer_type::isochronous:
111+
return 0b01;
112+
case klib::usb::descriptor::transfer_type::bulk:
113+
return 0b10;
114+
case klib::usb::descriptor::transfer_type::interrupt:
115+
return 0b11;
116+
default:
117+
return 0b00;
118+
}
119+
}
120+
121+
/**
122+
* @brief Convert a mode to the correct raw value for the usb hardware
123+
*
124+
* @param mode
125+
* @return uint8_t
126+
*/
127+
constexpr static bool endpoint_mode_to_raw(const klib::usb::usb::endpoint_mode mode) {
128+
switch (mode) {
129+
case klib::usb::usb::endpoint_mode::out:
130+
return false;
131+
case klib::usb::usb::endpoint_mode::in:
132+
case klib::usb::usb::endpoint_mode::control:
133+
case klib::usb::usb::endpoint_mode::disabled:
134+
default:
135+
return true;
136+
}
137+
}
138+
139+
static void clear_endpoint_state(const uint8_t endpoint) {
140+
state[endpoint].is_busy = false;
141+
state[endpoint].requested_size = 0;
142+
state[endpoint].transferred_size = 0;
143+
state[endpoint].callback = nullptr;
144+
state[endpoint].data = nullptr;
145+
}
146+
147+
/**
148+
* @brief Reset the bus
149+
*
150+
*/
151+
static void reset() {
152+
// reset the usb
153+
Usb::port->UDCC |= (0x1 << 7);
154+
155+
// change the power mode to self powered
156+
Usb::port->UDCC |= 0x1;
157+
158+
// configure enpoint 0 endpoint size.
159+
Usb::port->EP0C = max_endpoint_size;
160+
161+
// enable all the interrupts
162+
Usb::port->UDCIE = 0x3f;
163+
164+
// check if we need to call the reset callback
165+
if constexpr (has_bus_reset_callback) {
166+
// call the device bus reset
167+
device::template bus_reset<usb_type>();
168+
}
169+
}
170+
101171
public:
102172
/**
103173
* @brief Interrupt handler for the usb driver
@@ -106,9 +176,22 @@ namespace klib::core::mb9bf560l::io {
106176
*
107177
*/
108178
static void irq_handler() {
179+
// get the status and the mask
180+
const uint8_t status = Usb::port->UDCS;
181+
const uint8_t mask = Usb::port->UDCIE;
109182

110-
}
183+
// create the masked status
184+
const uint32_t masked_status = status & mask;
185+
186+
// clear the interrupt status so we dont miss any
187+
// interrupts while the user code is running. We
188+
// clear a interrupt by setting it to zero. Invert
189+
// the mask to get this result
190+
Usb::port->UDCS = (~masked_status);
111191

192+
193+
}
194+
112195
public:
113196
/**
114197
* @brief Initialize the usb hardware. This requires the usb pll to be enabled beforehand using
@@ -144,11 +227,26 @@ namespace klib::core::mb9bf560l::io {
144227
state[i].callback = nullptr;
145228
}
146229

230+
// do a partial reset
231+
reset();
232+
147233
// register ourselfs with the interrupt controller
148234
target::irq::register_irq<Usb::interrupt_id>(irq_handler);
149235

150236
// enable the usb interrupt
151237
target::enable_irq<Usb::interrupt_id>();
238+
239+
// clear the device addess
240+
set_device_address(0);
241+
242+
// init the device
243+
device::template init<usb_type>();
244+
245+
// check if we should enable the usb connect feature
246+
if constexpr (UsbConnect) {
247+
// enable the usb connect pin to allow connections
248+
connect();
249+
}
152250
}
153251

154252
/**
@@ -211,7 +309,17 @@ namespace klib::core::mb9bf560l::io {
211309
const uint8_t endpoint, const klib::usb::usb::endpoint_mode mode,
212310
const klib::usb::descriptor::transfer_type type, const uint32_t size)
213311
{
214-
312+
// get the register we should write to (skip every other word)
313+
volatile uint16_t *const epc = ((volatile uint16_t*)&Usb::port->EP0C)[endpoint * 2];
314+
315+
// limit the size based on the endpoint number
316+
const uint16_t s = size & (endpoint == 0 ? 0x1ff : 0x7f);
317+
318+
// set the endpoint configuration
319+
epc = (
320+
s | (endpoint_mode_to_raw(mode) << 12) |
321+
(transfer_type_to_raw(type) << 13)
322+
);
215323
}
216324

217325
/**
@@ -269,7 +377,11 @@ namespace klib::core::mb9bf560l::io {
269377
* @param mode
270378
*/
271379
static void stall(const uint8_t endpoint, const klib::usb::usb::endpoint_mode mode) {
380+
// get the register we should write to (skip every other word)
381+
volatile uint16_t *const epc = ((volatile uint16_t*)&Usb::port->EP0C)[endpoint * 2];
272382

383+
// set the stall bit
384+
(*epc) |= 0x1 << 9;
273385
}
274386

275387
/**
@@ -279,7 +391,11 @@ namespace klib::core::mb9bf560l::io {
279391
* @param mode
280392
*/
281393
static void un_stall(const uint8_t endpoint, const klib::usb::usb::endpoint_mode mode) {
394+
// get the register we should write to (skip every other word)
395+
volatile uint16_t *const epc = ((volatile uint16_t*)&Usb::port->EP0C)[endpoint * 2];
282396

397+
// clear the stall bit
398+
(*epc) = (*epc) & (~(0x1 << 9));
283399
}
284400

285401
/**
@@ -291,7 +407,11 @@ namespace klib::core::mb9bf560l::io {
291407
* @return false
292408
*/
293409
static bool is_stalled(const uint8_t endpoint, const klib::usb::usb::endpoint_mode mode) {
294-
return true;
410+
// get the register we should write to (skip every other word)
411+
volatile uint16_t *const epc = ((volatile uint16_t*)&Usb::port->EP0C)[endpoint * 2];
412+
413+
// return the endpoint stall bit
414+
return (*epc) & (0x1 << 9);
295415
}
296416

297417
/**
@@ -374,7 +494,20 @@ namespace klib::core::mb9bf560l::io {
374494
* @param mode
375495
*/
376496
static void cancel(const uint8_t endpoint, const klib::usb::usb::endpoint_mode mode) {
497+
// get the callback
498+
const auto callback = state[endpoint].callback;
499+
500+
// get the amount of data we have transferred
501+
const auto transferred = state[endpoint].transferred_size;
377502

503+
// clear the state of the endpoint
504+
clear_endpoint_state(endpoint);
505+
506+
// check if the callback is valid
507+
if (callback) {
508+
// call the callback
509+
callback(endpoint, mode, klib::usb::usb::error::cancel, transferred);
510+
}
378511
}
379512
};
380513
}

0 commit comments

Comments
 (0)