From cf409a54be3b3edd2b0bd3ff3e7663b4b26a764d Mon Sep 17 00:00:00 2001 From: Andrey Tolstoy Date: Tue, 7 Jun 2016 22:53:13 +0700 Subject: [PATCH] Fixes typo in USART::availableForWrite() and availableForWrite() behavior in general Test SERIAL1_AvailableForWriteWorksCorrectly added to wiring/serial_loopback --- hal/src/core/usart_hal.c | 7 ++- hal/src/stm32f2xx/usart_hal.c | 7 ++- user/tests/wiring/serial_loopback/serial.cpp | 49 ++++++++++++++++++++ wiring/src/spark_wiring_usartserial.cpp | 2 +- 4 files changed, 62 insertions(+), 3 deletions(-) diff --git a/hal/src/core/usart_hal.c b/hal/src/core/usart_hal.c index 3a54cf92db..4a2b7b940f 100644 --- a/hal/src/core/usart_hal.c +++ b/hal/src/core/usart_hal.c @@ -277,7 +277,12 @@ void HAL_USART_End(HAL_USART_Serial serial) int32_t HAL_USART_Available_Data_For_Write(HAL_USART_Serial serial) { - return (unsigned int)(SERIAL_BUFFER_SIZE + usartMap[serial]->usart_tx_buffer->head - usartMap[serial]->usart_tx_buffer->tail) % SERIAL_BUFFER_SIZE; + int32_t tail = usartMap[serial]->usart_tx_buffer->tail; + int32_t available = SERIAL_BUFFER_SIZE - (usartMap[serial]->usart_tx_buffer->head >= tail ? + usartMap[serial]->usart_tx_buffer->head - tail : + (SERIAL_BUFFER_SIZE + usartMap[serial]->usart_tx_buffer->head - tail) - 1); + + return available; } uint32_t HAL_USART_Write_Data(HAL_USART_Serial serial, uint8_t data) diff --git a/hal/src/stm32f2xx/usart_hal.c b/hal/src/stm32f2xx/usart_hal.c index 8e20b8ff9c..e679553f18 100644 --- a/hal/src/stm32f2xx/usart_hal.c +++ b/hal/src/stm32f2xx/usart_hal.c @@ -369,7 +369,12 @@ int32_t HAL_USART_Available_Data(HAL_USART_Serial serial) int32_t HAL_USART_Available_Data_For_Write(HAL_USART_Serial serial) { - return (unsigned int)(SERIAL_BUFFER_SIZE + usartMap[serial]->usart_tx_buffer->head - usartMap[serial]->usart_tx_buffer->tail) % SERIAL_BUFFER_SIZE; + int32_t tail = usartMap[serial]->usart_tx_buffer->tail; + int32_t available = SERIAL_BUFFER_SIZE - (usartMap[serial]->usart_tx_buffer->head >= tail ? + usartMap[serial]->usart_tx_buffer->head - tail : + (SERIAL_BUFFER_SIZE + usartMap[serial]->usart_tx_buffer->head - tail) - 1); + + return available; } diff --git a/user/tests/wiring/serial_loopback/serial.cpp b/user/tests/wiring/serial_loopback/serial.cpp index 6083fac4af..13b25e8988 100644 --- a/user/tests/wiring/serial_loopback/serial.cpp +++ b/user/tests/wiring/serial_loopback/serial.cpp @@ -187,3 +187,52 @@ test(SERIAL2_ReadWriteSucceedsInLoopbackWithD0D1Shorted) { assertTrue(strncmp(test, message, 5)==0); } #endif + +test(SERIAL1_AvailableForWriteWorksCorrectly) { + Serial1.begin(9600); + assertEqual(Serial1.isEnabled(), true); + + // Initially there should be SERIAL_BUFFER_SIZE available in TX buffer + assertEqual(Serial1.availableForWrite(), SERIAL_BUFFER_SIZE); + + // Disable Serial1 IRQ to prevent it from sending data + NVIC_DisableIRQ(USART1_IRQn); + // Write (SERIAL_BUFFER_SIZE / 2) bytes into TX buffer + for (int i = 0; i < SERIAL_BUFFER_SIZE / 2; i++) { + Serial1.write('a'); + } + // There should be (SERIAL_BUFFER_SIZE / 2) bytes available in TX buffer + assertEqual(Serial1.availableForWrite(), SERIAL_BUFFER_SIZE / 2); + + // Write (SERIAL_BUFFER_SIZE / 2 - 1) bytes into TX buffer + for (int i = 0; i < SERIAL_BUFFER_SIZE / 2 - 1; i++) { + Serial1.write('b'); + } + // There should only be 1 byte available in TX buffer + assertEqual(Serial1.availableForWrite(), 1); + // Enable Serial1 IRQ again to send out the data from TX buffer + NVIC_EnableIRQ(USART1_IRQn); + delay(100); + + // There should be SERIAL_BUFFER_SIZE available in TX buffer again + assertEqual(Serial1.availableForWrite(), SERIAL_BUFFER_SIZE); + + // At this point tx_buffer->head = (SERIAL_BUFFER_SIZE - 1), tx_buffer->tail = (SERIAL_BUFFER_SIZE - 1) + // Now test that availableForWrite() returns correct results for cases where tx_buffer->head < tx_buffer->tail + // Disable Serial1 IRQ again to prevent it from sending data + NVIC_DisableIRQ(USART1_IRQn); + // Write (SERIAL_BUFFER_SIZE / 2 + 1) bytes into TX buffer + for (int i = 0; i < SERIAL_BUFFER_SIZE / 2 + 1; i++) { + Serial1.write('c'); + } + // There should be (SERIAL_BUFFER_SIZE / 2) bytes available in TX buffer + assertEqual(Serial1.availableForWrite(), SERIAL_BUFFER_SIZE / 2); + // Enable Serial1 IRQ again to send out the data from TX buffer + NVIC_EnableIRQ(USART1_IRQn); + delay(100); + + // There should be SERIAL_BUFFER_SIZE available in TX buffer again + assertEqual(Serial1.availableForWrite(), SERIAL_BUFFER_SIZE); + + Serial1.end(); +} diff --git a/wiring/src/spark_wiring_usartserial.cpp b/wiring/src/spark_wiring_usartserial.cpp index 8f356b5a35..b1d2d0e2ab 100644 --- a/wiring/src/spark_wiring_usartserial.cpp +++ b/wiring/src/spark_wiring_usartserial.cpp @@ -66,7 +66,7 @@ void USARTSerial::blockOnOverrun(bool block) int USARTSerial::availableForWrite(void) { - return HAL_USART_Available_Data(_serial); + return HAL_USART_Available_Data_For_Write(_serial); } int USARTSerial::available(void)