Add serialEvent support for USB, UART0, UART1

parent 1f081150
......@@ -22,6 +22,14 @@
#include <hardware/uart.h>
#include <hardware/gpio.h>
// SerialEvent functions are weak, so when the user doesn't define them,
// the linker just sets their address to 0 (which is checked below).
// The Serialx_available is just a wrapper around Serialx.available(),
// but we can refer to it weakly so we don't pull in the entire
// HardwareSerial instance if the user doesn't also refer to it.
extern void serialEvent1() __attribute__((weak));
extern void serialEvent2() __attribute__((weak));
bool SerialUART::setPinout(pin_size_t tx, pin_size_t rx) {
const uint32_t uart_tx[2] = { 0b000010001000000000001000100000, 0b100000000000100010000000000010 };
const uint32_t uart_rx[2] = { 0b000001000100000000000100010000, 0b010000000000010001000000000001 };
......@@ -147,3 +155,14 @@ SerialUART::operator bool() {
SerialUART Serial1(uart0, 0, 1);
SerialUART Serial2(uart1, 4, 5);
void arduino::serialEvent1Run(void) {
if (serialEvent1 && Serial1.available()) {
serialEvent1();
}
}
void arduino::serialEvent2Run(void) {
if (serialEvent2 && Serial2.available()) {
serialEvent2();
}
}
......@@ -81,4 +81,9 @@ private:
extern SerialUART Serial1; // HW UART 0
extern SerialUART Serial2; // HW UART 1
namespace arduino {
extern void serialEvent1Run(void) __attribute__((weak));
extern void serialEvent2Run(void) __attribute__((weak));
};
#endif
......@@ -22,18 +22,22 @@
#include <Arduino.h>
#include "tusb.h"
#include "pico/time.h"
#include "pico/binary_info.h"
extern "C" {
#include "pico/bootrom.h"
}
#include "pico/bootrom.h"
#include "hardware/irq.h"
#include "pico/mutex.h"
#include "hardware/watchdog.h"
#include "pico/unique_id.h"
// SerialEvent functions are weak, so when the user doesn't define them,
// the linker just sets their address to 0 (which is checked below).
// The Serialx_available is just a wrapper around Serialx.available(),
// but we can refer to it weakly so we don't pull in the entire
// HardwareSerial instance if the user doesn't also refer to it.
extern void serialEvent() __attribute__((weak));
#define PICO_STDIO_USB_TASK_INTERVAL_US 1000
#define PICO_STDIO_USB_LOW_PRIORITY_IRQ 31
......@@ -178,6 +182,10 @@ void SerialUSB::end() {
}
int SerialUSB::peek() {
if (!_running) {
return 0;
}
uint8_t c;
uint32_t owner;
if (!mutex_try_enter(&usb_mutex, &owner)) {
......@@ -190,6 +198,10 @@ int SerialUSB::peek() {
}
int SerialUSB::read() {
if (!_running) {
return -1;
}
uint32_t owner;
if (!mutex_try_enter(&usb_mutex, &owner)) {
if (owner == get_core_num()) return -1; // would deadlock otherwise
......@@ -203,7 +215,12 @@ int SerialUSB::read() {
mutex_exit(&usb_mutex);
return -1;
}
int SerialUSB::available() {
if (!_running) {
return 0;
}
uint32_t owner;
if (!mutex_try_enter(&usb_mutex, &owner)) {
if (owner == get_core_num()) return 0; // would deadlock otherwise
......@@ -213,7 +230,12 @@ int SerialUSB::available() {
mutex_exit(&usb_mutex);
return ret;
}
int SerialUSB::availableForWrite() {
if (!_running) {
return 0;
}
uint32_t owner;
if (!mutex_try_enter(&usb_mutex, &owner)) {
if (owner == get_core_num()) return 0; // would deadlock otherwise
......@@ -223,7 +245,12 @@ int SerialUSB::availableForWrite() {
mutex_exit(&usb_mutex);
return ret;
}
void SerialUSB::flush() {
if (!_running) {
return;
}
uint32_t owner;
if (!mutex_try_enter(&usb_mutex, &owner)) {
if (owner == get_core_num()) return; // would deadlock otherwise
......@@ -232,10 +259,16 @@ void SerialUSB::flush() {
tud_cdc_write_flush();
mutex_exit(&usb_mutex);
}
size_t SerialUSB::write(uint8_t c) {
return write(&c, 1);
}
size_t SerialUSB::write(const uint8_t *buf, size_t length) {
if (!_running) {
return 0;
}
static uint64_t last_avail_time;
uint32_t owner;
if (!mutex_try_enter(&usb_mutex, &owner)) {
......@@ -270,7 +303,12 @@ size_t SerialUSB::write(const uint8_t *buf, size_t length) {
mutex_exit(&usb_mutex);
return i;
}
SerialUSB::operator bool() {
if (!_running) {
return false;
}
uint32_t owner;
if (!mutex_try_enter(&usb_mutex, &owner)) {
if (owner == get_core_num()) return -1; // would deadlock otherwise
......@@ -304,5 +342,11 @@ extern "C" void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_l
CheckSerialReset();
}
SerialUSB Serial;
void arduino::serialEventRun(void)
{
if (serialEvent && Serial.available()) {
serialEvent();
}
}
......@@ -72,4 +72,8 @@ private:
extern SerialUSB Serial;
namespace arduino {
extern void serialEventRun(void) __attribute__((weak));
};
#endif
......@@ -28,6 +28,15 @@ extern "C" int main() {
setup();
while (1) {
loop();
if (arduino::serialEventRun) {
arduino::serialEventRun();
}
if (arduino::serialEvent1Run) {
arduino::serialEvent1Run();
}
if (arduino::serialEvent2Run) {
arduino::serialEvent2Run();
}
}
return 0;
}
......
......@@ -22,10 +22,7 @@
#include <Arduino.h>
#include "EEPROM.h"
extern "C" {
// This header is missing the "ifdef cplusplus extern C" bit
#include <hardware/flash.h>
}
#include <hardware/sync.h>
extern "C" uint8_t _EEPROM_start;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment