{"id":12042,"date":"2021-04-24T09:39:01","date_gmt":"2021-04-24T09:39:01","guid":{"rendered":"http:\/\/blog.bachi.net\/?p=12042"},"modified":"2021-08-20T14:38:28","modified_gmt":"2021-08-20T14:38:28","slug":"stm32duino-uart-serial","status":"publish","type":"post","link":"https:\/\/blog.bachi.net\/?p=12042","title":{"rendered":"STM32duino UART \/ Serial"},"content":{"rendered":"<p><a href=\"https:\/\/time4ee.com\/articles.php?article_id=85\">STM32duino III. &#8211; How to use Serial (USART)<\/a><\/p>\n<p><!-- ------------------------------------------------------------------------------------------------------- --><\/p>\n<hr\/>\n<h1>STM32duino Wiki<\/h1>\n<p><a href=\"https:\/\/github.com\/stm32duino\/wiki\/wiki\">Welcome to the stm32duino wiki!<\/a><br \/>\n<a href=\"https:\/\/github.com\/stm32duino\/wiki\/wiki\/API#hardwareserial\">API HardwareSerial<\/a><\/p>\n<p><!-- ------------------------------------------------------------------------------------------------------- --><\/p>\n<hr\/>\n<h1>PlatformIO<\/h1>\n<p><a href=\"https:\/\/community.platformio.org\/t\/how-to-use-stm32duino-build-opt-h-in-platformio\/13173\">How to use stm32duino build_opt.h in PlatformIO?<\/a><br \/>\n<a href=\"https:\/\/community.platformio.org\/t\/how-to-use-stm32duino-official-stm32-core-build-opt-h-in-platformio\/11078\">How to use stm32duino (official STM32 core) build_opt.h in PlatformIO<\/a><br \/>\n<a href=\"https:\/\/stackoverflow.com\/questions\/3387453\/include-header-files-using-command-line-option\/\">Include header files using command line option?<\/a><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nbuild_flags = \r\n    -DENABLE_HWSERIAL3\r\n    -DPIN_SERIAL3_RX=PB11\r\n    -DPIN_SERIAL3_TX=PB10\r\n\r\nor\r\n\r\nbuild_flags = \r\n     -include build_opt.h\r\n<\/pre>\n<p><!-- ------------------------------------------------------------------------------------------------------- --><\/p>\n<hr\/>\n<h1>Variant<\/h1>\n<pre class=\"brush: plain; title: .platformio\/packages\/framework-arduinoststm32\/variants\/NUCLEO_G071RB; notranslate\" title=\".platformio\/packages\/framework-arduinoststm32\/variants\/NUCLEO_G071RB\">\r\nldscript.ld\r\nPeripheralPins.c\r\nPinNamesVar.h\r\nvariant.cpp\r\nvariant.h\r\n<\/pre>\n<pre class=\"brush: cpp; title: variant.h; notranslate\" title=\"variant.h\">\r\n#define PC5  0\r\n#define PC4  1\r\n#define PA10 2\r\n&#x5B;...]\r\n<\/pre>\n<pre class=\"brush: cpp; title: PeripheralPins.c; notranslate\" title=\"PeripheralPins.c\">\r\nHAL_ADC_MODULE_ENABLED\r\nHAL_DAC_MODULE_ENABLED\r\nHAL_I2C_MODULE_ENABLED\r\nHAL_TIM_MODULE_ENABLED\r\nHAL_UART_MODULE_ENABLED\r\nHAL_SPI_MODULE_ENABLED\r\n<\/pre>\n<pre class=\"brush: cpp; title: PeripheralPins.c; notranslate\" title=\"PeripheralPins.c\">\r\nWEAK const PinMap PinMap_UART_TX&#x5B;] = {\r\n  &#x5B;...]\r\n  {PA_5,  USART3,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_USART3)},\r\n  {PB_2,  USART3,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF4_USART3)},\r\n  &#x5B;...]\r\n                                    ^                 ^\r\n                                    |                 |\r\n                          STM_MODE_INPUT           GPIO_NOPULL\r\n                          STM_MODE_OUTPUT_PP       GPIO_PULLUP\r\n                          STM_MODE_OUTPUT_OD       GPIO_PULLDOWN\r\n                          STM_MODE_ANALOG\r\n                          STM_MODE_AF_OD =&gt; Alternate Function, Open-Drain\r\n                          STM_MODE_AF_PP =&gt; Alternate Function, Push-Pull\r\n<\/pre>\n<pre class=\"brush: cpp; title: .platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/stm32\/PinNamesTypes.h; notranslate\" title=\".platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/stm32\/PinNamesTypes.h\">\r\n#define STM_PIN_DATA(FUNC_OD, PUPD, AFNUM) \\\r\n            STM_PIN_DEFINE(FUNC_OD, PUPD, AFNUM)\r\n#define STM_PIN_DATA_EXT(FUNC_OD, PUPD, AFNUM, CHANNEL, INVERTED) \\\r\n            STM_PIN_DEFINE_EXT(FUNC_OD, PUPD, AFNUM, CHANNEL, INVERTED)\r\n<\/pre>\n<p><!-- ------------------------------------------------------------------------------------------------------- --><\/p>\n<hr\/>\n<h1>Digital<\/h1>\n<p><a href=\"https:\/\/www.programmersought.com\/article\/42635087817\/\">Arduino_Core_STM32&#8212;pinMode() implementation analysis<\/a><\/p>\n<pre class=\"brush: cpp; title: .platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/wiring_digital.c; notranslate\" title=\".platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/wiring_digital.c\">\r\nvoid pinMode(uint32_t ulPin, uint32_t ulMode)\r\n{\r\n  PinName p = digitalPinToPinName(ulPin);\r\n\r\n  if (p != NC) {\r\n    &#x5B;...]\r\n    switch (ulMode) {\r\n      case INPUT: \/* INPUT_FLOATING *\/\r\n        pin_function(p, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));\r\n        break;\r\n      case INPUT_PULLUP:\r\n        pin_function(p, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLUP, 0));\r\n        break;\r\n      case INPUT_PULLDOWN:\r\n        pin_function(p, STM_PIN_DATA(STM_MODE_INPUT, GPIO_PULLDOWN, 0));\r\n        break;\r\n\r\n      &#x5B;...]\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p><!-- ------------------------------------------------------------------------------------------------------- --><\/p>\n<hr\/>\n<h1>PinMap_UART_TX<\/h1>\n<pre class=\"brush: cpp; title: .platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/stm32\/pinmap.h; notranslate\" title=\".platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/stm32\/pinmap.h\">\r\ntypedef struct {\r\n  PinName pin;\r\n  void *peripheral;\r\n  int function;\r\n} PinMap;\r\n<\/pre>\n<pre class=\"brush: cpp; title: .platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/stm32\/PinNames.h; notranslate\" title=\".platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/stm32\/PinNames.h\">\r\ntypedef enum {\r\n  \/\/ Not connected\r\n  NC = (int)0xFFFFFFFF,\r\n\r\n  \/\/ Pin name definition\r\n  PA_0  = (PortA &lt;&lt; 4) + 0x00,\r\n  &#x5B;...]\r\n\r\n  \/\/ Specific pin name define in the variant\r\n  #include &quot;PinNamesVar.h&quot;\r\n\r\n  P_END = NC\r\n} PinName;\r\n<\/pre>\n<pre class=\"brush: cpp; title: .platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/stm32\/PortNames.h; notranslate\" title=\".platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/stm32\/PortNames.h\">\r\nextern GPIO_TypeDef *GPIOPort&#x5B;];\r\n\r\ntypedef enum {\r\n  FirstPort = 0x00,\r\n  PortA = FirstPort,\r\n  PortB,\r\n#if defined GPIOC_BASE\r\n  PortC,\r\n#endif\r\n  &#x5B;...]\r\n  PortEND,\r\n  LastPort = PortEND - 1\r\n} PortName;\r\n\r\n#define MAX_NB_PORT (LastPort-FirstPort+1)\r\n<\/pre>\n<pre class=\"brush: cpp; title: .platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/pins_arduino.h; notranslate\" title=\".platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/pins_arduino.h\">\r\nextern const PinName digitalPin&#x5B;];\r\nextern const uint32_t analogInputPin&#x5B;];\r\n\r\n&#x5B;...]\r\n\r\n#define digitalPinToPinName(p)      (((uint32_t)p &lt; NUM_DIGITAL_PINS) ? digitalPin&#x5B;p] : \\\r\n            ((uint32_t)p &gt;= NUM_ANALOG_FIRST) &amp;&amp; ((uint32_t)p &lt;= NUM_ANALOG_LAST) ? \\\r\n            digitalPin&#x5B;analogInputPin&#x5B;p-NUM_ANALOG_FIRST]] : NC)\r\n<\/pre>\n<ul>\n<li><code>STM_PIN_DATA()<\/code><\/li>\n<li><code>STM_PIN_DATA_EXT()<\/code><\/li>\n<li><code>pin_in_pinmap()<\/code><br \/><code>bool pin_in_pinmap(PinName pin, const PinMap *map)<\/code><br \/>Loop<\/li>\n<li><code>pinmap_peripheral()<\/code><br \/><code>void *pinmap_peripheral(PinName pin, const PinMap *map)<\/code><\/li>\n<li><code>pinmap_pinout()<\/code><br \/><code>void pinmap_pinout(PinName pin, const PinMap *map)<\/code><\/li>\n<li><code>pinmap_pin()<\/code><br \/><code>PinName pinmap_pin(void *peripheral, const PinMap *map)<\/code><\/li>\n<\/ul>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n.\/cores\/arduino\/pins_arduino.h:           pin_in_pinmap(digitalPinToPinName(p), PinMap_UART_TX))\r\n.\/cores\/arduino\/stm32\/PeripheralPins.h:   extern const PinMap PinMap_UART_TX&#x5B;];\r\n.\/libraries\/SrcWrapper\/src\/stm32\/uart.c:  #define DEBUG_UART          pinmap_peripheral(digitalPinToPinName(PIN_SERIAL_TX), PinMap_UART_TX)\r\n.\/libraries\/SrcWrapper\/src\/stm32\/uart.c:  USART_TypeDef *uart_tx = pinmap_peripheral(obj-&gt;pin_tx, PinMap_UART_TX);\r\n.\/libraries\/SrcWrapper\/src\/stm32\/uart.c:  pinmap_pinout(obj-&gt;pin_tx, PinMap_UART_TX);\r\n.\/libraries\/SrcWrapper\/src\/stm32\/uart.c:  serial_debug.pin_tx = pinmap_pin(DEBUG_UART, PinMap_UART_TX);\r\n<\/pre>\n<p><!-- ------------------------------------------------------------------------------------------------------- --><\/p>\n<hr\/>\n<h1>Serial3<\/h1>\n<ul>\n<li><code>HAVE_HWSERIAL3<\/code><\/li>\n<li><code>ENABLE_HWSERIAL3<\/code><\/li>\n<li><code>SERIAL_UART_INSTANCE<\/code><\/li>\n<\/ul>\n<pre class=\"brush: cpp; title: .platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/HardwareSerial.h; notranslate\" title=\".platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/HardwareSerial.h\">\r\n&#x5B;...]\r\nextern HardwareSerial Serial3;\r\nextern HardwareSerial Serial4;\r\n&#x5B;...]\r\n<\/pre>\n<pre class=\"brush: cpp; title: .platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/HardwareSerial.cpp; notranslate\" title=\".platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/HardwareSerial.cpp\">\r\n  &#x5B;...]\r\n  #if defined(HAVE_HWSERIAL3)\r\n    HardwareSerial Serial3(USART3);\r\n    void serialEvent3() __attribute__((weak));\r\n  #endif\r\n\r\n  #if defined(HAVE_HWSERIAL4)\r\n    #if defined(USART4)\r\n      HardwareSerial Serial4(USART4);\r\n    #else\r\n      HardwareSerial Serial4(UART4);\r\n    #endif\r\n    void serialEvent4() __attribute__((weak));\r\n  #endif\r\n\r\n  &#x5B;...]\r\n\r\n\/\/ Constructors \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\/* ex. PA0 from #define in variant.h *\/\r\nHardwareSerial::HardwareSerial(uint32_t _rx, uint32_t _tx)\r\n{\r\n  init(digitalPinToPinName(_rx), digitalPinToPinName(_tx));\r\n}\r\n\r\n\/* ex. PA_0 from enum PinName in PinNames.h*\/\r\nHardwareSerial::HardwareSerial(PinName _rx, PinName _tx)\r\n{\r\n  init(_rx, _tx);\r\n}\r\n\r\n\/* ex. peripheral Serial2 (stm32g071xx.h: USART2 =&gt; USART2_BASE =&gt; 0x40004400) *\/\r\nHardwareSerial::HardwareSerial(void *peripheral, HalfDuplexMode_t halfDuplex)\r\n{\r\n  &#x5B;...]\r\n\r\n  \/* if pins are defined (variant.h or compiler flag -D), use them, otherwise use from PinMap *\/\r\n\r\n#if defined(Serial) &amp;&amp; defined(PIN_SERIAL_TX)\r\n  if ((void *)this == (void *)&amp;Serial) {\r\n#if defined(PIN_SERIAL_RX)\r\n    setRx(PIN_SERIAL_RX);\r\n#endif\r\n    setTx(PIN_SERIAL_TX);\r\n  } else\r\n#endif\r\n\r\n  &#x5B;...]\r\n\r\n#if defined(PIN_SERIAL3_TX) &amp;&amp; defined(USART3_BASE)\r\n        if (peripheral == USART3) {\r\n#if defined(PIN_SERIAL3_RX)\r\n          setRx(PIN_SERIAL3_RX);\r\n#endif\r\n          setTx(PIN_SERIAL3_TX);\r\n        } else\r\n#endif\r\n\r\n  &#x5B;...]\r\n\r\n                          \/\/ else get the pins of the first peripheral occurence in PinMap\r\n                        {\r\n                          _serial.pin_rx = pinmap_pin(peripheral, PinMap_UART_RX);\r\n                          _serial.pin_tx = pinmap_pin(peripheral, PinMap_UART_TX);\r\n                        }\r\n\r\n  &#x5B;...]\r\n}\r\n\r\n&#x5B;...]\r\n\r\nvoid HardwareSerial::init(PinName _rx, PinName _tx)\r\n{\r\n  &#x5B;...]\r\n}\r\n<\/pre>\n<pre class=\"brush: cpp; title: .platformio\/packages\/framework-arduinoststm32\/system\/Drivers\/CMSIS\/Device\/ST\/STM32G0xx\/Include\/stm32g071xx.h; notranslate\" title=\".platformio\/packages\/framework-arduinoststm32\/system\/Drivers\/CMSIS\/Device\/ST\/STM32G0xx\/Include\/stm32g071xx.h\">\r\n\/*!&lt; Peripheral declaration *\/\r\n#define USART2              ((USART_TypeDef *) USART2_BASE)\r\n#define USART3              ((USART_TypeDef *) USART3_BASE)\r\n#define USART4              ((USART_TypeDef *) USART4_BASE)\r\n&#x5B;...]\r\n#define LPUART1             ((USART_TypeDef *) LPUART1_BASE)\r\n\r\n&#x5B;...]\r\n\r\n\/*!&lt; APB peripherals *\/\r\n#define USART2_BASE           (APBPERIPH_BASE + 0x00004400UL)\r\n#define USART3_BASE           (APBPERIPH_BASE + 0x00004800UL)\r\n#define USART4_BASE           (APBPERIPH_BASE + 0x00004C00UL)\r\n&#x5B;...]\r\n#define LPUART1_BASE          (APBPERIPH_BASE + 0x00008000UL)\r\n<\/pre>\n<pre class=\"brush: cpp; title: .platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/WSerial.h; notranslate\" title=\".platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/WSerial.h\">\r\n  &#x5B;...]\r\n  #if defined(ENABLE_HWSERIAL3)\r\n    #if defined(USART3_BASE)\r\n      #define HAVE_HWSERIAL3\r\n    #endif\r\n  #endif\r\n  #if defined(ENABLE_HWSERIAL4)\r\n    #if defined(USART4_BASE) || defined(UART4_BASE)\r\n      #define HAVE_HWSERIAL4\r\n    #endif\r\n  #endif\r\n  &#x5B;...]\r\n<\/pre>\n<pre class=\"brush: cpp; title: .platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/WSerial.cpp; notranslate\" title=\".platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/WSerial.cpp\">\r\nWEAK void serialEventRun(void)\r\n{\r\n  &#x5B;...]\r\n#if defined(HAVE_HWSERIAL3)\r\n  if (serialEvent3 &amp;&amp; Serial3.available()) {\r\n    serialEvent3();\r\n  }\r\n#endif\r\n#if defined(HAVE_HWSERIAL4)\r\n  if (serialEvent4 &amp;&amp; Serial4.available()) {\r\n    serialEvent4();\r\n  }\r\n#endif\r\n  &#x5B;...]\r\n}\r\n<\/pre>\n<div><a href=\"http:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial_pinmap.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial_pinmap-1024x130.png\" alt=\"\" width=\"625\" height=\"79\" class=\"alignleft size-large wp-image-12489\" srcset=\"https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial_pinmap-1024x130.png 1024w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial_pinmap-300x38.png 300w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial_pinmap-768x97.png 768w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial_pinmap-624x79.png 624w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial_pinmap.png 1333w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><\/a><\/div>\n<div><a href=\"http:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial2-1024x290.png\" alt=\"\" width=\"625\" height=\"177\" class=\"alignleft size-large wp-image-12486\" srcset=\"https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial2-1024x290.png 1024w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial2-300x85.png 300w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial2-768x218.png 768w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial2-1536x435.png 1536w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial2-624x177.png 624w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial2.png 1831w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><\/a><\/div>\n<div><a href=\"http:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial3.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial3-1024x274.png\" alt=\"\" width=\"625\" height=\"167\" class=\"alignleft size-large wp-image-12487\" srcset=\"https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial3-1024x274.png 1024w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial3-300x80.png 300w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial3-768x206.png 768w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial3-1536x412.png 1536w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial3-624x167.png 624w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/Serial3.png 1828w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><\/a><\/div>\n<div><a href=\"http:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/SerialLP1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/SerialLP1-1024x276.png\" alt=\"\" width=\"625\" height=\"168\" class=\"alignleft size-large wp-image-12488\" srcset=\"https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/SerialLP1-1024x276.png 1024w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/SerialLP1-300x81.png 300w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/SerialLP1-768x207.png 768w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/SerialLP1-1536x413.png 1536w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/SerialLP1-624x168.png 624w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/SerialLP1.png 1821w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><\/a><\/div>\n<p><!-- ------------------------------------------------------------------------------------------------------- --><\/p>\n<hr\/>\n<h1>Callstack<\/h1>\n<div><a href=\"http:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/HardwareSerial_write2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/HardwareSerial_write2-1024x207.png\" alt=\"\" width=\"625\" height=\"126\" class=\"alignleft size-large wp-image-12082\" srcset=\"https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/HardwareSerial_write2-1024x207.png 1024w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/HardwareSerial_write2-300x61.png 300w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/HardwareSerial_write2-768x155.png 768w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/HardwareSerial_write2-1536x310.png 1536w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/HardwareSerial_write2-624x126.png 624w, https:\/\/blog.bachi.net\/wp-content\/uploads\/2021\/04\/HardwareSerial_write2.png 1925w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><\/a><\/div>\n<pre class=\"brush: cpp; title: .platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/HardwareSerial.cpp; notranslate\" title=\".platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/HardwareSerial.cpp\">\r\nsize_t HardwareSerial::write(uint8_t c)\r\n{\r\n  &#x5B;...]\r\n\r\n  if (!serial_tx_active(&amp;_serial)) {\r\n    uart_attach_tx_callback(&amp;_serial, _tx_complete_irq);\r\n  }\r\n\r\n  &#x5B;...]\r\n}\r\n\r\nint HardwareSerial::_tx_complete_irq(serial_t *obj)\r\n{\r\n  \/\/ If interrupts are enabled, there must be more data in the output\r\n  \/\/ buffer. Send the next byte\r\n  obj-&gt;tx_tail = (obj-&gt;tx_tail + 1) % SERIAL_TX_BUFFER_SIZE;\r\n\r\n  if (obj-&gt;tx_head == obj-&gt;tx_tail) {\r\n    return -1;\r\n  }\r\n\r\n  return 0;\r\n}\r\n<\/pre>\n<pre class=\"brush: cpp; title: .platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/stm32\/uart.h; notranslate\" title=\".platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/stm32\/uart.h\">\r\ntypedef struct serial_s serial_t;\r\n\r\nstruct serial_s {\r\n  \/*  The 1st 2 members USART_TypeDef *uart\r\n   *  and UART_HandleTypeDef handle should\r\n   *  be kept as the first members of this struct\r\n   *  to have get_serial_obj() function work as expected\r\n   *\/\r\n  USART_TypeDef *uart;\r\n  UART_HandleTypeDef handle;\r\n  void (*rx_callback)(serial_t *);\r\n  int (*tx_callback)(serial_t *);\r\n  PinName pin_tx;\r\n  PinName pin_rx;\r\n  IRQn_Type irq;\r\n  uint8_t index;\r\n  uint8_t recv;\r\n  uint8_t *rx_buff;\r\n  uint8_t *tx_buff;\r\n  uint16_t rx_tail;\r\n  uint16_t tx_head;\r\n  volatile uint16_t rx_head;\r\n  volatile uint16_t tx_tail;\r\n};\r\n<\/pre>\n<pre class=\"brush: cpp; title: .platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/stm32\/uart.h; notranslate\" title=\".platformio\/packages\/framework-arduinoststm32\/cores\/arduino\/stm32\/uart.h\">\r\n\/**\r\n * Begin asynchronous TX transfer.\r\n *\r\n * @param obj : pointer to serial_t structure\r\n * @param callback : function call at the end of transmission\r\n * @retval none\r\n *\/\r\nvoid uart_attach_tx_callback(serial_t *obj, int (*callback)(serial_t *))\r\n{\r\n  if (obj == NULL) {\r\n    return;\r\n  }\r\n  obj-&gt;tx_callback = callback;\r\n\r\n  \/* Must disable interrupt to prevent handle lock contention *\/\r\n  HAL_NVIC_DisableIRQ(obj-&gt;irq);\r\n\r\n  \/* The following function will enable UART_IT_TXE and error interrupts *\/\r\n  HAL_UART_Transmit_IT(uart_handlers&#x5B;obj-&gt;index], &amp;obj-&gt;tx_buff&#x5B;obj-&gt;tx_tail], 1);\r\n\r\n  \/* Enable interrupt *\/\r\n  HAL_NVIC_SetPriority(obj-&gt;irq, UART_IRQ_PRIO, UART_IRQ_SUBPRIO);\r\n  HAL_NVIC_EnableIRQ(obj-&gt;irq);\r\n}\r\n\r\n\/**\r\n  * @brief  Tx Transfer completed callback\r\n  * @param  UartHandle pointer on the uart reference\r\n  * @retval None\r\n  *\/\r\nvoid HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)\r\n{\r\n  serial_t *obj = get_serial_obj(huart);\r\n\r\n  if (obj &amp;&amp; obj-&gt;tx_callback(obj) != -1) {\r\n    if (HAL_UART_Transmit_IT(huart, &amp;obj-&gt;tx_buff&#x5B;obj-&gt;tx_tail], 1) != HAL_OK) {\r\n      return;\r\n    }\r\n  }\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>STM32duino III. &#8211; How to use Serial (USART) STM32duino Wiki Welcome to the stm32duino wiki! API HardwareSerial PlatformIO How to use stm32duino build_opt.h in PlatformIO? How to use stm32duino (official STM32 core) build_opt.h in PlatformIO Include header files using command line option? build_flags = -DENABLE_HWSERIAL3 -DPIN_SERIAL3_RX=PB11 -DPIN_SERIAL3_TX=PB10 or build_flags = -include build_opt.h Variant ldscript.ld PeripheralPins.c [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-12042","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/posts\/12042","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=12042"}],"version-history":[{"count":26,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/posts\/12042\/revisions"}],"predecessor-version":[{"id":12490,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/posts\/12042\/revisions\/12490"}],"wp:attachment":[{"href":"https:\/\/blog.bachi.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=12042"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=12042"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=12042"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}