EventResponder * waitForEvent(EventResponder *list, int listsize, int timeout); | EventResponder * waitForEvent(EventResponder *list, int listsize, int timeout); | ||||
static void runFromYield() { | static void runFromYield() { | ||||
if (!firstYield) return; | |||||
// First, check if yield was called from an interrupt | // First, check if yield was called from an interrupt | ||||
// never call normal handler functions from any interrupt context | // never call normal handler functions from any interrupt context | ||||
uint32_t ipsr; | uint32_t ipsr; |
void enableSerialEvents(); | void enableSerialEvents(); | ||||
void disableSerialEvents(); | void disableSerialEvents(); | ||||
static void processSerialEvents(); | static void processSerialEvents(); | ||||
static uint8_t serial_event_handlers_active; | |||||
using Print::write; | using Print::write; | ||||
// Only overwrite some of the virtualWrite functions if we are going to optimize them over Print version | // Only overwrite some of the virtualWrite functions if we are going to optimize them over Print version | ||||
#else | #else | ||||
static SerialEventCheckingFunctionPointer serial_event_handler_checks[7]; | static SerialEventCheckingFunctionPointer serial_event_handler_checks[7]; | ||||
#endif | #endif | ||||
static uint8_t serial_event_handlers_active; | |||||
#endif // __cplusplus | #endif // __cplusplus | ||||
// c functions to call c++ code in case some programs call the old functions | |||||
// Defined under extern "C" {} | |||||
#ifdef __cplusplus | |||||
extern "C" { | |||||
#endif | |||||
extern void serial_print(const char *p); | |||||
extern void serial_phex(uint32_t n); | |||||
extern void serial_phex16(uint32_t n); | |||||
extern void serial_phex32(uint32_t n); | |||||
#ifdef __cplusplus | |||||
} | |||||
#endif | |||||
// TODO: replace with proper divisor+oversample calculation | // TODO: replace with proper divisor+oversample calculation |
void serialEvent1() __attribute__((weak)); | void serialEvent1() __attribute__((weak)); | ||||
void serialEvent1() {Serial1.disableSerialEvents(); } // No use calling this so disable if called... | void serialEvent1() {Serial1.disableSerialEvents(); } // No use calling this so disable if called... | ||||
// C wrapper functions to help take care of places that used to call these from standard C | |||||
void serial_print(const char *p) | |||||
{ | |||||
Serial1.write(p); | |||||
} | |||||
static void serial_phex1(uint32_t n) | |||||
{ | |||||
n &= 15; | |||||
if (n < 10) { | |||||
Serial1.write('0' + n); | |||||
} else { | |||||
Serial1.write('A' - 10 + n); | |||||
} | |||||
} | |||||
void serial_phex(uint32_t n) | |||||
{ | |||||
serial_phex1(n >> 4); | |||||
serial_phex1(n); | |||||
} | |||||
void serial_phex16(uint32_t n) | |||||
{ | |||||
serial_phex(n >> 8); | |||||
serial_phex(n); | |||||
} | |||||
void serial_phex32(uint32_t n) | |||||
{ | |||||
serial_phex(n >> 24); | |||||
serial_phex(n >> 16); | |||||
serial_phex(n >> 8); | |||||
serial_phex(n); | |||||
} | |||||
tempmon_init(); | tempmon_init(); | ||||
while (millis() < 300) ; // wait at least 300ms before calling user code | while (millis() < 300) ; // wait at least 300ms before calling user code | ||||
printf("before C++ constructors\n"); | |||||
//printf("before C++ constructors\n"); | |||||
__libc_init_array(); | __libc_init_array(); | ||||
printf("after C++ constructors\n"); | |||||
printf("before setup\n"); | |||||
//printf("after C++ constructors\n"); | |||||
//printf("before setup\n"); | |||||
setup(); | setup(); | ||||
printf("after setup\n"); | |||||
//printf("after setup\n"); | |||||
while (1) { | while (1) { | ||||
//printf("loop\n"); | //printf("loop\n"); | ||||
loop(); | loop(); | ||||
yield(); | |||||
} | } | ||||
} | } | ||||
#endif | #endif | ||||
#endif // F_CPU | #endif // F_CPU | ||||
uint8_t usb_enable_serial_event_processing = 1; | |||||
void serialEvent() __attribute__((weak)); | void serialEvent() __attribute__((weak)); | ||||
void serialEvent() {} | |||||
void serialEvent() {usb_enable_serial_event_processing = 0;} |
// peek at the next character, or -1 if nothing received | // peek at the next character, or -1 if nothing received | ||||
int usb_serial_peekchar(void) | int usb_serial_peekchar(void) | ||||
{ | { | ||||
if (rx_index[0] < rx_count[0]) { | |||||
return rx_buffer[rx_index[0]]; | |||||
} | |||||
#if 0 | #if 0 | ||||
if (!rx_packet) { | if (!rx_packet) { | ||||
if (!usb_configuration) return -1; | if (!usb_configuration) return -1; | ||||
// read a block of bytes to a buffer | // read a block of bytes to a buffer | ||||
int usb_serial_read(void *buffer, uint32_t size) | int usb_serial_read(void *buffer, uint32_t size) | ||||
{ | { | ||||
#if 0 | |||||
#if 1 | |||||
// Quick and dirty to make it at least limp... | |||||
uint8_t *p = (uint8_t *)buffer; | |||||
uint32_t count=0; | |||||
while (size) { | |||||
int ch = usb_serial_getchar(); | |||||
if (ch == -1) break; | |||||
*p++ = (uint8_t)ch; | |||||
size--; | |||||
count++; | |||||
} | |||||
return count; | |||||
#else | |||||
uint8_t *p = (uint8_t *)buffer; | uint8_t *p = (uint8_t *)buffer; | ||||
uint32_t qty, count=0; | uint32_t qty, count=0; | ||||
extern volatile uint8_t usb_cdc_line_rtsdtr; | extern volatile uint8_t usb_cdc_line_rtsdtr; | ||||
extern volatile uint8_t usb_cdc_transmit_flush_timer; | extern volatile uint8_t usb_cdc_transmit_flush_timer; | ||||
extern volatile uint8_t usb_configuration; | extern volatile uint8_t usb_configuration; | ||||
extern uint8_t usb_enable_serial_event_processing; | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } | ||||
#endif | #endif |
if (running) return; // TODO: does this need to be atomic? | if (running) return; // TODO: does this need to be atomic? | ||||
running = 1; | running = 1; | ||||
// USB Serail - Add hack to minimize impact... | |||||
if (usb_enable_serial_event_processing && Serial.available()) serialEvent(); | |||||
// Current workaround until integrate with EventResponder. | // Current workaround until integrate with EventResponder. | ||||
HardwareSerial::processSerialEvents(); | |||||
if (HardwareSerial::serial_event_handlers_active) HardwareSerial::processSerialEvents(); | |||||
running = 0; | running = 0; | ||||
EventResponder::runFromYield(); | EventResponder::runFromYield(); | ||||
}; | }; |