### Get Available Bytes in UART0 Receive Buffer Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt This function calculates and returns the number of bytes currently available in the UART0 receive buffer. It uses the head and tail pointers of the circular buffer to determine how many bytes have been received and are ready to be read. This helps in checking for incoming data before attempting to read it. ```C int serial_available(void) { uint32_t head, tail; head = rx_buffer_head; tail = rx_buffer_tail; if (head >= tail) return head - tail; return SERIAL1_RX_BUFFER_SIZE + head - tail; } ``` -------------------------------- ### Get Free Space in UART0 Transmit Buffer Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt This function calculates and returns the amount of free space available in the UART0 transmit buffer. It uses the head and tail pointers of the circular buffer to determine the number of bytes that can still be written. This helps in managing buffer overflow and optimizing data transmission. ```C int serial_write_buffer_free(void) { uint32_t head, tail; head = tx_buffer_head; tail = tx_buffer_tail; if (head >= tail) return SERIAL1_TX_BUFFER_SIZE - 1 - head + tail; return tail - head - 1; } ``` -------------------------------- ### Initialize UART0 Serial Communication Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt The `serial_begin` function initializes UART0 for serial communication. It configures the baud rate, sets up the transmit and receive pins, enables necessary UART modules and interrupts, and resets the buffer pointers. ```C void serial_begin(uint32_t divisor) { SIM_SCGC4 |= SIM_SCGC4_UART0; // turn on clock, TODO: use bitband rx_buffer_head = 0; rx_buffer_tail = 0; tx_buffer_head = 0; tx_buffer_tail = 0; transmitting = 0; CORE_PIN0_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3); CORE_PIN1_CONFIG = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); #if defined(HAS_KINETISK_UART0) UART0_BDH = (divisor >> 13) & 0x1F; UART0_BDL = (divisor >> 5) & 0xFF; UART0_C4 = divisor & 0x1F; #ifdef HAS_KINETISK_UART0_FIFO UART0_C1 = UART_C1_ILT; UART0_TWFIFO = 2; // tx watermark, causes S1_TDRE to set UART0_RWFIFO = 4; // rx watermark, causes S1_RDRF to set UART0_PFIFO = UART_PFIFO_TXFE | UART_PFIFO_RXFE; #else UART0_C1 = 0; UART0_PFIFO = 0; #endif #elif defined(HAS_KINETISL_UART0) UART0_BDH = (divisor >> 8) & 0x1F; UART0_BDL = divisor & 0xFF; UART0_C1 = 0; #endif UART0_C2 = UART_C2_TE | UART_C2_RE | UART_C2_RIE | UART_C2_ILIE; NVIC_SET_PRIORITY(IRQ_UART0_STATUS, IRQ_PRIORITY); NVIC_ENABLE_IRQ(IRQ_UART0_STATUS); } ``` -------------------------------- ### USB Flight Sim Controls API Reference Source: https://github.com/paulstoffregen/cores/blob/master/keywords.txt API for interfacing with flight simulator controls over USB, providing methods for sending commands, integer/float data, and handling events. ```APIDOC Class: FlightSim Methods: FlightSimCommand() FlightSimInteger() FlightSimFloat() FlightSimElapsedFrames() FlightSimData() FlightSimEvent() onChange() update() isEnabled() getFrameCount() XPlaneRef() ``` -------------------------------- ### USB RawHID API Reference Source: https://github.com/paulstoffregen/cores/blob/master/keywords.txt API for sending and receiving raw HID (Human Interface Device) reports over USB, allowing for custom communication protocols. ```APIDOC Class: RawHID Methods: recv() send() ``` -------------------------------- ### Teensy 2.0 USB Keyboard System Key Constants Source: https://github.com/paulstoffregen/cores/blob/master/keywords.txt Provides constants for system control actions such as power down, sleep, and wake up, for use with the USB Keyboard HID. These allow the Teensy to send system-level commands. ```APIDOC KEY_SYSTEM_POWER_DOWN KEY_SYSTEM_SLEEP KEY_SYSTEM_WAKE_UP ``` -------------------------------- ### Print String to Serial Port (C) Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt This function sends a null-terminated string character by character to the serial port. It iterates through the input string `p`, converting newline characters (\n) to carriage return (\r) before passing them to the `serial_putchar` function for transmission. This ensures proper line endings for serial terminals. ```C void serial_print(const char *p) { while (*p) { char c = *p++; if (c == '\n') serial_putchar('\r'); serial_putchar(c); } } ``` -------------------------------- ### USB Mouse API Reference Source: https://github.com/paulstoffregen/cores/blob/master/keywords.txt API for controlling a USB Mouse device, including movement, button states, and screen size information. ```APIDOC Class: USB Mouse Methods: moveTo() screenSize() scroll() set_buttons() isPressed() Constants: MOUSE_LEFT MOUSE_MIDDLE MOUSE_RIGHT MOUSE_ALL MOUSE_BACK MOUSE_FORWARD ``` -------------------------------- ### USB Touchscreen API Reference Source: https://github.com/paulstoffregen/cores/blob/master/keywords.txt API for controlling a USB Touchscreen device. ```APIDOC Class: TouchscreenUSB ``` -------------------------------- ### USB MIDI API Reference Source: https://github.com/paulstoffregen/cores/blob/master/keywords.txt Comprehensive API for sending and receiving MIDI messages over USB, supporting various message types like notes, control changes, program changes, and system exclusive messages. ```APIDOC Class: usbMIDI Methods: sendNoteOff() sendNoteOn() sendAfterTouchPoly() sendPolyPressure() sendControlChange() sendProgramChange() sendAfterTouch() sendPitchBend() sendSysEx() sendRealTime() sendClock() sendStart() sendStop() sendTick() sendContinue() sendActiveSensing() sendSystemReset() sendTimeCodeQuarterFrame() sendSongPosition() sendSongSelect() sendTuneRequest() beginRpn() sendRpnValue() sendRpnIncrement() sendRpnDecrement() endRpn() beginNrpn() sendNrpnValue() sendNrpnIncrement() sendNrpnDecrement() endNrpn() send() analog2velocity() getType() getCable() getChannel() getData1() getData2() getSysExArray() setHandleNoteOff() setHandleNoteOn() setHandleVelocityChange() setHandleControlChange() setHandleProgramChange() setHandleAfterTouch() setHandlePitchChange() Constants: NoteOff NoteOn AfterTouchPoly ControlChange ProgramChange AfterTouchChannel PitchBend SystemExclusive TimeCodeQuarterFrame SongPosition SongSelect TuneRequest Clock Start Continue Stop ActiveSensing SystemReset midiEventPacket_t Class: MidiUSB Methods: sendMIDI() ``` -------------------------------- ### Configure UART0 Serial Communication Parameters Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt This code snippet configures various parameters for UART0, including data format (e.g., 8N2), RX/TX inversion, and enables 9-bit support if `SERIAL_9BIT_SUPPORT` is defined. It directly manipulates UART0 control registers (C3, S2, C4) to set up the serial interface characteristics. ```C if ((format & 0x0F) == 0x04) UART0_C3 |= 0x40; // 8N2 is 9 bit with 9th bit always 1 c = UART0_S2 & ~0x10; if (format & 0x10) c |= 0x10; // rx invert UART0_S2 = c; c = UART0_C3 & ~0x10; if (format & 0x20) c |= 0x10; // tx invert UART0_C3 = c; #ifdef SERIAL_9BIT_SUPPORT c = UART0_C4 & 0x1F; if (format & 0x08) c |= 0x20; // 9 bit mode with parity (requires 10 bits) UART0_C4 = c; use9Bits = format & 0x80; #endif } ``` -------------------------------- ### USB Joystick API Reference Source: https://github.com/paulstoffregen/cores/blob/master/keywords.txt API for controlling a USB Joystick device, providing methods for button states, axis positions (X, Y, Z, rotation), sliders, and hat switch. ```APIDOC Class: Joystick Methods: button() X() Y() position() Z() Xrotate() Yrotate() Zrotate() sliderLeft() sliderRight() slider() hat() useManualSend() ``` -------------------------------- ### USB Disk API Reference Source: https://github.com/paulstoffregen/cores/blob/master/keywords.txt API for managing a USB Disk device, including claiming, reading/writing sectors, and releasing read-only status. ```APIDOC Class: Disk Methods: claim() readSector() writeSector() releaseReadOnly() ``` -------------------------------- ### Teensy 2.0 USB Keyboard Standard Key Constants Source: https://github.com/paulstoffregen/cores/blob/master/keywords.txt Enumerates constants for standard alphanumeric, symbol, function, navigation, and keypad keys. These are used for sending key presses via the USB Keyboard HID, simulating a full keyboard. ```APIDOC KEY_A KEY_B KEY_C KEY_D KEY_E KEY_F KEY_G KEY_H KEY_I KEY_J KEY_K KEY_L KEY_M KEY_N KEY_O KEY_P KEY_Q KEY_R KEY_S KEY_T KEY_U KEY_V KEY_W KEY_X KEY_Y KEY_Z KEY_1 KEY_2 KEY_3 KEY_4 KEY_5 KEY_6 KEY_7 KEY_8 KEY_9 KEY_0 KEY_ENTER KEY_ESC KEY_BACKSPACE KEY_TAB KEY_SPACE KEY_MINUS KEY_EQUAL KEY_LEFT_BRACE KEY_RIGHT_BRACE KEY_BACKSLASH KEY_NON_US_NUM KEY_SEMICOLON KEY_QUOTE KEY_TILDE KEY_COMMA KEY_PERIOD KEY_SLASH KEY_CAPS_LOCK KEY_F1 KEY_F2 KEY_F3 KEY_F4 KEY_F5 KEY_F6 KEY_F7 KEY_F8 KEY_F9 KEY_F10 KEY_F11 KEY_F12 KEY_PRINTSCREEN KEY_SCROLL_LOCK KEY_PAUSE KEY_INSERT KEY_HOME KEY_PAGE_UP KEY_DELETE KEY_END KEY_PAGE_DOWN KEY_RIGHT KEY_LEFT KEY_DOWN KEY_UP KEY_NUM_LOCK KEYPAD_SLASH KEYPAD_ASTERIX KEYPAD_MINUS KEYPAD_PLUS KEYPAD_ENTER KEYPAD_1 KEYPAD_2 KEYPAD_3 KEYPAD_4 KEYPAD_5 KEYPAD_6 KEYPAD_7 KEYPAD_8 KEYPAD_9 KEYPAD_0 KEYPAD_PERIOD KEY_UP_ARROW KEY_DOWN_ARROW KEY_LEFT_ARROW KEY_RIGHT_ARROW KEY_RETURN KEY_LEFT_CTRL KEY_LEFT_SHIFT KEY_LEFT_ALT KEY_LEFT_GUI KEY_RIGHT_CTRL KEY_RIGHT_SHIFT KEY_RIGHT_ALT KEY_RIGHT_GUI ``` -------------------------------- ### Teensy 2.0 USB Keyboard Media Key Constants Source: https://github.com/paulstoffregen/cores/blob/master/keywords.txt Defines constants for common media control keys (volume, play/pause, track navigation, stop, eject, record, rewind, fast forward) for use with the USB Keyboard HID. These allow for controlling media playback from the Teensy. ```APIDOC KEY_MEDIA_VOLUME_INC KEY_MEDIA_VOLUME_DEC KEY_MEDIA_MUTE KEY_MEDIA_PLAY_PAUSE KEY_MEDIA_NEXT_TRACK KEY_MEDIA_PREV_TRACK KEY_MEDIA_STOP KEY_MEDIA_EJECT KEY_MEDIA_PLAY KEY_MEDIA_PAUSE KEY_MEDIA_RECORD KEY_MEDIA_REWIND KEY_MEDIA_FAST_FORWARD KEY_MEDIA_PLAY_SKIP ``` -------------------------------- ### Write Buffer to UART0 (Kinetis FIFO Enabled) Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt This function writes a buffer of data to UART0, optimized for Kinetis microcontrollers with hardware FIFO support (enabled by `HAS_KINETISK_UART0_FIFO`). It efficiently manages the transmit buffer, placing bytes into it and handling buffer full conditions by waiting for space. It ensures transmit interrupts are enabled to process the data. ```C #ifdef HAS_KINETISK_UART0_FIFO void serial_write(const void *buf, unsigned int count) { const uint8_t *p = (const uint8_t *)buf; const uint8_t *end = p + count; uint32_t head, n; if (!(SIM_SCGC4 & SIM_SCGC4_UART0)) return; if (transmit_pin) transmit_assert(); while (p < end) { head = tx_buffer_head; if (++head >= SERIAL1_TX_BUFFER_SIZE) head = 0; if (tx_buffer_tail == head) { UART0_C2 |= UART_C2_TIE; UART0_C2 &= ~UART_C2_TCIE; do { int priority = nvic_execution_priority(); if (priority <= IRQ_PRIORITY) { if ((UART0_S1 & UART_S1_TDRE)) { uint32_t tail = tx_buffer_tail; if (++tail >= SERIAL1_TX_BUFFER_SIZE) tail = 0; n = tx_buffer[tail]; if (use9Bits) UART0_C3 = (UART0_C3 & ~0x40) | ((n & 0x100) >> 2); UART0_D = n; tx_buffer_tail = tail; } } else if (priority >= 256) { yield(); } } while (tx_buffer_tail == head); } tx_buffer[head] = *p++; transmitting = 1; tx_buffer_head = head; } UART0_C2 |= UART_C2_TIE; UART0_C2 &= ~UART_C2_TCIE; } ``` -------------------------------- ### Define Tunable Serial Buffer Parameters Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt These preprocessor directives define the sizes for the transmit and receive buffers used by the serial communication module, along with the interrupt priority for UART operations. These values can be adjusted to optimize memory usage and performance. ```C #ifndef SERIAL1_TX_BUFFER_SIZE #define SERIAL1_TX_BUFFER_SIZE 64 // number of outgoing bytes to buffer #endif #ifndef SERIAL1_RX_BUFFER_SIZE #define SERIAL1_RX_BUFFER_SIZE 64 // number of incoming bytes to buffer #endif #define IRQ_PRIORITY 64 // 0 = highest priority, 255 = lowest ``` -------------------------------- ### Conditional Serial Buffer Type and Transmit Pin Macros Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt This section defines the buffer element type (BUFTYPE) based on whether 9-bit serial support is enabled. It also defines macros for asserting and deasserting the transmit pin, with implementations varying based on Kinetis K-series or L-series microcontrollers. ```C #ifdef SERIAL_9BIT_SUPPORT static uint8_t use9Bits = 0; #define BUFTYPE uint16_t #else #define BUFTYPE uint8_t #define use9Bits 0 #endif #if defined(KINETISK) static volatile uint8_t *transmit_pin=NULL; #define transmit_assert() *transmit_pin = 1 #define transmit_deassert() *transmit_pin = 0 #elif defined(KINETISL) static volatile uint8_t *transmit_pin=NULL; static uint8_t transmit_mask=0; #define transmit_assert() *(transmit_pin+4) = transmit_mask; #define transmit_deassert() *(transmit_pin+8) = transmit_mask; #endif ``` -------------------------------- ### Serial Hexadecimal Printing Utilities (C) Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt This set of utility functions provides methods for printing unsigned integer values in hexadecimal format to the serial port. `serial_phex1` prints a single hexadecimal digit, while `serial_phex`, `serial_phex16`, and `serial_phex32` print 8-bit, 16-bit, and 32-bit values respectively, by breaking them down into individual hexadecimal digits and using `serial_phex1`. ```C static void serial_phex1(uint32_t n) { n &= 15; if (n < 10) { serial_putchar('0' + n); } else { serial_putchar('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); } ``` -------------------------------- ### Configure UART0 Serial Data Format Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt The `serial_format` function allows dynamic configuration of UART0's data format. It sets the parity type and the number of data bits (8 or 9) for serial communication based on the provided format parameter. ```C void serial_format(uint32_t format) { uint8_t c; c = UART0_C1; c = (c & ~0x13) | (format & 0x03); // configure parity if (format & 0x04) c |= 0x10; // 9 bits (might include parity) UART0_C1 = c; } ``` -------------------------------- ### Write Buffer to UART0 (Non-FIFO) Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt This function writes a buffer of data to UART0 for microcontrollers without hardware FIFO support. It iterates through the input buffer, calling `serial_putchar` for each byte. This approach processes one byte at a time, which is simpler but potentially less efficient than FIFO-enabled versions. ```C #else void serial_write(const void *buf, unsigned int count) { const uint8_t *p = (const uint8_t *)buf; while (count-- > 0) serial_putchar(*p++); } ``` -------------------------------- ### Teensy 2.0 USB Keyboard HID Functions Source: https://github.com/paulstoffregen/cores/blob/master/keywords.txt Outlines the core functions for controlling the USB Keyboard Human Interface Device (HID) on Teensy 2.0. These functions allow for sending unicode characters, setting modifier keys, and sending up to six simultaneous key presses. ```APIDOC write_unicode set_modifier set_key1 set_key2 set_key3 set_key4 set_key5 set_key6 set_media ``` -------------------------------- ### Peek at Next Character in UART0 Receive Buffer Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt This function allows peeking at the next character in the UART0 receive buffer without removing it. It returns the character at the current tail position. If the buffer is empty, it returns -1. This is useful for checking the next byte without consuming it, allowing for conditional processing. ```C int serial_peek(void) { uint32_t head, tail; head = rx_buffer_head; tail = rx_buffer_tail; if (head == tail) return -1; } ``` -------------------------------- ### Declare Global Volatile Serial Buffer Variables Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt These global volatile variables manage the transmit and receive buffers, including their head and tail pointers. The size of the pointers (uint8_t or uint16_t) is conditionally determined by the buffer size to optimize memory usage. ```C static volatile BUFTYPE tx_buffer[SERIAL1_TX_BUFFER_SIZE]; static volatile BUFTYPE rx_buffer[SERIAL1_RX_BUFFER_SIZE]; static volatile uint8_t transmitting = 0; #if SERIAL1_TX_BUFFER_SIZE > 255 static volatile uint16_t tx_buffer_head = 0; static volatile uint16_t tx_buffer_tail = 0; #else static volatile uint8_t tx_buffer_head = 0; static volatile uint8_t tx_buffer_tail = 0; #endif #if SERIAL1_RX_BUFFER_SIZE > 255 static volatile uint16_t rx_buffer_head = 0; static volatile uint16_t rx_buffer_tail = 0; #else static volatile uint8_t rx_buffer_head = 0; static volatile uint8_t rx_buffer_tail = 0; #endif ``` -------------------------------- ### Teensy 2.0 USB Serial Communication API Source: https://github.com/paulstoffregen/cores/blob/master/keywords.txt Describes the functions and parameters available for managing USB serial communication on the Teensy 2.0. These keywords control aspects like data transmission, baud rate, stop bits, parity, and DTR/RTS flow control. ```APIDOC send_now baud stopbits paritytype numbits dtr rts ``` -------------------------------- ### Teensy 2.0 Digital Pin Names Source: https://github.com/paulstoffregen/cores/blob/master/keywords.txt Lists the digital pin names available on the Teensy 2.0 microcontroller, typically used for digital input/output operations. These identifiers map to physical pins on the device. ```APIDOC PIN_A0 PIN_A1 PIN_A2 PIN_A3 PIN_A4 PIN_A5 PIN_A6 PIN_A7 PIN_B0 PIN_B1 PIN_B2 PIN_B3 PIN_B4 PIN_B5 PIN_B6 PIN_B7 PIN_C0 PIN_C1 PIN_C2 PIN_C3 PIN_C4 PIN_C5 PIN_C6 PIN_C7 PIN_D0 PIN_D1 PIN_D2 PIN_D3 PIN_D4 PIN_D5 PIN_D6 PIN_D7 PIN_E0 PIN_E1 PIN_E2 PIN_E3 PIN_E4 PIN_E5 PIN_E6 PIN_E7 PIN_F0 PIN_F1 PIN_F2 PIN_F3 PIN_F4 PIN_F5 PIN_F6 PIN_F7 PIN_SS PIN_SCLK PIN_MOSI PIN_MISO PIN_LED ``` -------------------------------- ### Teensy 2.0 USB Keyboard Modifier Key Constants Source: https://github.com/paulstoffregen/cores/blob/master/keywords.txt Lists the constants used to represent various modifier keys (Ctrl, Shift, Alt, GUI) for both left and right sides. These constants are typically used with USB Keyboard HID functions to simulate modifier key presses. ```APIDOC MODIFIERKEY_CTRL MODIFIERKEY_SHIFT MODIFIERKEY_ALT MODIFIERKEY_GUI MODIFIERKEY_LEFT_CTRL MODIFIERKEY_LEFT_SHIFT MODIFIERKEY_LEFT_ALT MODIFIERKEY_LEFT_GUI MODIFIERKEY_RIGHT_CTRL MODIFIERKEY_RIGHT_SHIFT MODIFIERKEY_RIGHT_ALT MODIFIERKEY_RIGHT_GUI ``` -------------------------------- ### Teensy 2.0 Analog Pin Names and Functions Source: https://github.com/paulstoffregen/cores/blob/master/keywords.txt Defines the analog pin names and associated analog read functions for the Teensy 2.0 microcontroller. This includes single-ended analog inputs and differential input options with various gain settings. ```APIDOC ANALOG_0 (AnalogRead) ANALOG_1 (AnalogRead) ANALOG_2 (AnalogRead) ANALOG_3 (AnalogRead) ANALOG_4 (AnalogRead) ANALOG_5 (AnalogRead) ANALOG_6 (AnalogRead) ANALOG_7 (AnalogRead) ANALOG_1_TO_0_X10 (AnalogRead) ANALOG_1_TO_0_X200 (AnalogRead) ANALOG_3_TO_2_X10 (AnalogRead) ANALOG_3_TO_2_X200 (AnalogRead) ANALOG_0_TO_1 (AnalogRead) ANALOG_2_TO_1 (AnalogRead) ANALOG_3_TO_1 (AnalogRead) ANALOG_4_TO_1 (AnalogRead) ANALOG_5_TO_1 (AnalogRead) ANALOG_6_TO_1 (AnalogRead) ANALOG_7_TO_1 (AnalogRead) ANALOG_0_TO_2 (AnalogRead) ANALOG_1_TO_2 (AnalogRead) ANALOG_3_TO_2 (AnalogRead) ANALOG_4_TO_2 (AnalogRead) ANALOG_5_TO_2 (AnalogRead) ANALOG_1_1V (AnalogRead) ANALOG_0V (AnalogRead) ``` -------------------------------- ### UART0 Status Interrupt Service Routine (C) Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt This is the interrupt service routine for UART0, designed to handle various serial events such as receive data ready (RDRF), transmit data empty (TDRE), and transmit complete (TC). It manages both receive and transmit buffers, including specific handling for Kinetis FIFO (if `HAS_KINETISK_UART0_FIFO` is defined) and 9-bit data. The routine also addresses a known design challenge related to clearing the IDLE interrupt flag when using FIFO. ```C void uart0_status_isr(void) { uint32_t head, tail, n; uint8_t c; #ifdef HAS_KINETISK_UART0_FIFO uint32_t newhead; if (UART0_S1 & (UART_S1_RDRF | UART_S1_IDLE)) { if (UART0_RCFIFO == 0) { // The only way to clear the IDLE interrupt flag is // to read the data register. But reading with no // data causes a FIFO underrun, which causes the // FIFO to return corrupted data. If anyone from // Freescale reads this, what a poor design! There // write should be a write-1-to-clear for IDLE. c = UART0_D; // flushing the fifo recovers from the underrun, // but there's a possible race condition where a // new character could be received between reading // RCFIFO == 0 and flushing the FIFO. To minimize // the chance, interrupts are disabled so a higher // priority interrupt (hopefully) doesn't delay. // TODO: change this to disabling the IDLE interrupt // which won't be simple, since we already manage // which transmit interrupts are enabled. __disable_irq(); UART0_CFIFO = UART_CFIFO_RXFLUSH; __enable_irq(); } else { head = rx_buffer_head; tail = rx_buffer_tail; do { newhead = head + 1; if (newhead >= SERIAL1_RX_BUFFER_SIZE) newhead = 0; if (UART0_MODEM & UART_MODEM_RXRTSE) { if (newhead == tail) { UART0_C2 &= ~(UART_C2_RIE | UART_C2_ILIE);//disable rx interrupts break; } } if (UART0_RCFIFO==1) UART0_S1; //as per page 1214 of datasheet regarding resetting of RDRF flag if (use9Bits && (UART0_C3 & 0x80)) { n = UART0_D | 0x100; } else { n = UART0_D; } head = newhead; rx_buffer[head] = n; } while (UART0_RCFIFO); rx_buffer_head = head; } } c = UART0_C2; if ((c & UART_C2_TIE) && (UART0_S1 & UART_S1_TDRE)) { head = tx_buffer_head; tail = tx_buffer_tail; do { if (tail == head) break; if (++tail >= SERIAL1_TX_BUFFER_SIZE) tail = 0; UART0_S1; n = tx_buffer[tail]; if (use9Bits) UART0_C3 = (UART0_C3 & ~0x40) | ((n & 0x100) >> 2); UART0_D = n; } while (UART0_TCFIFO < 8); tx_buffer_tail = tail; if (UART0_S1 & UART_S1_TDRE) { UART0_C2 |= UART_C2_TCIE; UART0_C2 &= ~UART_C2_TIE; } } #else if (UART0_S1 & UART_S1_RDRF) { do { head = rx_buffer_head + 1; if (head >= SERIAL1_RX_BUFFER_SIZE) head = 0; if (UART0_MODEM & UART_MODEM_RXRTSE) { if (head == rx_buffer_tail) { UART0_C2 &= ~(UART_C2_RIE);//disable rx interrupts break; } } n = UART0_D; if (use9Bits && (UART0_C3 & 0x80)) n |= 0x100; rx_buffer[head] = n; rx_buffer_head = head; break; } while (true); } c = UART0_C2; if ((c & UART_C2_TIE) && (UART0_S1 & UART_S1_TDRE)) { head = tx_buffer_head; tail = tx_buffer_tail; if (head == tail) { UART0_C2 |= UART_C2_TCIE; UART0_C2 &= ~UART_C2_TIE; } else { if (++tail >= SERIAL1_TX_BUFFER_SIZE) tail = 0; n = tx_buffer[tail]; if (use9Bits) UART0_C3 = (UART0_C3 & ~0x40) | ((n & 0x100) >> 2); UART0_D = n; tx_buffer_tail = tail; } } #endif if ((c & UART_C2_TCIE) && (UART0_S1 & UART_S1_TC)) { transmitting = 0; if (transmit_pin) transmit_deassert(); UART0_C2 &= ~(UART_C2_TCIE | UART_C2_TIE); } } ``` -------------------------------- ### Clear Serial Receive Buffer and UART0 FIFO (C) Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt This function clears the software receive buffer by resetting its head and tail pointers. If the `HAS_KINETISK_UART0_FIFO` macro is defined, it also flushes the UART0 receive FIFO and temporarily disables/re-enables UART0 interrupts to ensure proper state and prevent race conditions during FIFO operations. ```C void serial_clear(void) { #ifdef HAS_KINETISK_UART0_FIFO if (!(SIM_SCGC4 & SIM_SCGC4_UART0)) return; UART0_C2 &= ~(UART_C2_RE | UART_C2_RIE | UART_C2_ILIE); UART0_CFIFO = UART_CFIFO_RXFLUSH; UART0_C2 |= (UART_C2_RE | UART_C2_RIE | UART_C2_ILIE); #endif rx_buffer_head = rx_buffer_tail; } ``` -------------------------------- ### Set Custom Transmit Pin for UART0 Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt This function allows configuring a custom digital pin to be used for UART0 transmission. It waits for any ongoing transmission to complete, sets the specified pin as an output, drives it low, and stores its port output register and bitmask for direct manipulation. This is useful for software-controlled transmit lines or alternative pin configurations. ```C void serial_set_transmit_pin(uint8_t pin) { while (transmitting) ; pinMode(pin, OUTPUT); digitalWrite(pin, LOW); transmit_pin = portOutputRegister(pin); #if defined(KINETISL) transmit_mask = digitalPinToBitMask(pin); #endif } ``` -------------------------------- ### Transmit Single Character via UART0 Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt This function transmits a single character `c` over UART0. It manages the transmit buffer, waiting if the buffer is full, and handles 9-bit mode if enabled. It sets the transmit interrupt enable bit (UART_C2_TIE) to initiate transmission and clears the transmit complete interrupt enable bit (UART_C2_TCIE). This function is blocking if the buffer is full. ```C void serial_putchar(uint32_t c) { uint32_t head, n; if (!(SIM_SCGC4 & SIM_SCGC4_UART0)) return; if (transmit_pin) transmit_assert(); head = tx_buffer_head; if (++head >= SERIAL1_TX_BUFFER_SIZE) head = 0; while (tx_buffer_tail == head) { int priority = nvic_execution_priority(); if (priority <= IRQ_PRIORITY) { if ((UART0_S1 & UART_S1_TDRE)) { uint32_t tail = tx_buffer_tail; if (++tail >= SERIAL1_TX_BUFFER_SIZE) tail = 0; n = tx_buffer[tail]; if (use9Bits) UART0_C3 = (UART0_C3 & ~0x40) | ((n & 0x100) >> 2); UART0_D = n; tx_buffer_tail = tail; } } else if (priority >= 256) { yield(); } } tx_buffer[head] = c; transmitting = 1; tx_buffer_head = head; UART0_C2 |= UART_C2_TIE; UART0_C2 &= ~UART_C2_TCIE; } ``` -------------------------------- ### Flush UART0 Transmit Buffer Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt This function waits until all data currently in the UART0 transmit buffer has been successfully sent. It continuously calls `yield()` to allow other tasks to run while polling the `transmitting` flag, ensuring that all outgoing data is transmitted before the function returns. ```C void serial_flush(void) { while (transmitting) yield(); // wait } ``` -------------------------------- ### Deinitialize UART0 Serial Communication Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt This function deinitializes the UART0 module, ensuring all buffered data is sent before proceeding. It disables the UART0 status interrupt, clears the UART0 control register (C2), and reconfigures the associated RX and TX pins (CORE_PIN0, CORE_PIN1) to a default state. It also resets the receive buffer pointers. ```C void serial_end(void) { if (!(SIM_SCGC4 & SIM_SCGC4_UART0)) return; while (transmitting) yield(); // wait for buffered data to send NVIC_DISABLE_IRQ(IRQ_UART0_STATUS); UART0_C2 = 0; CORE_PIN0_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); CORE_PIN1_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); rx_buffer_head = 0; rx_buffer_tail = 0; } ``` -------------------------------- ### Read Single Character from UART0 Receive Buffer Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt This function reads and returns a single character from the UART0 receive buffer. If the buffer is empty, it returns -1. It manages the receive buffer tail pointer and re-enables receive interrupts (UART_C2_RIE, UART_C2_ILIE) if enough free space becomes available, especially for FIFO-enabled UARTs, to ensure continuous reception. ```C int serial_getchar(void) { uint32_t head, tail; int c; head = rx_buffer_head; tail = rx_buffer_tail; if (head == tail) return -1; if (++tail >= SERIAL1_RX_BUFFER_SIZE) tail = 0; c = rx_buffer[tail]; rx_buffer_tail = tail; #ifdef HAS_KINETISK_UART0_FIFO if ((UART0_C2 & (UART_C2_RIE | UART_C2_ILIE))==0) {//rx interrupt currently disabled int freespace; if (head >= tail) //rx head and tail would be unchanged from above if interrupts were disabled freespace = SERIAL1_RX_BUFFER_SIZE -1 + tail - head; else freespace = tail - head - 1; if (freespace >= UART0_RCFIFO) { UART0_C2 |= (UART_C2_RIE | UART_C2_ILIE);//enable rx interrupts } } #else UART0_C2 |= UART_C2_RIE; #endif return c; } ``` -------------------------------- ### Configure UART0 CTS Pin for Hardware Flow Control Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt This function configures a specified pin to serve as the Clear-To-Send (CTS) signal for UART0 hardware flow control. It checks if the UART0 clock is enabled and validates the pin against supported CTS options (pin 18 or 20). If valid, it sets the pin's multiplexer configuration and enables the TXCTSE bit in the UART0_MODEM register. ```C int serial_set_cts(uint8_t pin) { if (!(SIM_SCGC4 & SIM_SCGC4_UART0)) return 0; if (pin == 18) { CORE_PIN18_CONFIG = PORT_PCR_MUX(3); // TODO: weak pullup or pulldown? } else if (pin == 20) { CORE_PIN20_CONFIG = PORT_PCR_MUX(3); // TODO: weak pullup or pulldown? } else { UART0_MODEM &= ~UART_MODEM_TXCTSE; return 0; } UART0_MODEM |= UART_MODEM_TXCTSE; return 1; } ``` -------------------------------- ### Configure UART0 RTS Pin for Hardware Flow Control Source: https://github.com/paulstoffregen/cores/blob/master/teensy3/serial1_doughboy.txt This function configures a specified pin to serve as the Request-To-Send (RTS) signal for UART0 hardware flow control. It checks if the UART0 clock is enabled and validates the pin against supported RTS options (pin 6 or 19). If valid, it sets the pin's multiplexer configuration and enables the RXRTSE bit in the UART0_MODEM register. ```C int serial_set_rts(uint8_t pin) { if (!(SIM_SCGC4 & SIM_SCGC4_UART0)) return 0; if (pin == 6) { CORE_PIN6_CONFIG = PORT_PCR_MUX(3); } else if (pin == 19) { CORE_PIN19_CONFIG = PORT_PCR_MUX(3); } else { UART0_MODEM &= ~UART_MODEM_RXRTSE; return 0; } UART0_MODEM |= UART_MODEM_RXRTSE; return 1; } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.