Commit 5e438bab2b1044c7ec70dfb80cfbf7523c91ab5e

Authored by Antonio Carlos Domínguez Brito
1 parent 8caf1e15
Exists in master

New version 2.0: the internals of the library have been simplified in order to m…

…ake it faster. Main changes:
- The TC used now is programmed with a period half the bit time. This avoids the use of RA interrupts, simplifying and shortening TC interrupt handler's code.
- The synchronization has been also simplifyed, in order to solve a synchronization bug, avoiding in this cases error when receiving characters.
- All examples have been tested and the library behaves correctly.
README.md
1   -## soft_uart v1.1
  1 +## soft_uart v2.0
2 2  
3 3 This is soft_uart library for the Arduino DUE electronic prototyping platform.
4 4  
... ...
examples/soft_uart_serial_test/soft_uart_serial_test.ino
... ... @@ -40,7 +40,7 @@ using namespace arduino_due;
40 40  
41 41 #define RX_PIN 10 // software serial port's reception pin
42 42 #define TX_PIN 11 // software serial port's transmision pin
43   -#define SOFT_UART_BIT_RATE 57600 // 57600 38400 1200 19200 9600 115200 300
  43 +#define SOFT_UART_BIT_RATE 115200 // 57600 38400 1200 19200 9600 115200 300
44 44 #define RX_BUF_LENGTH 256 // software serial port's reception buffer length
45 45 #define TX_BUF_LENGTH 256 // software serial port's transmision buffer length
46 46 #define RECEPTION_TIMEOUT 100 // milliseconds
... ... @@ -106,14 +106,16 @@ void setup() {
106 106 SOFT_UART_BIT_RATE,
107 107 soft_uart::data_bit_codes::EIGHT_BITS,
108 108 soft_uart::parity_codes::EVEN_PARITY,
109   - soft_uart::stop_bit_codes::ONE_STOP_BIT
  109 + //soft_uart::stop_bit_codes::ONE_STOP_BIT
  110 + soft_uart::stop_bit_codes::TWO_STOP_BITS
110 111 );
111 112  
112 113 // Serial2's initialization
113 114 // we will communicate serial_obj to Serial2 to test the library,
114 115 // so we have to config Serial2 in the same way that serial_obj,
115 116 // same bit rate, parity and stop bits
116   - Serial2.begin(SOFT_UART_BIT_RATE,SERIAL_8E1);
  117 + //Serial2.begin(SOFT_UART_BIT_RATE,SERIAL_8E1);
  118 + Serial2.begin(SOFT_UART_BIT_RATE,SERIAL_8E2);
117 119 while(Serial2.available()) { Serial2.read(); }
118 120  
119 121 Serial.println("========================================================");
... ...
examples/soft_uart_serial_test_auto/soft_uart_serial_test_auto.ino
... ... @@ -128,7 +128,7 @@ void loop() {
128 128 // IMPORTANT: for sending 9-bit values you should send each value separately
129 129 // using function write(uint32_t). Using functions print or println, or alike
130 130 // function will truncate each data to be send to 8 bits.
131   - serial_obj.write(counter);
  131 + if(!serial_obj.write(counter)) Serial.println(" [sending unsuccessful]");;
132 132  
133 133 unsigned long timeout=
134 134 static_cast<unsigned long>(2*1000*serial_obj.get_frame_time());
... ...
examples/soft_uart_serial_test_half_duplex/soft_uart_serial_test_half_duplex.ino
... ... @@ -77,16 +77,16 @@ void receive_tc(serial_tc_t&amp; serial_tc, unsigned long timeout) \
77 77 { last_time=millis(); Serial.print(static_cast<char>(data)); } \
78 78 else \
79 79 { \
80   - if(serial_tc.bad_status()) \
81   - { \
82   - last_time=millis(); \
83   - Serial.print("||"); \
84   - if(serial_tc.bad_start_bit()) Serial.print("[BAD_START_BIT]"); \
85   - if(serial_tc.bad_parity()) Serial.print("[BAD_PARITY]"); \
86   - if(serial_tc.bad_stop_bit()) Serial.print("[BAD_STOP_BIT]"); \
87   - Serial.print((serial_tc.get_last_data_status()>>16),BIN); \
88   - Serial.print("||"); \
89   - } \
  80 + if(serial_tc.bad_status()) \
  81 + { \
  82 + last_time=millis(); \
  83 + Serial.print("["); \
  84 + if(serial_tc.bad_start_bit()) Serial.print("BAD_START_BIT,"); \
  85 + if(serial_tc.bad_parity()) Serial.print("BAD_PARITY,"); \
  86 + if(serial_tc.bad_stop_bit()) Serial.print("BAD_STOP_BIT,"); \
  87 + Serial.print((serial_tc.get_last_data_status()>>16),BIN); \
  88 + Serial.print("]"); \
  89 + } \
90 90 } \
91 91 } \
92 92 } \
... ...
examples/soft_uart_serial_test_half_duplex_9O2/soft_uart_serial_test_half_duplex_9O2.ino
... ... @@ -78,16 +78,16 @@ void receive_tc(serial_tc_t&amp; serial_tc, unsigned long timeout) \
78 78 { last_time=millis(); Serial.print(data,DEC); } \
79 79 else \
80 80 { \
81   - if(serial_tc.bad_status()) \
82   - { \
83   - last_time=millis(); \
84   - Serial.print("||"); \
85   - if(serial_tc.bad_start_bit()) Serial.print("[BAD_START_BIT]"); \
86   - if(serial_tc.bad_parity()) Serial.print("[BAD_PARITY]"); \
87   - if(serial_tc.bad_stop_bit()) Serial.print("[BAD_STOP_BIT]"); \
88   - Serial.print((serial_tc.get_last_data_status()>>16),BIN); \
89   - Serial.print("||"); \
90   - } \
  81 + if(serial_tc.bad_status()) \
  82 + { \
  83 + last_time=millis(); \
  84 + Serial.print("||"); \
  85 + if(serial_tc.bad_start_bit()) Serial.print("[BAD_START_BIT]"); \
  86 + if(serial_tc.bad_parity()) Serial.print("[BAD_PARITY]"); \
  87 + if(serial_tc.bad_stop_bit()) Serial.print("[BAD_STOP_BIT]"); \
  88 + Serial.print((serial_tc.get_last_data_status()>>16),BIN); \
  89 + Serial.print("||"); \
  90 + } \
91 91 } \
92 92 } \
93 93 } \
... ...
examples/soft_uart_serial_test_half_duplex_char/soft_uart_serial_test_half_duplex_char.ino
... ... @@ -38,7 +38,7 @@ using namespace arduino_due;
38 38  
39 39 #define SERIAL_TC0_PIN 10 // TC0 software serial port's half duplex pin
40 40 #define SERIAL_TC1_PIN 11 // TC1 software serial port's half duplex pin
41   -#define SOFT_UART_BIT_RATE 57600 // 38400 57600 38400 1200 19200 9600 115200 115200 75
  41 +#define SOFT_UART_BIT_RATE 38400 // 38400 57600 38400 1200 19200 9600 115200 115200 75
42 42 #define RX_BUF_LENGTH 256 // software serial port's reception buffer length
43 43 #define TX_BUF_LENGTH 256 // software serial port's transmision buffer length
44 44 #define TX_INACTIVE_TIME 50 // milliseconds
... ...
library.properties
1 1 name=soft_uart
2   -version=1.1.4
  2 +version=2.0
3 3 author=Antonio C. Domínguez Brito <adominguez@iusiani.ulpgc.es>
4 4 maintainer=Antonio C. Domínguez Brito <adominguez@iusiani.ulpgc.es>
5 5 sentence=This is an implementation of a software UART (Universal Asynchronous Receiver Transmitter) library for the Arduino Due's Atmel ATSAM3X8E micro-controller.
... ...
soft_uart.h
... ... @@ -100,6 +100,20 @@ serial_tc_declaration(7,rx_length,tx_length)
100 100 #define serial_tc8_declaration(rx_length,tx_length) \
101 101 serial_tc_declaration(8,rx_length,tx_length)
102 102  
  103 +/** \brief Get Enabled Interrupt
  104 +
  105 + This function reads the set-enable register in the NVIC and returns the enabled bit
  106 + for the specified interrupt.
  107 +
  108 + \param [in] IRQn Number of the interrupt for get pending
  109 + \return 0 Interrupt status is not enabled
  110 + \return 1 Interrupt status is enabled
  111 + */
  112 +static __INLINE uint32_t NVIC_GetEnabledIRQ(IRQn_Type IRQn)
  113 +{
  114 + return((uint32_t) ((NVIC->ISER[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if enabled else 0 */
  115 +}
  116 +
103 117 namespace arduino_due
104 118 {
105 119  
... ... @@ -200,6 +214,14 @@ namespace arduino_due
200 214 IRQn_Type irq;
201 215 };
202 216  
  217 + class interrupt_guard
  218 + {
  219 + public:
  220 +
  221 + interrupt_guard() { __disable_irq(); }
  222 + ~interrupt_guard() { __enable_irq(); }
  223 + };
  224 +
203 225 extern tc_timer_data
204 226 tc_timer_table[static_cast<uint32_t>(timer_ids::TIMER_IDS)];
205 227  
... ... @@ -259,7 +281,6 @@ namespace arduino_due
259 281 pinMode(rx_pin,INPUT_PULLUP);
260 282 attachInterrupt(rx_pin,uart::rx_interrupt,CHANGE);
261 283  
262   - _ctx_.enable_rx_interrupts();
263 284 _mode_=mode_codes::FULL_DUPLEX;
264 285  
265 286 return return_codes::EVERYTHING_OK;
... ... @@ -296,7 +317,6 @@ namespace arduino_due
296 317 // configure & attatch interrupt on rx pin
297 318 pinMode(rx_tx_pin,INPUT_PULLUP);
298 319 attachInterrupt(rx_tx_pin,uart::rx_interrupt,CHANGE);
299   - _ctx_.enable_rx_interrupts();
300 320 _mode_=mode_codes::RX_MODE;
301 321 }
302 322 else
... ... @@ -326,7 +346,6 @@ namespace arduino_due
326 346 attachInterrupt(_ctx_.rx_pin,uart::rx_interrupt,CHANGE);
327 347  
328 348 _mode_=mode_codes::RX_MODE;
329   - _ctx_.enable_rx_interrupts();
330 349 return true;
331 350 }
332 351  
... ... @@ -339,12 +358,8 @@ namespace arduino_due
339 358  
340 359 if(_mode_==mode_codes::TX_MODE) return true;
341 360  
342   - while(true)
343   - {
344   - _ctx_.disable_rx_interrupts();
345   - if(_ctx_.rx_status==rx_status_codes::LISTENING) break;
346   - _ctx_.enable_rx_interrupts();
347   - }
  361 + // waiting to finish reception
  362 + while(_ctx_.rx_status==rx_status_codes::RECEIVING) { /* do nothing */ }
348 363  
349 364 detachInterrupt(_ctx_.rx_pin);
350 365 pinMode(_ctx_.tx_pin,OUTPUT);
... ... @@ -473,12 +488,8 @@ namespace arduino_due
473 488  
474 489 int available()
475 490 {
476   - register int any;
477   - disable_tc_interrupts();
478   - any=rx_buffer.items();
479   - enable_tc_interrupts();
480   -
481   - return any;
  491 + interrupt_guard guard;
  492 + return rx_buffer.items();
482 493 }
483 494  
484 495 bool data_available(uint32_t status)
... ... @@ -517,18 +528,14 @@ namespace arduino_due
517 528 // is TX buffer full?
518 529 bool is_tx_full()
519 530 {
520   - disable_tc_interrupts();
521   - auto full=tx_buffer.is_full();
522   - enable_tc_interrupts();
523   - return full;
  531 + interrupt_guard guard;
  532 + return tx_buffer.is_full();
524 533 }
525 534  
526 535 int available_for_write()
527 536 {
528   - disable_tc_interrupts();
529   - auto items=tx_buffer.available();
530   - enable_tc_interrupts();
531   - return items;
  537 + interrupt_guard guard;
  538 + return tx_buffer.available();
532 539 }
533 540  
534 541 // NOTE: only the 5, 6, 7, 8 or 9 lowest significant bits
... ... @@ -544,9 +551,8 @@ namespace arduino_due
544 551  
545 552 void flush_rx()
546 553 {
547   - disable_tc_interrupts();
  554 + interrupt_guard guard;
548 555 rx_buffer.reset();
549   - enable_tc_interrupts();
550 556 }
551 557  
552 558 tx_status_codes get_tx_status() { return tx_status; }
... ... @@ -559,24 +565,34 @@ namespace arduino_due
559 565 return odd_parity;
560 566 }
561 567  
562   - void enable_rx_interrupts() { NVIC_EnableIRQ(rx_irq); }
563   - void disable_rx_interrupts() { NVIC_DisableIRQ(rx_irq); }
  568 + void config_rx_interrupt()
  569 + { NVIC_SetPriority(rx_irq,0); NVIC_EnableIRQ(timer_p->irq); }
  570 +
  571 + void enable_rx_interrupts() { rx_pio_p->PIO_IER=rx_mask; }
  572 +
  573 + void disable_rx_interrupts() { rx_pio_p->PIO_IDR=rx_mask; }
  574 +
  575 + bool is_rx_interrupts_enabled() { return bool{rx_pio_p->PIO_IMR & rx_mask}; }
564 576  
565 577 void config_tc_interrupt() { NVIC_SetPriority(timer_p->irq,0); }
566 578  
567 579 void enable_tc_interrupts() { NVIC_EnableIRQ(timer_p->irq); }
  580 +
568 581 void disable_tc_interrupts() { NVIC_DisableIRQ(timer_p->irq); }
569 582  
  583 + bool is_tc_interrupts_enabled()
  584 + { return bool{NVIC_GetEnabledIRQ(timer_p->irq)}; }
  585 +
570 586 void start_tc_interrupts()
571 587 {
572 588 NVIC_ClearPendingIRQ(timer_p->irq);
573   - NVIC_EnableIRQ(timer_p->irq);
  589 + enable_tc_interrupts();
574 590 TC_Start(timer_p->tc_p,timer_p->channel);
575 591 }
576 592  
577 593 void stop_tc_interrupts()
578 594 {
579   - NVIC_DisableIRQ(timer_p->irq);
  595 + disable_tc_interrupts();
580 596 TC_Stop(timer_p->tc_p,timer_p->channel);
581 597 }
582 598  
... ... @@ -673,13 +689,15 @@ namespace arduino_due
673 689 volatile uint32_t rx_bit;
674 690 volatile rx_status_codes rx_status;
675 691 volatile uint32_t rx_data_status;
676   - volatile bool rx_at_end_quarter;
  692 + //volatile bool rx_at_end_quarter;
  693 + volatile uint32_t rx_interrupt_counter;
677 694  
678 695 // tx data
679 696 fifo<uint32_t,TX_BUFFER_LENGTH> tx_buffer;
680 697 volatile uint32_t tx_data;
681 698 volatile uint32_t tx_bit_counter;
682 699 volatile tx_status_codes tx_status;
  700 + volatile uint32_t tx_interrupt_counter;
683 701 };
684 702  
685 703 static _uart_ctx_ _ctx_;
... ... @@ -803,6 +821,8 @@ namespace arduino_due
803 821 return _last_data_;
804 822 }
805 823  
  824 + bool data_available() { _tc_uart_.data_available(_last_data_status_); }
  825 +
