/*
 * serial_protocol.h
 *
 *  Created on: Aug 15, 2024
 *      Author: jakubski
 */

#ifndef INC_SERIAL_PROTOCOL_H_
#define INC_SERIAL_PROTOCOL_H_

#include "node-red-config.h"

/*
 *	Request frame
 *  |AA|ID0|ID1|CMD0|CMD1|LEN0|LEN1|0x00|DATA0|..|DATAn|CRC0|CRC1|
 *
 *	Response frame
 *	|AA|ID0|ID1|CMD0|CMD1|LEN0|LEN1|RESPSTAT|DATA0|..|DATAn|CRC0|CRC1|
 *	MSB set in CMD1
 */

#define FRAME_INDICATOR 0xAA
#define FRAME_HEADER_LENGTH 8
#define FRAME_DATALEN_LENGTH sizeof (uint16_t)
#define FRAME_COMMAND_LENGTH sizeof (uint16_t)
#define FRAME_ID_LENGTH sizeof (uint16_t)
#define FRAME_RESP_STAT_LENGTH sizeof (uint8_t)
#define FRAME_CRC_LENGTH sizeof (uint16_t)
#define FRAME_TIMEOUT_MS 2000

enum _SerialProtocolCommands {
	spGetElectricalMeasurments,
	spGetSensorMeasurments,
	spSetFanSpeed,
	spSetMotorXOn,
	spSetMotorYOn,
	spSetmotorXMaxCurrent,
	spSetmotorYMaxCurrent,
	spSetDiodeOn,
    spUnknown
};

typedef enum _SerialProtocolCommands SerialProtocolCommands;

enum _SerialProtocolRespStatus { spInternalError = -3, spCrcFail = -2, spTimeout, spOK };
typedef enum _SerialProtocolRespStatus SerialProtocolRespStatus;

#define GET_SHORT_WORD_FIRST_BYTE(cmd) ((uint8_t)(cmd & 0xFF))
#define GET_SHORT_WORD_SECOND_BYTE(cmd) ((uint8_t)((cmd >> 8) & 0xFF))

#define GET_WORD_FIRST_BYTE(cmd) ((uint8_t)(cmd & 0xFF))
#define GET_WORD_SECOND_BYTE(cmd) ((uint8_t)((cmd >> 8) & 0xFF))
#define GET_WORD_THIRD_BYTE(cmd) ((uint8_t)((cmd >> 16) & 0xFF))
#define GET_WORD_FOURTH_BYTE(cmd) ((uint8_t)((cmd >> 24) & 0xFF))

#define CONVERT_BYTES_TO_SHORT_WORD(buffer) ((uint16_t)((*(buffer + 1) << 8) | *buffer))
#define CONVERT_BYTES_TO_WORD(buffer) ((uint32_t)((*(buffer + 3) << 24) | (*(buffer + 2) << 16) | (*(buffer + 1) << 8) | *buffer))

void WriteDataToBuffer (uint8_t* buff, uint16_t* buffPos, void* data, uint8_t dataSize);
void ReadFloatFromBuffer(uint8_t* buff, uint16_t* buffPos, float* data);
void ReadShortWordFromBufer(uint8_t* buff, uint16_t* buffPos, uint16_t* data);
void ReadWordFromBufer(uint8_t* buff, uint16_t* buffPos, uint32_t* data);
void ReadByteFromBufer(uint8_t* buff, uint16_t* buffPos, uint8_t* data);
uint16_t PrepareReqFrame (uint8_t* txBuffer, uint16_t frameId, SerialProtocolCommands frameCommand, uint8_t* dataBuffer,uint16_t dataLength);
uint16_t PrepareRespFrame (uint8_t* txBuffer, uint16_t frameId, SerialProtocolCommands frameCommand, SerialProtocolRespStatus respStatus, uint8_t* dataBuffer, uint16_t dataLength);

#endif /* INC_SERIAL_PROTOCOL_H_ */
