|
|
|
|
|
|
|
|
pending_control = 0x0F; |
|
|
pending_control = 0x0F; |
|
|
mk_setup(setup, 0x40, 0, 0, 0, 0); // reset port |
|
|
mk_setup(setup, 0x40, 0, 0, 0, 0); // reset port |
|
|
queue_Control_Transfer(dev, &setup, NULL, this); |
|
|
queue_Control_Transfer(dev, &setup, NULL, this); |
|
|
|
|
|
control_queued = true; |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void USBSerial::control(const Transfer_t *transfer) |
|
|
void USBSerial::control(const Transfer_t *transfer) |
|
|
{ |
|
|
{ |
|
|
println("control callback (serial)"); |
|
|
println("control callback (serial)"); |
|
|
|
|
|
control_queued = false; |
|
|
|
|
|
|
|
|
// set data format |
|
|
// set data format |
|
|
if (pending_control & 1) { |
|
|
if (pending_control & 1) { |
|
|
pending_control &= ~1; |
|
|
pending_control &= ~1; |
|
|
mk_setup(setup, 0x40, 4, 8, 0, 0); // data format 8N1 |
|
|
mk_setup(setup, 0x40, 4, 8, 0, 0); // data format 8N1 |
|
|
queue_Control_Transfer(device, &setup, NULL, this); |
|
|
queue_Control_Transfer(device, &setup, NULL, this); |
|
|
|
|
|
control_queued = true; |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
// set baud rate |
|
|
// set baud rate |
|
|
|
|
|
|
|
|
uint32_t baudval = 3000000 / baudrate; |
|
|
uint32_t baudval = 3000000 / baudrate; |
|
|
mk_setup(setup, 0x40, 3, baudval, 0, 0); |
|
|
mk_setup(setup, 0x40, 3, baudval, 0, 0); |
|
|
queue_Control_Transfer(device, &setup, NULL, this); |
|
|
queue_Control_Transfer(device, &setup, NULL, this); |
|
|
|
|
|
control_queued = true; |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
// configure flow control |
|
|
// configure flow control |
|
|
|
|
|
|
|
|
pending_control &= ~4; |
|
|
pending_control &= ~4; |
|
|
mk_setup(setup, 0x40, 2, 0, 0, 0); |
|
|
mk_setup(setup, 0x40, 2, 0, 0, 0); |
|
|
queue_Control_Transfer(device, &setup, NULL, this); |
|
|
queue_Control_Transfer(device, &setup, NULL, this); |
|
|
|
|
|
control_queued = true; |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
// set DTR |
|
|
// set DTR |
|
|
|
|
|
|
|
|
pending_control &= ~8; |
|
|
pending_control &= ~8; |
|
|
mk_setup(setup, 0x40, 1, 0x0101, 0, 0); |
|
|
mk_setup(setup, 0x40, 1, 0x0101, 0, 0); |
|
|
queue_Control_Transfer(device, &setup, NULL, this); |
|
|
queue_Control_Transfer(device, &setup, NULL, this); |
|
|
|
|
|
control_queued = true; |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void USBSerial::rx_callback(const Transfer_t *transfer) |
|
|
void USBSerial::rx_callback(const Transfer_t *transfer) |
|
|
|
|
|
|
|
|
len = 0; |
|
|
len = 0; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
if (len > 0) { |
|
|
|
|
|
print("rx: "); |
|
|
|
|
|
print_hexbytes(p, len); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
//if (len > 0) { |
|
|
|
|
|
//print("rx: "); |
|
|
|
|
|
//print_hexbytes(p, len); |
|
|
|
|
|
//} |
|
|
// Copy data from packet buffer to circular buffer. |
|
|
// Copy data from packet buffer to circular buffer. |
|
|
// Assume the buffer will always have space, since we |
|
|
// Assume the buffer will always have space, since we |
|
|
// check before queuing the buffers |
|
|
// check before queuing the buffers |
|
|
uint32_t head = rxhead; |
|
|
uint32_t head = rxhead; |
|
|
uint32_t tail = rxtail; |
|
|
uint32_t tail = rxtail; |
|
|
|
|
|
if (++head >= rxsize) head = 0; |
|
|
uint32_t avail; |
|
|
uint32_t avail; |
|
|
if (len > 0) { |
|
|
if (len > 0) { |
|
|
|
|
|
//print("head=", head); |
|
|
|
|
|
//print(", tail=", tail); |
|
|
avail = rxsize - head; |
|
|
avail = rxsize - head; |
|
|
|
|
|
//print(", avail=", avail); |
|
|
|
|
|
//println(", rxsize=", rxsize); |
|
|
if (avail > len) avail = len; |
|
|
if (avail > len) avail = len; |
|
|
memcpy(rxbuf + head, p, avail); |
|
|
memcpy(rxbuf + head, p, avail); |
|
|
if (len <= avail) { |
|
|
if (len <= avail) { |
|
|
head += avail; |
|
|
|
|
|
|
|
|
head += avail - 1; |
|
|
if (head >= rxsize) head = 0; |
|
|
if (head >= rxsize) head = 0; |
|
|
} else { |
|
|
} else { |
|
|
head = len - avail; |
|
|
|
|
|
memcpy(rxbuf, p + avail, head); |
|
|
|
|
|
|
|
|
head = len - avail - 1; |
|
|
|
|
|
memcpy(rxbuf, p + avail, head + 1); |
|
|
} |
|
|
} |
|
|
rxhead = head; |
|
|
rxhead = head; |
|
|
} |
|
|
} |
|
|
// re-queue packet buffer(s) if possible |
|
|
|
|
|
|
|
|
rx_queue_packets(head, tail); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// re-queue packet buffer(s) if possible |
|
|
|
|
|
void USBSerial::rx_queue_packets(uint32_t head, uint32_t tail) |
|
|
|
|
|
{ |
|
|
|
|
|
uint32_t avail; |
|
|
if (head >= tail) { |
|
|
if (head >= tail) { |
|
|
avail = rxsize - 1 - head + tail; |
|
|
avail = rxsize - 1 - head + tail; |
|
|
} else { |
|
|
} else { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void USBSerial::begin(uint32_t baud, uint32_t format) |
|
|
void USBSerial::begin(uint32_t baud, uint32_t format) |
|
|
{ |
|
|
{ |
|
|
|
|
|
NVIC_DISABLE_IRQ(IRQ_USBHS); |
|
|
|
|
|
baudrate = baud; |
|
|
|
|
|
pending_control |= 2; |
|
|
|
|
|
if (!control_queued) control(NULL); |
|
|
|
|
|
NVIC_ENABLE_IRQ(IRQ_USBHS); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void USBSerial::end(void) |
|
|
void USBSerial::end(void) |
|
|
|
|
|
|
|
|
uint32_t head = rxhead; |
|
|
uint32_t head = rxhead; |
|
|
uint32_t tail = rxtail; |
|
|
uint32_t tail = rxtail; |
|
|
if (head >= tail) return head - tail; |
|
|
if (head >= tail) return head - tail; |
|
|
return 0; |
|
|
|
|
|
|
|
|
return rxsize + head - tail; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int USBSerial::peek(void) |
|
|
int USBSerial::peek(void) |
|
|
|
|
|
|
|
|
if (++tail >= rxsize) tail = 0; |
|
|
if (++tail >= rxsize) tail = 0; |
|
|
int c = rxbuf[tail]; |
|
|
int c = rxbuf[tail]; |
|
|
rxtail = tail; |
|
|
rxtail = tail; |
|
|
// TODO: if rx packet not queued, and buffer now can fit a full packet, queue it |
|
|
|
|
|
|
|
|
if ((rxstate & 0x03) != 0x03) { |
|
|
|
|
|
NVIC_DISABLE_IRQ(IRQ_USBHS); |
|
|
|
|
|
rx_queue_packets(head, tail); |
|
|
|
|
|
NVIC_ENABLE_IRQ(IRQ_USBHS); |
|
|
|
|
|
} |
|
|
return c; |
|
|
return c; |
|
|
} |
|
|
} |
|
|
|
|
|
|