2025-03-18 23:25:00 +08:00

280 lines
11 KiB
C

/*********************************************************************************************************
* ------------------------------------------------------------------------------------------------------
* file description
* ------------------------------------------------------------------------------------------------------
* \file slup.h
* \unit slup
* \brief This is a simple serial link universal protocol for C language
* \author Lamdonn
* \version v0.1.0
* \license GPL-2.0
* \copyright Copyright (C) 2023 Lamdonn.
********************************************************************************************************/
#ifndef __slup_H
#define __slup_H
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
/* Version infomation */
#define SLUP_V_MAJOR 0
#define SLUP_V_MINOR 1
#define SLUP_V_PATCH 0
// Maximum size of the head part in the SLUP structure, set to 4 bytes.
#define SLUP_HEAD_MAX 4
// Maximum size of the tail part in the SLUP structure, set to 4 bytes.
#define SLUP_TAIL_MAX 4
// Maximum size of the check code part in the SLUP structure, set to 4 bytes.
#define SLUP_CHECK_MAX 4
// Maximum size of the sequence number (SN) part in the SLUP structure, set to 4 bytes.
#define SLUP_SN_MAX 4
// Maximum size of the frame in the SLUP structure, set to 4095 bytes.
#define SLUP_FRAME_MAX 4095
// Size of the receive queue in the SLUP structure, set to 1024 bytes.
#define SLUP_RXQUE_SIZE 1024
// Success code, indicating that an operation has been completed successfully.
#define SLUP_E_OK 0
// Error code, indicating that the 'slup' pointer is invalid.
#define SLUP_E_INVALID 1
// Error code, indicating that the 'data' pointer is invalid.
#define SLUP_E_DATA 2
// Error code, indicating that the length value is invalid.
#define SLUP_E_LEN 3
// Error code, indicating that the SLUP load testing has not started.
#define SLUP_E_NTEST 4
// Error code, indicating that the SLUP load exceeds the defined range.
#define SLUP_E_OVER 5
// Error code, indicating that the 'link' pointer is invalid.
#define SLUP_E_LINK 6
// Error code, indicating that the 'rate' pointer is invalid.
#define SLUP_E_RATE 7
// Link status value representing the link is in the down state.
#define SLUP_LINK_DOWN 0x00
// Link status value representing the link is in the transmit (TX) state.
#define SLUP_LINK_TX 0x01
// Link status value representing the link is in the receive (RX) state.
#define SLUP_LINK_RX 0x02
// Link status value representing the link is in the up state.
#define SLUP_LINK_UP 0x03
// Function pointer type for a function that writes a character.
// It takes a character 'c' as an argument and returns an 'int'.
typedef int (*slup_putc_t)(char c);
// Function pointer type for a function that checks data.
// It takes a pointer to an array of 'uint8_t' data and its length (in 'uint16_t') as arguments
// and returns a 'uint32_t'.
typedef uint32_t (*slup_check_t)(uint8_t *data, uint16_t length);
// Function pointer type for a function that receives data.
// It takes a pointer to an array of 'uint8_t' data and its length (in 'uint16_t') as arguments
// and returns an 'int'.
typedef int (*slup_receive_t)(uint8_t *data, uint16_t length);
// Structure definition for SLUP configuration.
typedef struct
{
// Array to store the head mask, with a maximum size defined by SLUP_HEAD_MAX.
uint8_t head[SLUP_HEAD_MAX]; /**< head mask */
// Array to store the tail mask, with a maximum size defined by SLUP_TAIL_MAX.
uint8_t tail[SLUP_TAIL_MAX]; /**< tail mask */
// Size of the head part, stored in 4 bits.
uint8_t hsize : 4; /**< head size */
// Size of the tail part, stored in 4 bits.
uint8_t tsize : 4; /**< tail size */
// Size of the check code part, stored in 4 bits.
uint8_t csize : 4; /**< check code size */
// Size of the sequence number (sn) part, stored in 4 bits.
uint8_t ssize : 4; /**< sn size */
} SLUP_CFG;
/* queue type define */
// Structure definition for an SLUP queue.
typedef struct
{
// Array that serves as the base address for the data in the queue,
// with a size defined by SLUP_RXQUE_SIZE.
char base[SLUP_RXQUE_SIZE]; /* base address of data */
// Total size of the queue.
uint32_t size; /* size of queue */
// Index of the queue head.
uint32_t head; /* index of queue head */
// Index of the queue tail.
uint32_t tail; /* index of queue tail */
} SLUP_QUEUE;
// Structure definition for an SLUP parser.
typedef struct
{
// Current state of the parser.
uint8_t state;
// Index related to the head part, stored in 4 bits.
uint8_t hindex : 4;
// Index related to the tail part, stored in 4 bits.
uint8_t tindex : 4;
// Index related to the check code part, stored in 4 bits.
uint8_t cindex : 4;
// Index related to the sequence number (sn) part, stored in 4 bits.
uint8_t sindex : 4;
// Index related to the length part, stored in 2 bits.
uint8_t lindex : 2;
// Flag indicating the frame status.
uint8_t frame;
// Length of the data being processed.
uint16_t length;
// Index within the data.
uint16_t dindex;
// Check value for the data.
uint32_t check;
// Sequence number.
uint32_t sn;
} SLUP_PARSER;
// Structure definition for an SLUP dummy data structure.
typedef struct
{
// Compression factor, represented as a floating-point number.
float compression;
// Rate value, represented as a floating-point number.
float rate;
// Target value, represented as a 32-bit unsigned integer.
uint32_t target;
// Base value for the gap, represented as a 32-bit unsigned integer.
uint32_t gapbase;
// Count value for the gap, represented as a 32-bit unsigned integer.
uint32_t gapcount;
// Array to store data, with a size of 64 bytes.
uint8_t data[64];
} SLUP_DUMMY;
// Structure definition for the main SLUP structure that combines multiple components.
typedef struct
{
// SLUP configuration structure.
SLUP_CFG cfg;
// SLUP queue structure.
SLUP_QUEUE queue;
// SLUP parser structure.
SLUP_PARSER parser;
// SLUP dummy data structure.
SLUP_DUMMY dummy;
// Buffer to store data, with a maximum size defined by SLUP_FRAME_MAX.
uint8_t buffer[SLUP_FRAME_MAX];
// Size of the buffer.
uint32_t bsize;
// Sequence number.
uint32_t sn;
// Link status flag.
uint8_t link;
// Silent status flag.
uint8_t silent;
// Period value, represented as a 16-bit unsigned integer.
uint16_t period;
// Timestamp value, represented as a 32-bit unsigned integer.
uint32_t timestamp;
// Number of bits for the up direction, represented as a 32-bit unsigned integer.
uint32_t upbits;
// Number of bits for the down direction, represented as a 32-bit unsigned integer.
uint32_t downbits;
// Rate value for the up direction, represented as a 32-bit unsigned integer.
uint32_t uprate;
// Rate value for the down direction, represented as a 32-bit unsigned integer.
uint32_t downrate;
// Function pointer of type 'slup_putc_t' for writing a character.
slup_putc_t putc;
// Function pointer of type 'slup_check_t' for checking data.
slup_check_t check;
// Function pointer of type 'slup_receive_t' for receiving data.
slup_receive_t receive;
} SLUP;
/**
* \brief Initializes the SLUP structure.
* \param slup: Pointer to the SLUP structure.
* \return SLUP_E_OK if the initialization is successful, SLUP_E_INVALID if the pointer is NULL.
*
* This function initializes various fields in the SLUP structure.
*/
int slup_init(SLUP *slup);
/**
* \brief Sends data in the SLUP protocol with a frame type of 0x01.
* \param slup: Pointer to the SLUP structure.
* \param data: Pointer to the data buffer to be sent.
* \param length: The length of the data buffer.
* \return SLUP_E_OK if the data is successfully sent, appropriate error code otherwise.
*
* This function simply calls the slup_send_package function with a frame type of 0x01
* to send the provided data.
*/
int slup_send(SLUP *slup, uint8_t *data, uint16_t length);
/**
* \brief Retrieves the current link status from the SLUP structure.
* \param slup: Pointer to the SLUP structure.
* \param link: Pointer to a variable where the link status will be stored.
* \return SLUP_E_OK if the retrieval is successful, appropriate error code otherwise.
*
* This function checks if the provided pointers are valid.
*/
int slup_link_status(SLUP *slup, uint8_t *link);
/**
* \brief Retrieves the upload rate from the SLUP structure.
* \param slup: Pointer to the SLUP structure.
* \param rate: Pointer to a variable where the upload rate will be stored.
* \return SLUP_E_OK if the retrieval is successful, appropriate error code otherwise.
*
* This function checks if the provided pointers are valid.
*/
int slup_upload_rate(SLUP *slup, uint32_t *rate);
/**
* \brief Retrieves the download rate from the SLUP structure.
* \param slup: Pointer to the SLUP structure.
* \param rate: Pointer to a variable where the download rate will be stored.
* \return SLUP_E_OK if the retrieval is successful, appropriate error code otherwise.
*
* This function checks if the provided pointers are valid.
*/
int slup_download_rate(SLUP *slup, uint32_t *rate);
/**
* \brief Sets the target rate for the dummy data in the SLUP structure.
* \param slup: Pointer to the SLUP structure.
* \param rate: The target rate value to be set.
* \return SLUP_E_OK if the setting is successful, SLUP_E_INVALID if the pointer is NULL.
*
* This function checks if the provided pointer is valid.
*/
int slup_set_dummy(SLUP *slup, uint32_t rate);
/**
* \brief Handles the reception of a single character in the SLUP system.
* \param slup: Pointer to the SLUP structure.
* \param c: The received character.
*
* This function updates the link status to indicate a received character (sets SLUP_LINK_RX),
* clears the silent flag, updates the download statistics, and pushes the received character
* into the queue.
*/
void slup_getc(SLUP *slup, char c);
/**
* \brief The main task function for the SLUP system.
* \param slup: Pointer to the SLUP structure.
*
* This function is the main task handler for the SLUP system. It updates the timestamp,
* and based on the timestamp value, performs various operations such as sending heartbeat
* messages, calculating rates, executing dummy data sending, and updating dummy data parameters.
* It also calls the slup_parse_task function to parse the received data in the queue.
*/
void slup_task(SLUP *slup);
#endif