Implement virtual com port receiver
This commit is contained in:
parent
3d0cce0db4
commit
e0bb399415
53
AdaptiveBrightnessFirmware/Inc/vcp_receiver.hpp
Normal file
53
AdaptiveBrightnessFirmware/Inc/vcp_receiver.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
extern "C" void vcpReceiveCallback(uint8_t*, uint32_t);
|
||||
|
||||
namespace detail {
|
||||
|
||||
constexpr auto VCP_RECEIVE_BUFFER_SIZE = 64;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class VcpReceiver {
|
||||
public:
|
||||
static inline bool rxByte(uint8_t& data)
|
||||
{
|
||||
if(m_receiveBuffer.head == m_receiveBuffer.tail)
|
||||
return false;
|
||||
|
||||
const uint8_t newTail = (m_receiveBuffer.tail + 1) % detail::VCP_RECEIVE_BUFFER_SIZE;
|
||||
data = m_receiveBuffer.data[newTail];
|
||||
m_receiveBuffer.tail = newTail;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
friend void vcpReceiveCallback(uint8_t*, uint32_t);
|
||||
|
||||
template<size_t Size>
|
||||
struct RingBuffer {
|
||||
size_t head = 0;
|
||||
size_t tail = 0;
|
||||
uint8_t data[Size];
|
||||
};
|
||||
|
||||
static volatile RingBuffer<detail::VCP_RECEIVE_BUFFER_SIZE> m_receiveBuffer;
|
||||
|
||||
static inline void rxHandler(const uint8_t& data)
|
||||
{
|
||||
const uint8_t newHead = (m_receiveBuffer.head + 1) % detail::VCP_RECEIVE_BUFFER_SIZE;
|
||||
|
||||
if(newHead != m_receiveBuffer.tail) {
|
||||
m_receiveBuffer.head = newHead;
|
||||
m_receiveBuffer.data[newHead] = data;
|
||||
}
|
||||
else {
|
||||
// TODO: Handle overflow
|
||||
}
|
||||
}
|
||||
};
|
@ -74,7 +74,8 @@ Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c
|
||||
|
||||
# C++ sources
|
||||
CXX_SOURCES = \
|
||||
Src/main.cpp
|
||||
Src/main.cpp \
|
||||
Src/vcp_receiver.cpp
|
||||
|
||||
# ASM sources
|
||||
ASM_SOURCES = \
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "init.h"
|
||||
#include "usbd_cdc_if.h"
|
||||
#include "utils.hpp"
|
||||
#include "vcp_receiver.hpp"
|
||||
|
||||
std::array<uint16_t, 3> sampleLightSensors()
|
||||
{
|
||||
@ -31,6 +32,8 @@ int main()
|
||||
{
|
||||
init();
|
||||
|
||||
VcpReceiver vcpReceiver;
|
||||
|
||||
HAL_GPIO_WritePin(RED_LED_GPIO_Port, RED_LED_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GREEN_LED_GPIO_Port, GREEN_LED_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_RESET);
|
||||
@ -41,7 +44,13 @@ int main()
|
||||
HAL_GPIO_WritePin(GREEN_LED_GPIO_Port, GREEN_LED_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_SET);
|
||||
|
||||
uint8_t data = 0;
|
||||
|
||||
while(true) {
|
||||
if(vcpReceiver.rxByte(data)) {
|
||||
CDC_Transmit_FS(&data, 1);
|
||||
}
|
||||
|
||||
const auto ldrValues = sampleLightSensors();
|
||||
|
||||
HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_RESET);
|
||||
@ -51,8 +60,8 @@ int main()
|
||||
for(uint8_t i = 0; i < ldrValues.size(); ++i) {
|
||||
const auto ldrID = i + 1;
|
||||
const auto percentage = ldrValues[i] * 100 / 0xFFF;
|
||||
const auto bufLen =
|
||||
std::sprintf(reinterpret_cast<char*>(printBuffer.data()), "LDR%d: %04hu - %03d%%\r\n%s", ldrID, ldrValues[i], percentage, (i == 2) ? "\r\n" : "");
|
||||
const auto bufLen = std::sprintf(reinterpret_cast<char*>(printBuffer.data()), "LDR%d: %04hu - %03d%%\r\n%s", ldrID, ldrValues[i], percentage,
|
||||
(i == 2) ? "\r\n" : "");
|
||||
if(bufLen > 0) {
|
||||
while(CDC_Transmit_FS(printBuffer.data(), bufLen) == USBD_BUSY)
|
||||
;
|
||||
|
@ -246,6 +246,8 @@ static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length)
|
||||
/* USER CODE END 5 */
|
||||
}
|
||||
|
||||
extern void vcpReceiveCallback(uint8_t* buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief Data received over USB OUT endpoint are sent over CDC interface
|
||||
* through this function.
|
||||
@ -265,6 +267,7 @@ static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
|
||||
/* USER CODE BEGIN 6 */
|
||||
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
|
||||
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
|
||||
vcpReceiveCallback(Buf, *Len);
|
||||
return (USBD_OK);
|
||||
/* USER CODE END 6 */
|
||||
}
|
||||
|
10
AdaptiveBrightnessFirmware/Src/vcp_receiver.cpp
Normal file
10
AdaptiveBrightnessFirmware/Src/vcp_receiver.cpp
Normal file
@ -0,0 +1,10 @@
|
||||
#include "vcp_receiver.hpp"
|
||||
|
||||
extern "C" void vcpReceiveCallback(uint8_t* buf, uint32_t len)
|
||||
{
|
||||
for(uint32_t i = 0; i < len; ++i) {
|
||||
VcpReceiver::rxHandler(buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
volatile VcpReceiver::RingBuffer<detail::VCP_RECEIVE_BUFFER_SIZE> VcpReceiver::m_receiveBuffer;
|
Loading…
Reference in New Issue
Block a user