| 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(); | ||||
| }; | }; |