806 826 bool data_lost() { return _tc_uart_.data_lost(_last_data_status_); }
807 827  
808 828 bool bad_status() { return _tc_uart_.bad_status(_last_data_status_); }
... ... @@ -936,7 +956,7 @@ namespace arduino_due
936 956 rx_status=rx_status_codes::LISTENING;
937 957 rx_data_status=rx_data_status_codes::NO_DATA_AVAILABLE;
938 958 rx_buffer.reset();
939   - rx_at_end_quarter=false;
  959 + rx_interrupt_counter=0;
940 960  
941 961 rx_irq=(
942 962 (rx_pio_p==PIOA)?
... ... @@ -952,6 +972,7 @@ namespace arduino_due
952 972 tx_mask=g_APinDescription[tx_pin].ulPin;
953 973 tx_status=tx_status_codes::IDLE;
954 974 tx_buffer.reset();
  975 + tx_interrupt_counter=0;
955 976  
956 977 // PMC settings
957 978 pmc_set_writeprotect(0);
... ... @@ -966,12 +987,15 @@ namespace arduino_due
966 987 TC_CMR_WAVSEL_UP_RC
967 988 );
968 989  
969   - TC_SetRA(timer_p->tc_p,timer_p->channel,bit_1st_half);
970   - disable_tc_ra_interrupt();
  990 + //TC_SetRA(timer_p->tc_p,timer_p->channel,bit_1st_half);
  991 + //disable_tc_ra_interrupt();
