@@ -327,7 +327,7 @@ int HardwareSerial::_tx_complete_irq(serial_t *obj)
327327{
328328 // If interrupts are enabled, there must be more data in the output
329329 // buffer. Send the next byte
330- obj->tx_tail = (obj->tx_tail + 1 ) % SERIAL_TX_BUFFER_SIZE;
330+ obj->tx_tail = (obj->tx_tail + obj-> tx_size ) % SERIAL_TX_BUFFER_SIZE;
331331
332332 if (obj->tx_head == obj->tx_tail ) {
333333 return -1 ;
@@ -467,8 +467,12 @@ void HardwareSerial::flush()
467467 // the hardware finished tranmission (TXC is set).
468468}
469469
470- size_t HardwareSerial::write (uint8_t c )
470+ size_t HardwareSerial::write (const uint8_t *buffer, size_t size )
471471{
472+ tx_buffer_index_t i;
473+ size_t size_tmp;
474+ size_t ret = size;
475+
472476 _written = true ;
473477 if (isHalfDuplex ()) {
474478 if (_rx_enabled) {
@@ -477,22 +481,59 @@ size_t HardwareSerial::write(uint8_t c)
477481 }
478482 }
479483
480- tx_buffer_index_t i = (_serial.tx_head + 1 ) % SERIAL_TX_BUFFER_SIZE;
484+ // If necessary split transfert till end of TX buffer
485+ while (_serial.tx_head + size > SERIAL_TX_BUFFER_SIZE) {
486+ size_t size_intermediate = SERIAL_TX_BUFFER_SIZE - _serial.tx_head ;
481487
482- // If the output buffer is full, there's nothing for it other than to
483- // wait for the interrupt handler to empty it a bit
484- while (i == _serial.tx_tail ) {
485- // nop, the interrupt handler will free up space for us
488+ write (buffer, size_intermediate);
489+ size -= size_intermediate;
490+ buffer += size_intermediate;
491+ }
492+
493+ // Here size if less or equal to SERIAL_TX_BUFFER_SIZE, but SERIAL_TX_BUFFER_SIZE is not possible as tx_head = tx_tail is ambiguous empty or full
494+ if (size == SERIAL_TX_BUFFER_SIZE) {
495+ size_t size_intermediate = SERIAL_TX_BUFFER_SIZE - 1 ;
496+
497+ write (buffer, size_intermediate);
498+ size -= size_intermediate;
499+ buffer += size_intermediate;
500+ }
501+
502+ size_tmp = size;
503+
504+ while (size_tmp) {
505+ i = (_serial.tx_head + 1 ) % SERIAL_TX_BUFFER_SIZE;
506+
507+
508+ // If the output buffer is full, there's nothing for it other than to
509+ // wait for the interrupt handler to empty it a bit
510+ while (i == _serial.tx_tail ) {
511+ // nop, the interrupt handler will free up space for us
512+ }
513+ _serial.tx_buff [_serial.tx_head ] = *buffer;
514+ _serial.tx_head = i;
515+ size_tmp --;
516+ buffer ++;
517+ }
518+
519+ while ((_serial.tx_head != (_serial.tx_tail + size) % SERIAL_TX_BUFFER_SIZE)) {
520+ // nop, previous transfert no yet completed
486521 }
487522
488- _serial.tx_buff [_serial.tx_head ] = c;
489- _serial.tx_head = i;
523+ _serial.tx_size = size;
490524
491525 if (!serial_tx_active (&_serial)) {
492- uart_attach_tx_callback (&_serial, _tx_complete_irq);
526+ uart_attach_tx_callback (&_serial, _tx_complete_irq, size );
493527 }
494528
495- return 1 ;
529+ /* There is no real error management so just return transfer size requested*/
530+ return ret;
531+ }
532+
533+ size_t HardwareSerial::write (uint8_t c)
534+ {
535+ uint8_t buff = c;
536+ return write (&buff, 1 );
496537}
497538
498539void HardwareSerial::setRx (uint32_t _rx)
0 commit comments