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
|
# C++ sources
|
||||||
CXX_SOURCES = \
|
CXX_SOURCES = \
|
||||||
Src/main.cpp
|
Src/main.cpp \
|
||||||
|
Src/vcp_receiver.cpp
|
||||||
|
|
||||||
# ASM sources
|
# ASM sources
|
||||||
ASM_SOURCES = \
|
ASM_SOURCES = \
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "usbd_cdc_if.h"
|
#include "usbd_cdc_if.h"
|
||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
|
#include "vcp_receiver.hpp"
|
||||||
|
|
||||||
std::array<uint16_t, 3> sampleLightSensors()
|
std::array<uint16_t, 3> sampleLightSensors()
|
||||||
{
|
{
|
||||||
@ -31,6 +32,8 @@ int main()
|
|||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
|
|
||||||
|
VcpReceiver vcpReceiver;
|
||||||
|
|
||||||
HAL_GPIO_WritePin(RED_LED_GPIO_Port, RED_LED_Pin, GPIO_PIN_RESET);
|
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(GREEN_LED_GPIO_Port, GREEN_LED_Pin, GPIO_PIN_RESET);
|
||||||
HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_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(GREEN_LED_GPIO_Port, GREEN_LED_Pin, GPIO_PIN_SET);
|
||||||
HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_SET);
|
||||||
|
|
||||||
|
uint8_t data = 0;
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
|
if(vcpReceiver.rxByte(data)) {
|
||||||
|
CDC_Transmit_FS(&data, 1);
|
||||||
|
}
|
||||||
|
|
||||||
const auto ldrValues = sampleLightSensors();
|
const auto ldrValues = sampleLightSensors();
|
||||||
|
|
||||||
HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_RESET);
|
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) {
|
for(uint8_t i = 0; i < ldrValues.size(); ++i) {
|
||||||
const auto ldrID = i + 1;
|
const auto ldrID = i + 1;
|
||||||
const auto percentage = ldrValues[i] * 100 / 0xFFF;
|
const auto percentage = ldrValues[i] * 100 / 0xFFF;
|
||||||
const auto bufLen =
|
const auto bufLen = std::sprintf(reinterpret_cast<char*>(printBuffer.data()), "LDR%d: %04hu - %03d%%\r\n%s", ldrID, ldrValues[i], percentage,
|
||||||
std::sprintf(reinterpret_cast<char*>(printBuffer.data()), "LDR%d: %04hu - %03d%%\r\n%s", ldrID, ldrValues[i], percentage, (i == 2) ? "\r\n" : "");
|
(i == 2) ? "\r\n" : "");
|
||||||
if(bufLen > 0) {
|
if(bufLen > 0) {
|
||||||
while(CDC_Transmit_FS(printBuffer.data(), bufLen) == USBD_BUSY)
|
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 */
|
/* 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
|
* @brief Data received over USB OUT endpoint are sent over CDC interface
|
||||||
* through this function.
|
* through this function.
|
||||||
@ -265,6 +267,7 @@ static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
|
|||||||
/* USER CODE BEGIN 6 */
|
/* USER CODE BEGIN 6 */
|
||||||
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
|
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
|
||||||
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
|
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
|
||||||
|
vcpReceiveCallback(Buf, *Len);
|
||||||
return (USBD_OK);
|
return (USBD_OK);
|
||||||
/* USER CODE END 6 */
|
/* 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