971 992  
972   - TC_SetRC(timer_p->tc_p,timer_p->channel,bit_ticks);
973   - disable_tc_rc_interrupt();
  993 + //TC_SetRC(timer_p->tc_p,timer_p->channel,bit_ticks);
  994 + TC_SetRC(timer_p->tc_p,timer_p->channel,bit_1st_half);
  995 + //disable_tc_rc_interrupt();
  996 + enable_tc_rc_interrupt();
974 997  
  998 + config_rx_interrupt();
975 999 config_tc_interrupt();
976 1000 stop_tc_interrupts();
977 1001  
... ... @@ -990,80 +1014,46 @@ namespace arduino_due
990 1014 uint32_t the_status
991 1015 )
992 1016 {
993   - // RA compare interrupt
994   - if((the_status & TC_SR_CPAS) && is_enabled_ra_interrupt())
  1017 + // RC compare interrupt
  1018 + if((the_status & TC_SR_CPCS) && is_enabled_rc_interrupt())
995 1019 {
  1020 + // rx code
996 1021 if(rx_status==rx_status_codes::RECEIVING)
997   - {
998   - if(!rx_at_end_quarter)
  1022 + {
  1023 + if((rx_interrupt_counter++)&1)
999 1024 {
1000 1025 get_incoming_bit();
1001   - if((rx_bit_counter++)==rx_frame_bits-1)
  1026 + if((rx_bit_counter++)==rx_frame_bits-1)
1002 1027 {
1003 1028 if(stop_bits==stop_bit_codes::TWO_STOP_BITS)
1004 1029 get_incoming_bit();
1005 1030  
1006   - disable_tc_ra_interrupt();
1007   -
1008   - if(tx_status==tx_status_codes::IDLE)
1009   - stop_tc_interrupts();
  1031 + if(tx_status==tx_status_codes::IDLE) stop_tc_interrupts();
1010 1032  
1011 1033 update_rx_data_buffer();
1012 1034  
1013 1035 rx_status=rx_status_codes::LISTENING;
1014 1036 }
1015 1037 }
1016   - else rx_at_end_quarter=false;
1017   - }
1018   - }
1019   -
1020   - // RC compare interrupt
1021   - if((the_status & TC_SR_CPCS) && is_enabled_rc_interrupt())
1022   - {
1023   - // rx code
1024   - if(
1025   - !is_enabled_ra_interrupt() &&
1026   - (rx_status==rx_status_codes::RECEIVING)
1027   - )
1028   - {
1029   - get_incoming_bit();
1030   - if((rx_bit_counter++)==rx_frame_bits-1)
1031   - {
1032   - if(stop_bits==stop_bit_codes::TWO_STOP_BITS)
1033   - get_incoming_bit();
1034   -
1035   - if(tx_status==tx_status_codes::IDLE)
1036   - {
1037   - disable_tc_rc_interrupt();
1038   - stop_tc_interrupts();
1039   - }
1040   -
1041   - update_rx_data_buffer();
1042   -
1043   - rx_status=rx_status_codes::LISTENING;
1044   - }
1045 1038 }
1046 1039  
1047 1040 // tx code
1048 1041 if(tx_status==tx_status_codes::SENDING)
1049 1042 {
1050   - set_outgoing_bit();
1051   - if((tx_bit_counter++)==tx_frame_bits-1)
  1043 + if((tx_interrupt_counter++)&1)
1052 1044 {
1053   - uint32_t data_to_send;
1054   - if(tx_buffer.pop(data_to_send))
1055   - { tx_data=data_to_send; tx_bit_counter=0; }
1056   - else
  1045 + set_outgoing_bit();
  1046 + if((tx_bit_counter++)==tx_frame_bits-1)
1057 1047 {
1058   - if(rx_status==rx_status_codes::LISTENING)
1059   - { disable_tc_rc_interrupt(); stop_tc_interrupts(); }
  1048 + uint32_t data_to_send;
  1049 + if(tx_buffer.pop(data_to_send))
  1050 + { tx_data=data_to_send; tx_bit_counter=0; }
1060 1051 else
1061 1052 {
1062   - if(is_enabled_ra_interrupt())
1063   - disable_tc_rc_interrupt();
1064   - }
  1053 + if(rx_status==rx_status_codes::LISTENING) stop_tc_interrupts();
1065 1054  
1066   - tx_status=tx_status_codes::IDLE;
  1055 + tx_status=tx_status_codes::IDLE;
  1056 + }
1067 1057 }
1068 1058 }
1069 1059 }
... ... @@ -1090,27 +1080,15 @@ namespace arduino_due
1090 1080 {
1091 1081 rx_status=rx_status_codes::RECEIVING;
1092 1082 rx_data=rx_bit_counter=rx_bit=0;
  1083 + rx_interrupt_counter=1;
1093 1084  
1094   - if(tx_status==tx_status_codes::IDLE)
1095   - {
1096   - enable_tc_ra_interrupt();
1097   - start_tc_interrupts();
1098   - }
  1085 + if(tx_status==tx_status_codes::IDLE) start_tc_interrupts();
1099 1086 else
1100 1087 {
1101 1088 register uint32_t timer_value=
1102 1089 TC_ReadCV(timer_p->tc_p,timer_p->channel);
1103 1090  
1104   - if(timer_value<=(bit_1st_half>>1))
1105   - enable_tc_ra_interrupt();
1106   - else
1107   - {
1108   - if(timer_value>bit_1st_half+(bit_1st_half>>1))
1109   - {
1110   - enable_tc_ra_interrupt();
1111   - rx_at_end_quarter=true;
1112   - }
1113   - }
  1091 + if(timer_value>=(bit_1st_half>>1)) rx_interrupt_counter=0;
1114 1092 }
1115 1093 }
1116 1094 break;
... ... @@ -1136,23 +1114,21 @@ namespace arduino_due
1136 1114 register uint32_t status;
1137 1115 register bool not_empty;
1138 1116 uint32_t data_received;
1139   -
1140   - disable_tc_interrupts();
1141 1117  
1142   - if(!(not_empty=rx_buffer.pop(data_received)))
1143   - rx_data_status=rx_data_status_codes::NO_DATA_AVAILABLE;
1144   - status=rx_data_status;
1145   -
1146   - enable_tc_interrupts();
  1118 + {
  1119 + interrupt_guard guard;
  1120 +
  1121 + status=(not_empty=rx_buffer.pop(data_received))?
  1122 + rx_data_status_codes::DATA_AVAILABLE:
  1123 + rx_data_status_codes::NO_DATA_AVAILABLE;
  1124 + }
1147 1125  
1148 1126 if(!not_empty) return status;
1149 1127  
1150 1128 // checking start bit
1151   - status=(
1152   - (data_received & 1)?
1153   - status|rx_data_status_codes::BAD_START_BIT:
1154   - status&(~rx_data_status_codes::BAD_START_BIT)
1155   - );
  1129 + status=(data_received & 1)?
  1130 + status|rx_data_status_codes::BAD_START_BIT:
  1131 + status&(~rx_data_status_codes::BAD_START_BIT);
1156 1132  
1157 1133 // cheking parity
1158 1134 if(parity!=parity_codes::NO_PARITY)
... ... @@ -1169,20 +1145,16 @@ namespace arduino_due
1169 1145 (data_received>>parity_bit_pos) & 1;
1170 1146  
1171 1147 // verifying parity bit
1172   - status=(
1173   - (received_parity^data_parity)?
  1148 + status=(received_parity^data_parity)?
1174 1149 status|rx_data_status_codes::BAD_PARITY:
1175   - status&(~rx_data_status_codes::BAD_PARITY)
1176   - );
  1150 + status&(~rx_data_status_codes::BAD_PARITY);
1177 1151 }
1178 1152  
1179 1153 // checking stop bit
1180 1154 // NOTE: we only verify the first stop bit
1181   - status=(
1182   - ((data_received>>first_stop_bit_pos) & 1)?
1183   - status&(~rx_data_status_codes::BAD_STOP_BIT):
1184   - status|rx_data_status_codes::BAD_STOP_BIT
1185   - );
  1155 + status=((data_received>>first_stop_bit_pos) & 1)?
  1156 + status&(~rx_data_status_codes::BAD_STOP_BIT):
  1157 + status|rx_data_status_codes::BAD_STOP_BIT;
1186 1158  
1187 1159 // NOTE: in case of error, we put the received raw data
1188 1160 // on the high 16 bits of status
... ... @@ -1231,35 +1203,25 @@ namespace arduino_due
1231 1203 data_to_send=data_to_send|(0x3<<first_stop_bit_pos);
1232 1204  
1233 1205 register bool not_full;
1234   -
1235   - disable_tc_interrupts();
  1206 + interrupt_guard guard;
  1207 +
1236 1208 not_full=tx_buffer.push(data_to_send);
1237   - enable_tc_interrupts();
1238 1209  
1239 1210 if(!not_full) return false;
1240   -
1241   - enable_tc_rc_interrupt();
1242   -
1243   - disable_tc_interrupts();
1244   -
1245   - disable_rx_interrupts();
1246   - if(
1247   - (rx_status==rx_status_codes::LISTENING)
1248   - && (tx_status==tx_status_codes::IDLE)
1249   - ) start_tc_interrupts();
1250   - enable_rx_interrupts();
1251 1211  
1252   - //disable_tc_interrupts();
1253   -
1254 1212 if(tx_status==tx_status_codes::IDLE)
1255 1213 {
1256 1214 tx_buffer.pop(data_to_send);
1257 1215 tx_data=data_to_send; tx_bit_counter=0;
  1216 + tx_interrupt_counter=1;
1258 1217 }
1259 1218  
  1219 + if(
  1220 + (rx_status==rx_status_codes::LISTENING)
  1221 + && (tx_status==tx_status_codes::IDLE)
  1222 + ) start_tc_interrupts();
  1223 +
1260 1224 tx_status=tx_status_codes::SENDING;
1261   -
1262   - enable_tc_interrupts();
1263 1225  
1264 1226 return true;
1265 1227 }
... ...