1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2024-12-29 02:39:53 +02:00

trying to simplify things, not working yet

This commit is contained in:
Bas Wijnen 2010-09-08 18:08:57 +02:00
parent 61d76aaefb
commit 3a38ea2944

View File

@ -152,9 +152,6 @@ class Udc:
REQUEST_SENSE = 0x03 REQUEST_SENSE = 0x03
}; };
} __attribute__ ((packed)) } __attribute__ ((packed))
union Cbw:
unsigned u[8]
CBW cbw
static unsigned const max_packet_size0 = 64 static unsigned const max_packet_size0 = 64
static unsigned const max_packet_size_bulk = 64 static unsigned const max_packet_size_bulk = 64
enum Requests: enum Requests:
@ -215,30 +212,23 @@ class Udc:
unsigned handle_setup (Setup *s) unsigned handle_setup (Setup *s)
void irq_usb () void irq_usb ()
void irq_in0 () void irq_in0 ()
void irq_in2 ()
void irq_out () void irq_out ()
void send_csw () void send_csw ()
void parse_cbw ()
unsigned big_endian (unsigned src) unsigned big_endian (unsigned src)
enum State: bool handle_interrupt (bool usb, bool in)
IDLE void stall (unsigned error)
IDLE_WAIT bool stalling[3]
RX
TX
CSW
SEND_CSW
State state
Cbw cbw
unsigned residue unsigned residue
unsigned status unsigned status
unsigned tag
unsigned block_bits unsigned block_bits
Iris::WBlock block Iris::WBlock block
public: public:
void init (Iris::WBlock b) void init (Iris::WBlock b)
void log (unsigned c) void log (unsigned c)
void interrupt () void interrupt ()
unsigned send (unsigned ep, char const *data, unsigned length, unsigned maxlength) void send (unsigned ep, char const *data, unsigned length, unsigned maxlength)
unsigned send_padded (unsigned ep, char const *data, unsigned length, unsigned maxlength) void send_padded (char const *data, unsigned length, unsigned maxlength)
Udc::Device Udc::device_descriptor Udc::Device Udc::device_descriptor
Udc::my_config Udc::config_descriptor Udc::my_config Udc::config_descriptor
@ -268,7 +258,6 @@ void Udc::init (Iris::WBlock b):
// Disconnect from the bus and don't try to get high-speed. // Disconnect from the bus and don't try to get high-speed.
UDC_POWER = 0 UDC_POWER = 0
UDC_TESTMODE = 0 UDC_TESTMODE = 0
UDC_INDEX = 0
configuration = 0 configuration = 0
// exit suspend mode by reading the interrupt register. // exit suspend mode by reading the interrupt register.
unsigned i = UDC_INTRUSB unsigned i = UDC_INTRUSB
@ -279,41 +268,64 @@ void Udc::init (Iris::WBlock b):
UDC_INTRUSBE = UDC_INTR_RESET UDC_INTRUSBE = UDC_INTR_RESET
// enable interrupt on control endpoint. // enable interrupt on control endpoint.
UDC_INTRINE = 1 << 0 UDC_INTRINE = 1 << 0
// Set max packet sizes.
UDC_INDEX = 1
UDC_OUTMAXP = max_packet_size_bulk
UDC_INDEX = 2
UDC_INMAXP = max_packet_size_bulk
// Wait a while. // Wait a while.
Iris::sleep (HZ / 10) Iris::sleep (HZ / 10)
// Connect to the host. // Connect to the host.
UDC_POWER = UDC_POWER_SOFTCONN UDC_POWER = UDC_POWER_SOFTCONN
// Initialize cbw state // Initialize cbw state
state = IDLE
status = 0 status = 0
residue = 0 residue = 0
unsigned Udc::send (unsigned ep, char const *data, unsigned length, unsigned maxlength): void Udc::send (unsigned ep, char const *data, unsigned length, unsigned maxlength):
if maxlength < length: if maxlength < length:
length = maxlength length = maxlength
unsigned i unsigned i
for i = 0; (length - i & ~3) > 0 && i < length; i += 4: for i = 0; (length - i & ~3) > 0 && i < length; i += 4:
UDC_FIFO (ep) = ((unsigned *)data)[i / 4] UDC_FIFO (ep) = ((unsigned *)data)[i / 4]
kdebug_char ('#') kdebug_num (((unsigned *)data)[i / 4], 8)
kdebug (" ")
for ; i < length; ++i: for ; i < length; ++i:
UDC_FIFO8 (ep) = data[i] UDC_FIFO8 (ep) = data[i]
kdebug_char ('+') kdebug_num (data[i], 2)
return ep == 0 ? UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND : 0 kdebug (" ")
unsigned Udc::send_padded (unsigned ep, char const *data, unsigned length, unsigned maxlength): void Udc::send_padded (char const *data, unsigned length, unsigned maxlength):
unsigned len = length < maxlength ? length : maxlength unsigned len = length < maxlength ? length : maxlength
residue = maxlength - len residue = maxlength - len
len = (len + 3) & ~3 len = (len + 3) & ~3
send (ep, data, len, maxlength) send (2, data, len, maxlength)
while len + 3 < maxlength: while len + 3 < maxlength:
UDC_FIFO (ep) = 0 UDC_FIFO (2) = 0
len += 4 len += 4
kdebug_char ('-') kdebug_char ('-')
while len < maxlength: while len < maxlength:
UDC_FIFO8 (ep) = 0 UDC_FIFO8 (2) = 0
++len ++len
kdebug_char ('.') kdebug_char ('.')
UDC_INDEX = 2
UDC_INCSR |= UDC_INCSR_INPKTRDY
while true:
Iris::register_interrupt (IRQ_UDC)
Iris::wait_for_interrupt (IRQ_UDC)
kdebug ("interrupt pad\n")
unsigned usb = UDC_INTRUSB
unsigned in = UDC_INTRIN
unsigned out = UDC_INTROUT
if usb & 4 || in & 1:
kdebug ("general interrupt pad\n")
if !handle_interrupt (usb & 4, in & 1):
return
if out & 2:
Iris::panic (0, "out interrupt while waiting for in")
if in & 4:
break
kdebug ("done interrupt pad\n")
unsigned Udc::get_descriptor (unsigned type, unsigned idx, unsigned len): unsigned Udc::get_descriptor (unsigned type, unsigned idx, unsigned len):
switch type: switch type:
@ -321,16 +333,19 @@ unsigned Udc::get_descriptor (unsigned type, unsigned idx, unsigned len):
if idx != 0: if idx != 0:
return false return false
Iris::debug ("get config descriptor\n") Iris::debug ("get config descriptor\n")
return send (0, reinterpret_cast <char const *> (&config_descriptor), sizeof (config_descriptor), len) send (0, reinterpret_cast <char const *> (&config_descriptor), sizeof (config_descriptor), len)
return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
case Device::Type: case Device::Type:
if idx != 0: if idx != 0:
return false return false
Iris::debug ("get device descriptor\n") Iris::debug ("get device descriptor\n")
return send (0, reinterpret_cast <char const *> (&device_descriptor), sizeof (device_descriptor), len) send (0, reinterpret_cast <char const *> (&device_descriptor), sizeof (device_descriptor), len)
return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
case Device_Qualifier::Type: case Device_Qualifier::Type:
//if idx != 0: //if idx != 0:
// return false // return false
//return send (0, reinterpret_cast <char const *> (&device_qualifier_descriptor), sizeof (device_qualifier_descriptor), len) //send (0, reinterpret_cast <char const *> (&device_qualifier_descriptor), sizeof (device_qualifier_descriptor), len)
//return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
//break //break
return ~0 return ~0
// The 6 is an arbitrary number, except that String <6> is instantiated already. // The 6 is an arbitrary number, except that String <6> is instantiated already.
@ -338,16 +353,20 @@ unsigned Udc::get_descriptor (unsigned type, unsigned idx, unsigned len):
switch idx: switch idx:
case 0: case 0:
Iris::debug ("get language descriptor\n") Iris::debug ("get language descriptor\n")
return send (0, reinterpret_cast <char const *> (&s_langs), sizeof (s_langs), len) send (0, reinterpret_cast <char const *> (&s_langs), sizeof (s_langs), len)
return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
case 1: case 1:
Iris::debug ("get manufacturer descriptor\n") Iris::debug ("get manufacturer descriptor\n")
return send (0, reinterpret_cast <char const *> (&s_manufacturer), sizeof (s_manufacturer), len) send (0, reinterpret_cast <char const *> (&s_manufacturer), sizeof (s_manufacturer), len)
return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
case 2: case 2:
Iris::debug ("get product descriptor\n") Iris::debug ("get product descriptor\n")
return send (0, reinterpret_cast <char const *> (&s_product), sizeof (s_product), len) send (0, reinterpret_cast <char const *> (&s_product), sizeof (s_product), len)
return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
case 3: case 3:
Iris::debug ("get serial descriptor\n") Iris::debug ("get serial descriptor\n")
return send (0, reinterpret_cast <char const *> (&s_serial), sizeof (s_serial), len) send (0, reinterpret_cast <char const *> (&s_serial), sizeof (s_serial), len)
return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
default: default:
return ~0 return ~0
default: default:
@ -378,15 +397,18 @@ unsigned Udc::handle_setup (Setup *s):
switch s->request: switch s->request:
case GET_STATUS: case GET_STATUS:
Iris::debug ("get status\n") Iris::debug ("get status\n")
return send (0, "\0\0", 2, s->length) send (0, "\0\0", 2, s->length)
return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
case GET_DESCRIPTOR: case GET_DESCRIPTOR:
return get_descriptor ((s->value >> 8) & 0xff, s->value & 0xff, s->length) return get_descriptor ((s->value >> 8) & 0xff, s->value & 0xff, s->length)
case GET_CONFIGURATION: case GET_CONFIGURATION:
Iris::debug ("get configuration\n") Iris::debug ("get configuration\n")
return send (0, &configuration, 1, s->length) send (0, &configuration, 1, s->length)
return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
case GET_INTERFACE: case GET_INTERFACE:
Iris::debug ("get interface\n") Iris::debug ("get interface\n")
return send (0, "\0", 1, s->length) send (0, "\0", 1, s->length)
return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
default: default:
return ~0 return ~0
case STANDARD_TO_ENDPOINT: case STANDARD_TO_ENDPOINT:
@ -399,15 +421,13 @@ unsigned Udc::handle_setup (Setup *s):
Iris::debug ("in ep halt reset\n") Iris::debug ("in ep halt reset\n")
UDC_INDEX = 2 UDC_INDEX = 2
UDC_INCSR &= ~(UDC_INCSR_SENDSTALL | UDC_INCSR_SENTSTALL) UDC_INCSR &= ~(UDC_INCSR_SENDSTALL | UDC_INCSR_SENTSTALL)
if state == CSW: stalling[2] = false
state = SEND_CSW
return 0 return 0
case 1: case 1:
Iris::debug ("out ep halt reset\n") Iris::debug ("out ep halt reset\n")
UDC_INDEX = 1 UDC_INDEX = 1
UDC_OUTCSR &= ~(UDC_OUTCSR_SENDSTALL | UDC_OUTCSR_SENTSTALL) UDC_OUTCSR &= ~(UDC_OUTCSR_SENDSTALL | UDC_OUTCSR_SENTSTALL)
if state == CSW: stalling[1] = false
state = SEND_CSW
return 0 return 0
default: default:
return ~0 return ~0
@ -419,14 +439,14 @@ unsigned Udc::handle_setup (Setup *s):
switch s->request: switch s->request:
case GET_MAX_LUN: case GET_MAX_LUN:
Iris::debug ("get max lun\n") Iris::debug ("get max lun\n")
return send (0, "\0", 1, s->length) send (0, "\0", 1, s->length)
return UDC_CSR0_INPKTRDY | UDC_CSR0_DATAEND
default: default:
return ~0 return ~0
case CLASS_TO_INTERFACE: case CLASS_TO_INTERFACE:
switch s->request: switch s->request:
case BULK_ONLY_RESET: case BULK_ONLY_RESET:
Iris::debug ("bulk reset\n") Iris::debug ("bulk reset\n")
state = IDLE
return 0 return 0
default: default:
return ~0 return ~0
@ -441,26 +461,21 @@ void Udc::irq_usb ():
// and on out endpoint 1. // and on out endpoint 1.
UDC_INTROUTE = 1 << 1 UDC_INTROUTE = 1 << 1
UDC_INDEX = 1 UDC_INDEX = 1
UDC_OUTMAXP = max_packet_size_bulk
// Do this twice to flush a double-buffered fifo completely. // Do this twice to flush a double-buffered fifo completely.
UDC_OUTCSR |= UDC_OUTCSR_CDT | UDC_OUTCSR_FF UDC_OUTCSR |= UDC_OUTCSR_CDT | UDC_OUTCSR_FF
UDC_OUTCSR |= UDC_OUTCSR_CDT | UDC_OUTCSR_FF UDC_OUTCSR |= UDC_OUTCSR_CDT | UDC_OUTCSR_FF
UDC_INDEX = 2 UDC_INDEX = 2
UDC_INMAXP = max_packet_size_bulk
UDC_INCSR |= UDC_INCSR_CDT UDC_INCSR |= UDC_INCSR_CDT
UDC_INDEX = 0
Iris::debug ("usb reset\n") Iris::debug ("usb reset\n")
void Udc::irq_in0 (): void Udc::irq_in0 ():
// Interrupt on endpoint 0. // Interrupt on endpoint 0.
UDC_INDEX = 0
unsigned csr = UDC_CSR0 unsigned csr = UDC_CSR0
if csr & UDC_CSR0_SENTSTALL: if csr & UDC_CSR0_SENTSTALL:
csr &= ~(UDC_CSR0_SENTSTALL | UDC_CSR0_SENDSTALL) csr &= ~(UDC_CSR0_SENTSTALL | UDC_CSR0_SENDSTALL)
if csr & UDC_CSR0_SETUPEND: if csr & UDC_CSR0_SETUPEND:
csr |= UDC_CSR0_SVDSETUPEND csr |= UDC_CSR0_SVDSETUPEND
if state == SEND_CSW:
send_csw ()
state = IDLE_WAIT
if !(csr & UDC_CSR0_OUTPKTRDY): if !(csr & UDC_CSR0_OUTPKTRDY):
kdebug ("packet sent 0\n") kdebug ("packet sent 0\n")
return return
@ -476,10 +491,8 @@ void Udc::irq_in0 ():
csr &= ~(UDC_CSR0_SETUPEND | UDC_CSR0_SENDSTALL | UDC_CSR0_SENTSTALL) csr &= ~(UDC_CSR0_SETUPEND | UDC_CSR0_SENDSTALL | UDC_CSR0_SENTSTALL)
unsigned ret = handle_setup (&packet.s) unsigned ret = handle_setup (&packet.s)
UDC_INDEX = 1 UDC_INDEX = 1
UDC_OUTMAXP = max_packet_size_bulk
UDC_OUTCSR |= UDC_OUTCSR_CDT UDC_OUTCSR |= UDC_OUTCSR_CDT
UDC_INDEX = 2 UDC_INDEX = 2
UDC_INMAXP = max_packet_size_bulk
UDC_INCSR |= UDC_INCSR_CDT UDC_INCSR |= UDC_INCSR_CDT
UDC_INDEX = 0 UDC_INDEX = 0
if ret == ~0: if ret == ~0:
@ -487,115 +500,64 @@ void Udc::irq_in0 ():
UDC_CSR0 = csr | UDC_CSR0_SENDSTALL UDC_CSR0 = csr | UDC_CSR0_SENDSTALL
return return
UDC_CSR0 = csr | ret UDC_CSR0 = csr | ret
kdebug ("done in0\n")
void Udc::send_csw (): void Udc::send_csw ():
UDC_INDEX = 2 UDC_INDEX = 2
UDC_FIFO (2) = 0x53425355 UDC_FIFO (2) = 0x53425355
UDC_FIFO (2) = cbw.cbw.tag UDC_FIFO (2) = tag
UDC_FIFO (2) = residue UDC_FIFO (2) = residue
UDC_FIFO8 (2) = status UDC_FIFO8 (2) = status
UDC_INCSR |= UDC_INCSR_INPKTRDY UDC_INCSR |= UDC_INCSR_INPKTRDY
status = 0 status = 0
residue = 0 residue = 0
while true:
Iris::register_interrupt (IRQ_UDC)
Iris::wait_for_interrupt (IRQ_UDC)
unsigned usb = UDC_INTRUSB
unsigned in = UDC_INTRIN
if usb & 4 || in & 1:
if !handle_interrupt (usb & 4, in & 1):
return
if in & 4:
break
unsigned out = UDC_INTROUT
if out & 2:
Iris::panic (0, "out interrupt while waiting for in after csw")
kdebug ("sent csw\n") kdebug ("sent csw\n")
state = IDLE_WAIT
void Udc::stall (unsigned error):
unsigned index = UDC_INDEX
if index == 1:
UDC_OUTCSR |= UDC_OUTCSR_SENDSTALL
else:
UDC_INCSR |= UDC_INCSR_SENDSTALL
stalling[index] = true
kdebug ("stalling\n")
while stalling[index]:
Iris::register_interrupt (IRQ_UDC)
Iris::wait_for_interrupt (IRQ_UDC)
kdebug ("stalling interrupt\n")
unsigned usb = UDC_INTRUSB
unsigned in = UDC_INTRIN
if usb & 4 || in & 1:
kdebug ("stuff\n")
if !handle_interrupt (usb & 4, in & 1):
return
if in & 4:
kdebug ("in interrupt ignored while waiting for stall reset\n")
unsigned out = UDC_INTROUT
if out & 2:
Iris::panic (0, "out interrupt while waiting for stall reset")
kdebug ("no stuff\n")
UDC_INDEX = index
if index == 2:
status = error
send_csw ()
unsigned Udc::big_endian (unsigned src): unsigned Udc::big_endian (unsigned src):
return src >> 24 | src >> 8 & 0xff00 | src << 8 & 0xff0000 | src << 24 return src >> 24 | src >> 8 & 0xff00 | src << 8 & 0xff0000 | src << 24
void Udc::parse_cbw ():
UDC_INDEX = 2
bool to_host = cbw.cbw.flags & 0x80
switch cbw.cbw.data[0]:
case CBW::INQUIRY:
if !to_host:
UDC_INCSR |= UDC_INCSR_SENDSTALL
status = 2
state = CSW
return
Iris::debug ("sending inquiry response\n")
send_padded (2, "\x00\x00\x04\x02\x1f\x00\x00\x00shevek iris usb stick 0 ", 36, cbw.cbw.length)
UDC_INCSR |= UDC_INCSR_INPKTRDY
state = CSW
return
case CBW::TEST_UNIT_READY:
if to_host || cbw.cbw.length != 0:
UDC_INCSR |= UDC_INCSR_SENDSTALL
status = 2
state = CSW
return
Iris::debug ("sending ready response\n")
send_csw ()
return
case CBW::READ_CAPACITY:
if !to_host:
UDC_INCSR |= UDC_INCSR_SENDSTALL
status = 2
state = CSW
return
unsigned capacity[2]
capacity[0] = big_endian ((block.get_size ().value () >> block_bits) - 1)
capacity[1] = big_endian (1 << block_bits)
Iris::debug ("sending capacity: %x * %x\n", capacity[0], capacity[1])
send_padded (2, (char *)capacity, 8, cbw.cbw.length)
UDC_INCSR |= UDC_INCSR_INPKTRDY
state = CSW
return
case CBW::REQUEST_SENSE:
Iris::debug ("sense requested\n")
send_padded (2, "\xf0\x00\x05\x00\x00\x00\x00\x00", 8, cbw.cbw.length)
UDC_INCSR |= UDC_INCSR_INPKTRDY
state = CSW
return
default:
Iris::debug ("cbw:")
for unsigned i = 0; i < cbw.cbw.size; ++i:
kdebug_char (' ')
kdebug_num (cbw.cbw.data[i], 2)
Iris::debug ("\n")
UDC_INCSR |= UDC_INCSR_SENDSTALL
residue = cbw.cbw.length
status = 1
state = CSW
return
// TODO.
void Udc::irq_in2 ():
UDC_INDEX = 2
unsigned csr = UDC_INCSR
if csr & UDC_INCSR_SENDSTALL:
// When stalling, do nothing else.
kdebug ("stalling\n")
UDC_INDEX = 0
return
switch state:
case IDLE_WAIT:
// data has been received.
kdebug ("bulk data was sent\n")
state = IDLE
break
case IDLE:
// This should not happen.
Iris::debug ("in interrupt while idle\n")
break
case TX:
// TODO: transmit more.
kdebug ("bulk transmit\n")
break
case RX:
// This should not be possible.
Iris::debug ("in interrupt while receiving\n")
UDC_INCSR = csr | UDC_INCSR_SENDSTALL
status = 2
state = CSW
break
case CSW:
// The host is now ready to receive the csw; send it.
kdebug ("bulk send csw\n")
send_csw ()
break
UDC_INDEX = 0
void Udc::irq_out (): void Udc::irq_out ():
UDC_INDEX = 1 UDC_INDEX = 1
unsigned csr = UDC_OUTCSR unsigned csr = UDC_OUTCSR
@ -606,48 +568,83 @@ void Udc::irq_out ():
return return
if csr & UDC_OUTCSR_SENDSTALL: if csr & UDC_OUTCSR_SENDSTALL:
// When stalling, do nothing else. // When stalling, do nothing else.
UDC_INDEX = 0 kdebug ("not responding to out during stall\n")
UDC_OUTCSR &= ~UDC_OUTCSR_SENTSTALL
return return
switch state: // expect a new cbw.
case IDLE_WAIT: if size != 31:
Iris::debug ("out interrupt while idle waiting\n") Iris::debug ("count %d != 31\n", size)
break stall (2)
case IDLE: return
// expect a new cbw. union Cbw:
if size != 31: unsigned u[8]
Iris::debug ("count %d != 31\n", UDC_OUTCOUNT) CBW cbw
UDC_OUTCSR = csr | UDC_OUTCSR_SENDSTALL Cbw cbw
status = 2 for unsigned i = 0; i < 8; ++i:
state = CSW cbw.u[i] = UDC_FIFO (1)
tag = cbw.cbw.tag
if cbw.cbw.sig != 0x43425355 || cbw.cbw.lun != 0 || cbw.cbw.size == 0 || cbw.cbw.size > 16:
Iris::debug ("sig %x lun %d size %d\n", cbw.cbw.sig, cbw.cbw.lun, cbw.cbw.size)
stall (2)
return
UDC_OUTCSR = csr & ~UDC_OUTCSR_OUTPKTRDY
kdebug ("bulk cbw\n")
UDC_INDEX = 2
bool to_host = cbw.cbw.flags & 0x80
switch cbw.cbw.data[0]:
case CBW::INQUIRY:
if !to_host:
stall (2)
break break
for unsigned i = 0; i < 8; ++i: Iris::debug ("sending inquiry response\n")
cbw.u[i] = UDC_FIFO (1) send_padded ("\x00\x00\x04\x02\x1f\x00\x00\x00shevek iris usb stick 0 ", 36, cbw.cbw.length)
if cbw.cbw.sig != 0x43425355 || cbw.cbw.lun != 0 || cbw.cbw.size == 0 || cbw.cbw.size > 16: send_csw ()
Iris::debug ("sig %x lun %d size %d\n", cbw.cbw.sig, cbw.cbw.lun, cbw.cbw.size) break
UDC_OUTCSR = csr | UDC_OUTCSR_SENDSTALL case CBW::TEST_UNIT_READY:
status = 2 if to_host || cbw.cbw.length != 0:
state = CSW stall (2)
return
Iris::debug ("sending ready response\n")
send_csw ()
break
case CBW::READ_CAPACITY:
if !to_host:
stall (2)
break break
UDC_OUTCSR = csr & ~UDC_OUTCSR_OUTPKTRDY unsigned capacity[2]
kdebug ("bulk cbw\n") capacity[0] = big_endian ((block.get_size ().value () >> block_bits) - 1)
parse_cbw () capacity[1] = big_endian (1 << block_bits)
Iris::debug ("sending capacity: %x * %x\n", capacity[0], capacity[1])
send_padded ((char *)capacity, 8, cbw.cbw.length)
send_csw ()
break break
case TX: case CBW::REQUEST_SENSE:
// This should be impossible. Iris::debug ("sense requested\n")
Iris::debug ("out interrupt while transmitting\n") send_padded ("\xf0\x00\x05\x00\x00\x00\x00\x00", 8, cbw.cbw.length)
UDC_OUTCSR = csr | UDC_OUTCSR_SENDSTALL send_csw ()
break break
case RX: default:
// TODO: Handle the data. Iris::debug ("cbw:")
kdebug ("bulk rx\n") for unsigned i = 0; i < cbw.cbw.size; ++i:
UDC_OUTCSR = csr & ~UDC_OUTCSR_OUTPKTRDY kdebug_char (' ')
kdebug_num (cbw.cbw.data[i], 2)
Iris::debug ("\n")
residue = cbw.cbw.length
stall (1)
break break
case CSW: // TODO.
// This should be impossible.
Iris::debug ("out interrupt while csw-waiting\n") bool Udc::handle_interrupt (bool usb, bool in):
UDC_OUTCSR = csr | UDC_OUTCSR_SENDSTALL if usb:
break Iris::debug ("usb\t")
UDC_INDEX = 0 // reset.
irq_usb ()
return false
if in:
Iris::debug ("control\t")
// control request
irq_in0 ()
return true
void Udc::interrupt (): void Udc::interrupt ():
while true: while true:
@ -658,21 +655,10 @@ void Udc::interrupt ():
// No more interrupts to handle; this is normal, because we're looping until this happens. // No more interrupts to handle; this is normal, because we're looping until this happens.
Iris::debug ("irq done\n") Iris::debug ("irq done\n")
return return
if usb & 4:
Iris::debug ("usb\t")
// reset.
irq_usb ()
if in & 1:
Iris::debug ("control\t")
// control request
irq_in0 ()
if in & 4: if in & 4:
Iris::debug ("in\t") Iris::debug ("ignoring data request during idle\n")
// bulk in done handle_interrupt (usb & 4, in & 1)
irq_in2 ()
if out & 2: if out & 2:
Iris::debug ("out\t")
// bulk out waiting
irq_out () irq_out ()
Iris::Num start (): Iris::Num start ():