This repository has been archived on 2024-05-28. You can view files and clone it, but cannot push or open issues or pull requests.
2023-11-14 16:25:09 -05:00

195 lines
5.1 KiB
C++
Executable File

#ifndef STM32U5XX_HAL_QUEUE_HPP
#define STM32U5XX_HAL_QUEUE_HPP
#include "global_variable.h"
#include "stdint.h"
#include "stdlib.h"
#include <stm32u5xx.h>
#include <algorithm>
class queue {
private:
uint8_t *buffer; // pointer to buffer
uint32_t size; // size of buffer
uint32_t head; // index of head
uint32_t tail; // index of tail
uint32_t count; // number of elements in queue
public:
queue() {}
void clear() { head = tail = count = 0; }
bool is_empty() { return count == 0; }
hal_status_e init(uint32_t _size) {
size = _size;
buffer = (uint8_t *)malloc(size);
head = tail = count = 0;
return buffer != nullptr ? HAL_OK : QUEUE_ERROR_MALLOC_FAILED;
}
hal_status_e push(uint8_t data) {
if (count == size) return QUEUE_ERROR_NO_ENOUGH_SPACE;
buffer[tail] = data;
tail = (tail + 1) % size;
count++;
return HAL_OK;
}
hal_status_e pop(uint8_t *data) {
if (count == 0) return QUEUE_EMPTY;
*data = buffer[head];
head = (head + 1) % size;
count--;
return HAL_OK;
}
hal_status_e push_block(const uint8_t *data, uint32_t len) {
if (count + len > size) return QUEUE_ERROR_NO_ENOUGH_SPACE;
for (uint32_t i = 0; i < len; i++) {
buffer[tail] = data[i];
tail = (tail + 1) % size;
}
count += len;
return HAL_OK;
}
hal_status_e pop_block(uint8_t *data, uint32_t &len) {
if (count < len) return QUEUE_ERROR_NO_ENOUGH_DATA;
if (count == 0) {
len = 0;
return QUEUE_EMPTY;
}
// if there is no enough buf, pop all buf
// the buffer_size will be set to the actual length of buf
__disable_irq();
len = std::min(len, count);
for (uint32_t i = 0; i < len; i++) {
*(data + i) = buffer[head];
head = (head + 1) % size;
}
count -= len;
__enable_irq();
return HAL_OK;
}
hal_status_e get_line(uint8_t *data, uint32_t &len) {
if (count == 0) {
len = 0;
return QUEUE_EMPTY;
}
__disable_irq();
// find '\n'
uint32_t tmp_len = 0;
for (uint32_t i = 0; i < count; i++) {
if (buffer[(head + i) % size] == '\n') {
tmp_len = i + 1;
break;
}
}
if (tmp_len == 0) {
__enable_irq();
return QUEUE_ERROR_NO_LINE;
}
if (tmp_len > len) {
__enable_irq();
return QUEUE_ERROR_BUFFER_OVERFLOW;
}
len = tmp_len;
return this->pop_block(data, len);
}
};
template <int size, typename T> class queue_stack {
private:
T buffer[size]{};
uint32_t head = 0; // index of head
uint32_t tail = 0; // index of tail
uint32_t count = 0; // number of elements in queue
public:
queue_stack() = default;
void clear() { head = tail = count = 0; }
bool is_empty() { return count == 0; }
hal_status_e push(T data) {
if (count == size) return QUEUE_ERROR_NO_ENOUGH_SPACE;
buffer[tail] = data;
tail = (tail + 1) % size;
count++;
return HAL_OK;
}
hal_status_e pop(T *data) {
if (count == 0) return QUEUE_EMPTY;
*data = buffer[head];
head = (head + 1) % size;
count--;
return HAL_OK;
}
hal_status_e push_block(const T *data, uint32_t len) {
if (count + len > size) return QUEUE_ERROR_NO_ENOUGH_SPACE;
for (uint32_t i = 0; i < len; i++) {
buffer[tail] = data[i];
tail = (tail + 1) % size;
}
count += len;
return HAL_OK;
}
hal_status_e pop_block(T *data, uint32_t &len) {
if (count < len) return QUEUE_ERROR_NO_ENOUGH_DATA;
if (count == 0) {
len = 0;
return QUEUE_EMPTY;
}
// if there is no enough buf, pop all buf
// the buffer_size will be set to the actual length of buf
__disable_irq();
len = std::min(len, count);
for (uint32_t i = 0; i < len; i++) {
*(data + i) = buffer[head];
head = (head + 1) % size;
}
count -= len;
__enable_irq();
return HAL_OK;
}
hal_status_e get_line(T *data, uint32_t &len) {
if (count == 0) {
len = 0;
return QUEUE_EMPTY;
}
__disable_irq();
// find '\n'
uint32_t tmp_len = 0;
for (uint32_t i = 0; i < count; i++) {
if (buffer[(head + i) % size] == '\n') {
tmp_len = i + 1;
break;
}
}
if (tmp_len == 0) {
__enable_irq();
return QUEUE_ERROR_NO_LINE;
}
if (tmp_len > len) {
__enable_irq();
return QUEUE_ERROR_BUFFER_OVERFLOW;
}
len = tmp_len;
return this->pop_block(data, len);
}
};
#define queue20u8 queue_stack<20, uint8_t>
#define queue20u32 queue_stack<20, uint32_t>
#endif // STM32U5XX_HAL_QUEUE_HPP