Index: platforms/stm/disco_fletch/src/uart.cc |
diff --git a/platforms/stm/disco_fletch/src/uart.cc b/platforms/stm/disco_fletch/src/uart.cc |
deleted file mode 100644 |
index f20f0d586f83f5b7f9e91f2d193aacf84a168725..0000000000000000000000000000000000000000 |
--- a/platforms/stm/disco_fletch/src/uart.cc |
+++ /dev/null |
@@ -1,164 +0,0 @@ |
-// Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file |
-// for details. All rights reserved. Use of this source code is governed by a |
-// BSD-style license that can be found in the LICENSE.md file. |
- |
-#include "platforms/stm/disco_fletch/src/uart.h" |
- |
-#include <stdlib.h> |
- |
-#include <stm32f7xx_hal.h> |
- |
-#include "src/shared/atomic.h" |
-#include "src/shared/utils.h" |
- |
-// Reference to the instance in the code generated by STM32CubeMX. |
-extern UART_HandleTypeDef huart1; |
- |
-// TODO(sgjesse): Get rid of these global variables. These global |
-// variables are accessed from the interrupt handlers. |
-static osSemaphoreId sem_; |
-static uint32_t error = 0; |
- |
-// Bits set from interrupt handlers. |
-const int kReceivedBit = 1 << 0; |
-const int kTransmittedBit = 1 << 1; |
-const int kErrorBit = 1 << 2; |
-static fletch::Atomic<uint32_t> interrupt_flags; |
- |
-const int kRxBufferSize = 511; |
-const int kTxBufferSize = 511; |
- |
-// C trampoline for the interrupt handling thread. |
-void __UartTask(void const* argument) { |
- Uart* uart = const_cast<Uart*>(reinterpret_cast<const Uart*>(argument)); |
- uart->Task(); |
-} |
- |
-Uart::Uart() { |
- uart_ = &huart1; |
- rx_buffer_ = new CircularBuffer(kRxBufferSize); |
- tx_mutex_ = fletch::Platform::CreateMutex(); |
- tx_buffer_ = new CircularBuffer(kTxBufferSize); |
- tx_pending_ = false; |
- error_count_ = 0; |
- |
- // Semaphore for signaling from interrupt handlers. A maximum of |
- // three tokens - one for data received and one for data transmitted |
- // and one for error. |
- semaphore_ = osSemaphoreCreate(osSemaphore(semaphore_def_), 3); |
- // Store in global variable for access from interrupt handlers. |
- sem_ = semaphore_; |
-} |
- |
-void Uart::Start() { |
- // Start thread for handling interrupts. |
- osThreadDef(UART_TASK, __UartTask, osPriorityHigh, 0, 1024); |
- osThreadCreate(osThread(UART_TASK), this); |
- |
- // Start receiving. |
- HAL_UART_Receive_IT(uart_, &rx_data_, 1); |
-} |
- |
-size_t Uart::Read(uint8_t* buffer, size_t count) { |
- return rx_buffer_->Read(buffer, count, CircularBuffer::kBlock); |
-} |
- |
-size_t Uart::Write(const uint8_t* buffer, size_t count) { |
- size_t written = tx_buffer_->Write(buffer, count, CircularBuffer::kBlock); |
- |
- fletch::ScopedLock lock(tx_mutex_); |
- EnsureTransmission(); |
- return written; |
-} |
- |
-void Uart::Task() { |
- // Process notifications from the interrupt handlers. |
- for (;;) { |
- // Wait for an interrupt to be processed. |
- osSemaphoreWait(semaphore_, osWaitForever); |
- // Read the flags and set them to zero. |
- uint32_t flags = interrupt_flags.exchange(0); |
- |
- if ((flags & kReceivedBit) != 0) { |
- // Don't block when writing to the buffer. Buffer overrun will |
- // cause lost data. |
- rx_buffer_->Write(&rx_data_, 1, CircularBuffer::kDontBlock); |
- |
- // Start receiving of next byte. |
- HAL_StatusTypeDef status = HAL_UART_Receive_IT(uart_, &rx_data_, 1); |
- if (status != HAL_OK) { |
- fletch::Print::Error("HAL_UART_Receive_IT returned %d\n", status); |
- } |
- } |
- |
- if ((flags & kTransmittedBit) != 0) { |
- fletch::ScopedLock lock(tx_mutex_); |
- tx_pending_ = false; |
- EnsureTransmission(); |
- } |
- |
- if ((flags & kErrorBit) != 0) { |
- // Ignore errors for now. |
- error_count_++; |
- error = 0; |
- // Setup interrupt for next byte. |
- HAL_StatusTypeDef status = HAL_UART_Receive_IT(uart_, &rx_data_, 1); |
- if (status != HAL_OK) { |
- fletch::Print::Error("HAL_UART_Receive_IT returned %d\n", status); |
- } |
- } |
- } |
-} |
- |
-void Uart::EnsureTransmission() { |
- if (!tx_pending_) { |
- // Don't block when there is nothing to send. |
- int bytes = tx_buffer_->Read( |
- tx_data_, kTxBlockSize, CircularBuffer::kDontBlock); |
- if (bytes > 0) { |
- HAL_StatusTypeDef status = HAL_UART_Transmit_IT(uart_, tx_data_, bytes); |
- if (status != HAL_OK) { |
- fletch::Print::Error("HAL_UART_Transmit_IT returned %d\n", status); |
- } |
- tx_pending_ = true; |
- } |
- } |
-} |
- |
-// Shared return from interrupt handler. Will set the specified flag |
-// and transfer control to the thread handling interrupts. |
-static void ReturnFromInterrupt(UART_HandleTypeDef *huart, uint32_t flag) { |
- // Set the requested bit. |
- uint32_t flags = interrupt_flags; |
- uint32_t new_flags = flags |= flag; |
- bool success = false; |
- while (!success) { |
- success = |
- interrupt_flags.compare_exchange_weak(flags, new_flags); |
- } |
- |
- // Pass control to the thread handling interrupts. |
- portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; |
- osSemaphoreRelease(sem_); |
- portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); |
-} |
- |
-extern "C" void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { |
- ReturnFromInterrupt(huart, kReceivedBit); |
-} |
- |
-extern "C" void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { |
- ReturnFromInterrupt(huart, kTransmittedBit); |
-} |
- |
-extern "C" void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) { |
- error = HAL_UART_GetError(huart); |
- |
- // Clear all errors. |
- __HAL_UART_CLEAR_OREFLAG(&huart1); |
- __HAL_UART_CLEAR_FEFLAG(&huart1); |
- __HAL_UART_CLEAR_PEFLAG(&huart1); |
- __HAL_UART_CLEAR_NEFLAG(&huart1); |
- |
- ReturnFromInterrupt(huart, kErrorBit); |
-} |