1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-13 03:20:00 +03:00
betaflight/src/platform/PICO/serial_usb_vcp_pico.c
Jay Blackman 5969e4c3ad
PICO: Initial multicore (using it for IRQs) (#14458)
* PICO: Initial multicore (using it for IRQs)

* Updated so any function can be pushed.

* Corrected includes

* Move to queues

* Removed header

* Adding check on command

- correcting core reset return

* Updates based on feedback

* Whitespace

* making static

* Removing comment
2025-06-23 10:07:22 +10:00

212 lines
4.7 KiB
C

/*
* This file is part of Betaflight.
*
* Betaflight is free software. You can redistribute this software
* and/or modify this software under the terms of the GNU General
* Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later
* version.
*
* Betaflight is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this software.
*
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <stdbool.h>
#include "platform.h"
#ifdef USE_VCP
#include "build/build_config.h"
#include "common/utils.h"
#include "drivers/io.h"
#include "pg/usb.h"
#include "usb/usb_cdc.h"
#include "drivers/time.h"
#include "drivers/serial.h"
#include "drivers/serial_usb_vcp.h"
#include "platform/multicore.h"
static vcpPort_t vcpPort = { 0 };
static void usbVcpSetBaudRate(serialPort_t *instance, uint32_t baudRate)
{
UNUSED(instance);
UNUSED(baudRate);
}
static void usbVcpSetMode(serialPort_t *instance, portMode_e mode)
{
UNUSED(instance);
UNUSED(mode);
}
static void usbVcpSetCtrlLineStateCb(serialPort_t *instance, void (*cb)(void *context, uint16_t ctrlLineState), void *context)
{
UNUSED(instance);
UNUSED(cb);
UNUSED(context);
}
static void usbVcpSetBaudRateCb(serialPort_t *instance, void (*cb)(serialPort_t *context, uint32_t baud), serialPort_t *context)
{
UNUSED(instance);
UNUSED(cb);
UNUSED(context);
}
static bool isUsbVcpTransmitBufferEmpty(const serialPort_t *instance)
{
UNUSED(instance);
return true;
}
static uint32_t usbVcpRxBytesAvailable(const serialPort_t *instance)
{
UNUSED(instance);
return cdc_usb_bytes_available();
}
static uint8_t usbVcpRead(serialPort_t *instance)
{
UNUSED(instance);
uint8_t buf[1];
while (true) {
if (cdc_usb_read(buf, 1)) {
return buf[0];
}
}
}
static void usbVcpWriteBuf(serialPort_t *instance, const void *data, int count)
{
UNUSED(instance);
if (!(cdc_usb_connected() && cdc_usb_configured())) {
return;
}
const uint8_t *p = data;
while (count > 0) {
int txed = cdc_usb_write(p, count);
if (txed <= 0) {
break;
}
count -= txed;
p += txed;
}
}
static bool usbVcpFlush(vcpPort_t *port)
{
uint32_t count = port->txAt;
port->txAt = 0;
if (count == 0) {
return true;
}
if (!cdc_usb_connected() || !cdc_usb_configured()) {
return false;
}
const uint8_t *p = port->txBuf;
while (count > 0) {
int txed = cdc_usb_write(p, count);
if (txed <= 0) {
break;
}
count -= txed;
p += txed;
}
return count == 0;
}
static void usbVcpWrite(serialPort_t *instance, uint8_t c)
{
vcpPort_t *port = container_of(instance, vcpPort_t, port);
port->txBuf[port->txAt++] = c;
if (!port->buffering || port->txAt >= ARRAYLEN(port->txBuf)) {
usbVcpFlush(port);
}
}
static void usbVcpBeginWrite(serialPort_t *instance)
{
vcpPort_t *port = container_of(instance, vcpPort_t, port);
port->buffering = true;
}
static uint32_t usbTxBytesFree(const serialPort_t *instance)
{
UNUSED(instance);
return cdc_usb_tx_bytes_free();
}
static void usbVcpEndWrite(serialPort_t *instance)
{
vcpPort_t *port = container_of(instance, vcpPort_t, port);
port->buffering = false;
usbVcpFlush(port);
}
static const struct serialPortVTable usbVTable[] = {
{
.serialWrite = usbVcpWrite,
.serialTotalRxWaiting = usbVcpRxBytesAvailable,
.serialTotalTxFree = usbTxBytesFree,
.serialRead = usbVcpRead,
.serialSetBaudRate = usbVcpSetBaudRate,
.isSerialTransmitBufferEmpty = isUsbVcpTransmitBufferEmpty,
.setMode = usbVcpSetMode,
.setCtrlLineStateCb = usbVcpSetCtrlLineStateCb,
.setBaudRateCb = usbVcpSetBaudRateCb,
.writeBuf = usbVcpWriteBuf,
.beginWrite = usbVcpBeginWrite,
.endWrite = usbVcpEndWrite
}
};
serialPort_t *usbVcpOpen(void)
{
// initialise the USB CDC interface
// potentially this could be done in a multicore task
//multicoreExecuteBlocking(&cdc_usb_init);
cdc_usb_init();
vcpPort_t *s = &vcpPort;
s->port.vTable = usbVTable;
return &s->port;
}
uint32_t usbVcpGetBaudRate(serialPort_t *instance)
{
UNUSED(instance);
return cdc_usb_baud_rate();
}
uint8_t usbVcpIsConnected(void)
{
return cdc_usb_connected();
}
#endif // USE_VCP