Skip to content

Commit

Permalink
Move Huawei CAN bus communication to separate thread
Browse files Browse the repository at this point in the history
  • Loading branch information
MalteSchm committed Sep 30, 2023
1 parent 933345d commit c44dd5a
Show file tree
Hide file tree
Showing 2 changed files with 320 additions and 179 deletions.
88 changes: 62 additions & 26 deletions include/Huawei_can.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <cstdint>
#include "SPI.h"
#include <mcp_can.h>
#include <mutex>

#ifndef HUAWEI_PIN_MISO
#define HUAWEI_PIN_MISO 12
Expand Down Expand Up @@ -34,35 +35,45 @@

#define MAX_CURRENT_MULTIPLIER 20

// Index values for rec_values array
#define HUAWEI_INPUT_POWER_IDX 0
#define HUAWEI_INPUT_FREQ_IDX 1
#define HUAWEI_INPUT_CURRENT_IDX 2
#define HUAWEI_OUTPUT_POWER_IDX 3
#define HUAWEI_EFFICIENCY_IDX 4
#define HUAWEI_OUTPUT_VOLTAGE_IDX 5
#define HUAWEI_OUTPUT_CURRENT_MAX_IDX 6
#define HUAWEI_INPUT_VOLTAGE_IDX 7
#define HUAWEI_OUTPUT_TEMPERATURE_IDX 8
#define HUAWEI_INPUT_TEMPERATURE_IDX 9
#define HUAWEI_OUTPUT_CURRENT_IDX 10
#define HUAWEI_OUTPUT_CURRENT1_IDX 11

// Defines and index values for tx_values array
#define HUAWEI_OFFLINE_VOLTAGE 0x01
#define HUAWEI_ONLINE_VOLTAGE 0x00
#define HUAWEI_OFFLINE_CURRENT 0x04
#define HUAWEI_ONLINE_CURRENT 0x03

#define R48xx_DATA_INPUT_POWER 0x70
#define R48xx_DATA_INPUT_FREQ 0x71
#define R48xx_DATA_INPUT_CURRENT 0x72
#define R48xx_DATA_OUTPUT_POWER 0x73
#define R48xx_DATA_EFFICIENCY 0x74
#define R48xx_DATA_OUTPUT_VOLTAGE 0x75
#define R48xx_DATA_OUTPUT_CURRENT_MAX 0x76
#define R48xx_DATA_INPUT_VOLTAGE 0x78
#define R48xx_DATA_OUTPUT_TEMPERATURE 0x7F
#define R48xx_DATA_INPUT_TEMPERATURE 0x80
#define R48xx_DATA_OUTPUT_CURRENT 0x81
#define R48xx_DATA_OUTPUT_CURRENT1 0x82

// Modes of operation
#define HUAWEI_MODE_OFF 0
#define HUAWEI_MODE_ON 1
#define HUAWEI_MODE_AUTO_EXT 2
#define HUAWEI_MODE_AUTO_INT 3

// Error codes
#define HUAWEI_ERROR_CODE_RX 0x01
#define HUAWEI_ERROR_CODE_TX 0x02

// Wait time/current before shuting down the PSU / charger
// This is set to allow the fan to run for some time
#define HUAWEI_AUTO_MODE_SHUTDOWN_DELAY 60000
#define HUAWEI_AUTO_MODE_SHUTDOWN_CURRENT 1.0

struct RectifierParameters_t {
// Updateinterval used to request new values from the PSU
#define HUAWEI_DATA_REQUEST_INTERVAL_MS 2500

typedef struct RectifierParameters {
float input_voltage;
float input_frequency;
float input_current;
Expand All @@ -75,6 +86,33 @@ struct RectifierParameters_t {
float output_power;
float output_temp;
float amp_hour;
} RectifierParameters_t;

class HuaweiCanCommClass {
public:
bool init(uint8_t huawei_miso, uint8_t huawei_mosi, uint8_t huawei_clk, uint8_t huawei_irq, uint8_t huawei_cs);
void loop();
bool gotNewRxDataFrame(bool clear);
uint8_t getErrorCode(bool clear);
uint32_t getParameterValue(uint8_t parameter);
void setParameterValue(uint16_t in, uint8_t parameterType);

private:
void sendRequest();

SPIClass *SPI;
MCP_CAN *_CAN;
uint8_t _huaweiIrq; // IRQ pin
uint32_t _nextRequestMillis = 0; // When to send next data request to PSU

std::mutex _mutex;

uint32_t _recValues[12];
uint16_t _txValues[5];
bool _hasNewTxValue[5];

uint8_t _errorCode;
bool _completeUpdateReceived;
};

class HuaweiCanClass {
Expand All @@ -89,26 +127,24 @@ class HuaweiCanClass {
bool getAutoPowerStatus();

private:
void sendRequest();
void onReceive(uint8_t* frame, uint8_t len);
void processReceivedParameters();

SPIClass *spi;
MCP_CAN *CAN;
TaskHandle_t _HuaweiCanCommunicationTaskHdl = NULL;
bool _initialized = false;
uint8_t _huawei_irq; // IRQ pin
uint8_t _huawei_power; // Power pin
uint8_t _huaweiPower; // Power pin
uint8_t _mode = HUAWEI_MODE_AUTO_EXT;

RectifierParameters_t _rp;

uint32_t _lastUpdateReceivedMillis; // Timestamp for last data seen from the PSU
uint32_t _nextRequestMillis = 0; // When to send next data request to PSU
uint32_t _nextAutoModePeriodicIntMillis; // When to send the next output volume request in Automatic mode
uint32_t _lastPowerMeterUpdateReceivedMillis; // Timestamp of last power meter value
uint32_t _outputCurrentOnSinceMillis; // Timestamp since when the PSU was idle at zero amps
bool _newOutputPowerReceived = false;
uint8_t _autoPowerEnabled = false;
bool _autoPowerActive = false;
uint32_t _nextAutoModePeriodicIntMillis; // When to set the next output voltage in automatic mode
uint32_t _lastPowerMeterUpdateReceivedMillis; // Timestamp of last seen power meter value
uint32_t _autoModeBlockedTillMillis = 0; // Timestamp to block running auto mode for some time

uint8_t _autoPowerEnabledCounter = 0;
bool _autoPowerEnabled = false;
};

extern HuaweiCanClass HuaweiCan;
extern HuaweiCanCommClass HuaweiCanComm;
Loading

0 comments on commit c44dd5a

Please sign in to comment.