rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
usbconsole.cpp
Go to the documentation of this file.
1#include "pch.h"
2
3#if EFI_USB_SERIAL
4
5#include "pdl_header.h"
6#include "usb.h"
7#include "UsbDeviceCdcCom.h"
8
9// 10 seconds
10#define USB_WRITE_TIMEOUT 10000
11
12// See uart_dma_s
13#define USB_FIFO_BUFFER_SIZE (BLOCKING_FACTOR + 30)
14
15// struct needed for async transfer mode
16typedef struct {
17 // secondary FIFO buffer for async. transfer
18 uint8_t buffer[USB_FIFO_BUFFER_SIZE];
19 // input FIFO Rx queue
20 input_queue_t fifoRxQueue;
21} usb_buf_s;
22
23static usb_buf_s usbBuf;
24
25static bool isUsbSerialInitialized = false;
26
27static bool isUsbSerialInitStarted = false;
28
29// called from the USB IRQ handler
30static void onUsbDataReceived(uint8_t* pu8Data, uint32_t u32ReceviedSize) {
31 osalSysLockFromISR();
32
33 // copy the data to the FIFO buffer
34 for (int i = 0; i < u32ReceviedSize; i++) {
35 if (iqPutI(&usbBuf.fifoRxQueue, *pu8Data++) != Q_OK) {
36 break; // todo: ignore overflow?
37 }
38 }
39
40 // tell the reader thread to wake up
41#if 0
42 if (threadrx != NULL) {
43 osalThreadResumeI(&threadrx, MSG_OK);
44 }
45#endif
46
47 osalSysUnlockFromISR();
48}
49
50// To use UART driver instead of Serial, we need to imitate "BaseChannel" streaming functionality
51static msg_t _putt(void *ip, uint8_t b, sysinterval_t timeout) {
52 (void)ip;
53 (void)timeout;
54 UsbDeviceCdcCom_SendByte(b);
55 return MSG_OK;
56}
57static size_t _writet(void *ip, const uint8_t *bp, size_t n, sysinterval_t timeout) {
58 (void)ip;
59 (void)timeout;
60 UsbDeviceCdcCom_SendBuffer((uint8_t *)bp, n);
61 return n;
62}
63static msg_t _put(void *ip, uint8_t b) {
64 (void)ip;
65 UsbDeviceCdcCom_SendByte(b);
66 return MSG_OK;
67}
68static size_t _write(void *ip, const uint8_t *bp, size_t n) {
69 return _writet(ip, bp, n, USB_WRITE_TIMEOUT);
70}
71static size_t _readt(void *ip, uint8_t *bp, size_t n, sysinterval_t timeout) {
72 //size_t numBytesRead = UsbDeviceCdcCom_ReceiveBuffer(bp, n);
73
74 return (size_t)iqReadTimeout(&usbBuf.fifoRxQueue, bp, n, timeout);
75/*
76 // if we don't have all bytes immediately
77 if (numBytesRead < n) {
78 osalSysLock();
79 threadrx = chThdGetSelfX();
80 osalThreadSuspendTimeoutS(&threadrx, timeout);
81 osalSysUnlock();
82 numBytesRead += UsbDeviceCdcCom_ReceiveBuffer(bp + numBytesRead, n - numBytesRead);
83 }
84 return numBytesRead;
85*/
86}
87static msg_t _gett(void *ip, sysinterval_t timeout) {
88 (void)ip;
89 (void)timeout;
90 //msg_t msg = UsbDeviceCdcCom_ReceiveByte();
91 uint8_t b;
92 if (_readt(ip, &b, 1, timeout) == 1)
93 return (msg_t)b;
94 return MSG_TIMEOUT;
95}
96static msg_t _get(void *ip) {
97 return _gett(ip, USB_WRITE_TIMEOUT);
98}
99static size_t _read(void *ip, uint8_t *bp, size_t n) {
100 (void)ip;
101 return _readt(ip, bp, n, USB_WRITE_TIMEOUT);
102}
103static msg_t _ctl(void *ip, unsigned int operation, void *arg) {
104 return MSG_OK;
105}
106
107// This is a "fake" channel for getConsoleChannel() filled with our handlers
108static const struct BaseChannelVMT usbChannelVmt = {
109 .instance_offset = (size_t)0, .write = _write, .read = _read, .put = _put, .get = _get,
110 .putt = _putt, .gett = _gett, .writet = _writet, .readt = _readt, .ctl = _ctl
111};
112
113BaseChannel SDU1 = { .vmt = &usbChannelVmt };
114
115
116static void usb_VBus_handler(uint8_t channel) {
117 // call it only if the USB driver is already initialized
120}
121
122/**
123 ******************************************************************************
124 ** \brief Main function of PDL
125 **
126 ** \return uint32_t return value, if needed
127 ******************************************************************************/
130 return;
131
133
135
136 // init FIFO queue
137 iqObjectInit(&usbBuf.fifoRxQueue, usbBuf.buffer, sizeof(usbBuf.buffer), NULL, NULL);
138
139 UsbDeviceCdcCom_SetReceivedCallback(onUsbDataReceived);
140
142
143 // init VBus detector for P60 (INT31_0)
144 SetPinFunc_INT31_0(0u);
145 _pal_lld_setpadeventhandler(31, ExIntRisingEdge, usb_VBus_handler);
146
147
149
150}
151
153 return isUsbSerialInitialized /*&& SDU1.config->usbp->state == USB_ACTIVE*/;
154}
155
156#endif /* EFI_USB_SERIAL */
uint16_t channel
Definition adc_inputs.h:104
static bool write(void *, uint32_t, const uint8_t *, uint32_t)
static bool read(void *instance, uint32_t startblk, uint8_t *buffer, uint32_t)
static size_t _writet(void *ip, const uint8_t *bp, size_t n, sysinterval_t timeout)
static usb_buf_s usbBuf
static void onUsbDataReceived(uint8_t *pu8Data, uint32_t u32ReceviedSize)
static msg_t _get(void *ip)
static msg_t _gett(void *ip, sysinterval_t timeout)
static msg_t _ctl(void *ip, unsigned int operation, void *arg)
BaseChannel SDU1
static msg_t _put(void *ip, uint8_t b)
static size_t _write(void *ip, const uint8_t *bp, size_t n)
static msg_t _putt(void *ip, uint8_t b, sysinterval_t timeout)
static bool isUsbSerialInitialized
static size_t _readt(void *ip, uint8_t *bp, size_t n, sysinterval_t timeout)
static void usb_VBus_handler(uint8_t channel)
static size_t _read(void *ip, uint8_t *bp, size_t n)
bool is_usb_serial_ready()
void usb_serial_start(void)
Main function of PDL.
static bool isUsbSerialInitStarted
static const struct BaseChannelVMT usbChannelVmt
static BigBufferHandle buffer
void UsbConfig_UsbInit(void)
Initialize USB.
void UsbConfig_SwitchMode(void)
Switch USB mode (dummy if USB is disabled)