| Line 227... |
Line 227... |
| 227 |
void synopsysotg_ep0_start_rx(const struct usb_instance* instance, int non_setup)
|
227 |
void synopsysotg_ep0_start_rx(const struct usb_instance* instance, int non_setup)
|
| 228 |
{
|
228 |
{
|
| 229 |
const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config;
|
229 |
const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config;
|
| 230 |
struct synopsysotg_state* state = (struct synopsysotg_state*)instance->driver_state;
|
230 |
struct synopsysotg_state* state = (struct synopsysotg_state*)instance->driver_state;
|
| 231 |
|
231 |
|
| 232 |
// If we don't expect a non-SETUP packet, we can stall the OUT pipe,
|
- |
|
| 233 |
// SETUP packets will ignore that.
|
- |
|
| 234 |
if (!non_setup) data->core->outep_regs[0].doepctl.b.stall = 1;
|
- |
|
| 235 |
|
- |
|
| 236 |
// Set up data destination
|
232 |
// Set up data destination
|
| 237 |
if (data->use_dma) data->core->outep_regs[0].doepdma = instance->buffer;
|
233 |
if (data->use_dma) data->core->outep_regs[0].doepdma = instance->buffer;
|
| 238 |
else state->endpoints[0].rxaddr = (uint32_t*)instance->buffer;
|
234 |
else state->endpoints[0].rxaddr = (uint32_t*)instance->buffer;
|
| 239 |
union synopsysotg_dep0xfrsiz deptsiz = { .b = { .supcnt = 3, .pktcnt = !!non_setup, .xfersize = 64 } };
|
235 |
union synopsysotg_dep0xfrsiz deptsiz = { .b = { .supcnt = 3, .pktcnt = !!non_setup, .xfersize = 64 } };
|
| 240 |
data->core->outep_regs[0].doeptsiz.d32 = deptsiz.d32;
|
236 |
data->core->outep_regs[0].doeptsiz.d32 = deptsiz.d32;
|
| Line 243... |
Line 239... |
| 243 |
if (data->use_dma) invalidate_dcache(instance->buffer, sizeof(instance->buffer));
|
239 |
if (data->use_dma) invalidate_dcache(instance->buffer, sizeof(instance->buffer));
|
| 244 |
|
240 |
|
| 245 |
// Enable the endpoint
|
241 |
// Enable the endpoint
|
| 246 |
union synopsysotg_depctl depctl = data->core->outep_regs[0].doepctl;
|
242 |
union synopsysotg_depctl depctl = data->core->outep_regs[0].doepctl;
|
| 247 |
depctl.b.epena = 1;
|
243 |
depctl.b.epena = 1;
|
| 248 |
depctl.b.cnak = 1;
|
244 |
depctl.b.cnak = non_setup;
|
| 249 |
data->core->outep_regs[0].doepctl = depctl;
|
245 |
data->core->outep_regs[0].doepctl = depctl;
|
| 250 |
}
|
246 |
}
|
| 251 |
|
247 |
|
| 252 |
void synopsysotg_ep0_start_tx(const struct usb_instance* instance, const void* buf, int len)
|
248 |
void synopsysotg_ep0_start_tx(const struct usb_instance* instance, const void* buf, int len)
|
| 253 |
{
|
249 |
{
|
| Line 293... |
Line 289... |
| 293 |
// Make sure both EP0 pipes are active.
|
289 |
// Make sure both EP0 pipes are active.
|
| 294 |
// (The hardware should take care of that, but who knows...)
|
290 |
// (The hardware should take care of that, but who knows...)
|
| 295 |
union synopsysotg_depctl depctl = { .b = { .usbactep = 1, .nextep = data->core->inep_regs[0].diepctl.b.nextep } };
|
291 |
union synopsysotg_depctl depctl = { .b = { .usbactep = 1, .nextep = data->core->inep_regs[0].diepctl.b.nextep } };
|
| 296 |
data->core->outep_regs[0].doepctl = depctl;
|
292 |
data->core->outep_regs[0].doepctl = depctl;
|
| 297 |
data->core->inep_regs[0].diepctl = depctl;
|
293 |
data->core->inep_regs[0].diepctl = depctl;
|
| 298 |
|
- |
|
| 299 |
// Prime EP0 for the first setup packet.
|
- |
|
| 300 |
usb_ep0_expect_setup(instance);
|
- |
|
| 301 |
}
|
294 |
}
|
| 302 |
|
295 |
|
| 303 |
void synopsysotg_irq(const struct usb_instance* instance)
|
296 |
void synopsysotg_irq(const struct usb_instance* instance)
|
| 304 |
{
|
297 |
{
|
| 305 |
const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config;
|
298 |
const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config;
|
| Line 313... |
Line 306... |
| 313 |
usb_handle_bus_reset(instance, 0);
|
306 |
usb_handle_bus_reset(instance, 0);
|
| 314 |
}
|
307 |
}
|
| 315 |
|
308 |
|
| 316 |
if (gintsts.b.enumdone)
|
309 |
if (gintsts.b.enumdone)
|
| 317 |
{
|
310 |
{
|
| 318 |
synopsysotg_ep0_init(instance);
|
- |
|
| 319 |
usb_handle_bus_reset(instance, data->core->dregs.dsts.b.enumspd == 0);
|
311 |
usb_handle_bus_reset(instance, data->core->dregs.dsts.b.enumspd == 0);
|
| - |
|
312 |
synopsysotg_ep0_init(instance);
|
| 320 |
}
|
313 |
}
|
| 321 |
|
314 |
|
| 322 |
if (gintsts.b.rxstsqlvl)
|
315 |
if (gintsts.b.rxstsqlvl)
|
| 323 |
{
|
316 |
{
|
| 324 |
// Device to memory part of the "software DMA" implementation, used to receive data if use_dma == 0.
|
317 |
// Device to memory part of the "software DMA" implementation, used to receive data if use_dma == 0.
|
| Line 387... |
Line 380... |
| 387 |
union synopsysotg_doepintn epints = data->core->outep_regs[ep].doepint;
|
380 |
union synopsysotg_doepintn epints = data->core->outep_regs[ep].doepint;
|
| 388 |
union usb_endpoint_number epnum = { .direction = USB_ENDPOINT_DIRECTION_OUT, .number = ep };
|
381 |
union usb_endpoint_number epnum = { .direction = USB_ENDPOINT_DIRECTION_OUT, .number = ep };
|
| 389 |
if (epints.b.setup)
|
382 |
if (epints.b.setup)
|
| 390 |
{
|
383 |
{
|
| 391 |
if (data->use_dma) invalidate_dcache(instance->buffer, sizeof(instance->buffer));
|
384 |
if (data->use_dma) invalidate_dcache(instance->buffer, sizeof(instance->buffer));
|
| 392 |
union synopsysotg_dep0xfrsiz deptsiz = { .d32 = data->core->outep_regs[0].doeptsiz.d32 };
|
- |
|
| 393 |
int back2back = 3 - deptsiz.b.supcnt;
|
- |
|
| 394 |
synopsysotg_flush_in_endpoint(instance, ep);
|
385 |
synopsysotg_flush_in_endpoint(instance, ep);
|
| 395 |
usb_handle_setup_received(instance, epnum, back2back);
|
386 |
usb_handle_setup_received(instance, epnum);
|
| 396 |
}
|
387 |
}
|
| 397 |
else if (epints.b.xfercompl)
|
388 |
else if (epints.b.xfercompl)
|
| 398 |
{
|
389 |
{
|
| 399 |
int bytesleft = data->core->inep_regs[ep].dieptsiz.b.xfersize;
|
390 |
int bytesleft = data->core->inep_regs[ep].dieptsiz.b.xfersize;
|
| 400 |
usb_handle_xfer_complete(instance, epnum, bytesleft);
|
391 |
usb_handle_xfer_complete(instance, epnum, bytesleft);
|