Added ADC, H-Bridge and motor models, refactored project structure

This commit is contained in:
2018-07-28 09:45:49 +02:00
parent 100822810f
commit 38099e3fc6
61 changed files with 696 additions and 44 deletions

View File

@ -0,0 +1,105 @@
/*
* BLDC.h
*
* Created on: 26.06.2018
* Author: eyck
*/
#ifndef BLDC_H_
#define BLDC_H_
#include <boost/numeric/odeint.hpp>
namespace odeint = boost::numeric::odeint;
inline
double norm_angle(double alpha){
double alpha_n = fmod(alpha, M_PI * 2);
if (alpha_n < 0.) alpha_n += (M_PI * 2);
return alpha_n;
}
class BLDC {
public:
struct Config {
double inertia = 0.0005; /* aka 'J' in kg/(m^2) */
double damping = 0.000089; /* aka 'B' in Nm/(rad/s) */
double static_friction = 0.0; /* in Nm */
//double Kv = 0.0042; /* motor constant in RPM/V */
double Ke = 0.0042; /* back emf constant in V/rad/s*/
double L = 0.0027; /* Coil inductance in H */
double M = -0.000069; /* Mutual coil inductance in H */
double R = 2.875; /* Coil resistence in Ohm */
int NbPoles = 2; /* NbPoles / 2 = Number of pole pairs (you count the permanent magnets on the rotor to get NbPoles) */
};
using StateVector = std::array<double, 5>;
struct State{
double& theta; /* angle of the rotor */
double& omega; /* angular speed of the rotor */
double& ia; /* phase a current */
double& ib; /* phase b current */
double& ic; /* phase c current */
explicit State(StateVector& v):theta(v[0]), omega(v[1]), ia(v[2]), ib(v[3]), ic(v[4]){}
State(State&&) = delete;
State(const State&) = delete;
State& operator=(const State&) = delete; // Copy assignment operator
State& operator=(const State&&) = delete; // Move assignment operator
~State(){}
void init(){
theta = ia = ib = ic = 0;
omega = 0.;
}
};
explicit BLDC(const Config config);
virtual ~BLDC();
void set_input(std::array<double, 3> vin){
this->vin=vin;
}
void run(double dt);
void printToStream(std::ostream&) const;
double get_current_time(){return current_time;}
std::tuple<double, double, double> get_voltages(){
return std::tuple<double, double, double>(
voltages[VA]+voltages[EA]+state.ia*config.R,
voltages[VB]+voltages[EB]+state.ib*config.R,
voltages[VC]+voltages[EC]+state.ic*config.R
);
}
const State& getState(){ return state;}
void setLoad(double torque){torque_load=torque;}
protected:
Config config;
StateVector stateVector;
State state;
std::array<double, 3> vin;
double current_time = 0.0;
double torque_load=0.0;
double etorque=0.0, mtorque=0.0;
const double dt = 0.000001;
std::array<double, 7> voltages;
enum VoltageNames {EA=0, EB=1, EC=2, VA=3, VB=4, VC=5, VCENTER=6};
double calc_bemf_factor(const State& state, double theta );
void calc_back_emf(const State& state, double theta_e );
void calc_voltages();
// ODE part
//boost::numeric::odeint::runge_kutta4< StateVector > stepper;
//boost::numeric::odeint::runge_kutta_cash_karp54<StateVector > stepper;
//using stepper_type = odeint::runge_kutta_dopri5<StateVector>;
//using stepper_type = odeint::runge_kutta_cash_karp54< StateVector>;
using stepper_type = odeint::runge_kutta_fehlberg78< StateVector>;
void rotor_dyn( const StateVector& x , StateVector& dxdt , const double t );
};
std::ostream& operator<<(std::ostream& os, const BLDC& bldc);
#endif /* BLDC_H_ */

View File

@ -0,0 +1,38 @@
/*
* dcmotor.h
*
* Created on: 25.07.2018
* Author: eyck
*/
#ifndef _SYSC_TOP_DCMOTOR_H_
#define _SYSC_TOP_DCMOTOR_H_
#include "BLDC.h"
#include "scc/traceable.h"
#include <systemc>
namespace sysc {
class dc_motor: public sc_core::sc_module, public scc::traceable {
public:
SC_HAS_PROCESS(dc_motor);
sc_core::sc_in<double> va_i, vb_i, vc_i;
sc_core::sc_out<double> va_o, vb_o, vc_o;
dc_motor(const sc_core::sc_module_name& nm );
virtual ~dc_motor();
void trace(sc_core::sc_trace_file *trf) override;
private:
void thread(void);
BLDC bldc_model;
const BLDC::State& bldc_state;
};
} /* namespace sysc */
#endif /* RISCV_SC_INCL_SYSC_TOP_DCMOTOR_H_ */

View File

@ -0,0 +1,39 @@
/*
* h_bridge.h
*
* Created on: 25.07.2018
* Author: eyck
*/
#ifndef RISCV_SC_INCL_SYSC_TOP_H_BRIDGE_H_
#define RISCV_SC_INCL_SYSC_TOP_H_BRIDGE_H_
#include "cci_configuration"
#include <sysc/kernel/sc_module.h>
namespace sysc {
class h_bridge: public sc_core::sc_module {
public:
SC_HAS_PROCESS(h_bridge);
sc_core::sc_in<sc_dt::sc_logic> ha_i, la_i;
sc_core::sc_in<sc_dt::sc_logic> hb_i, lb_i;
sc_core::sc_in<sc_dt::sc_logic> hc_i, lc_i;
sc_core::sc_out<double> va_o, vb_o, vc_o;
cci::cci_param<double> vcc;
h_bridge(const sc_core::sc_module_name& nm);
virtual ~h_bridge();
private:
void ain_cb();
void bin_cb();
void cin_cb();
};
} /* namespace sysc */
#endif /* RISCV_SC_INCL_SYSC_TOP_H_BRIDGE_H_ */

View File

@ -0,0 +1,47 @@
/*
* mcp3008.h
*
* Created on: 17.07.2018
* Author: eyck
*/
#ifndef _SYSC_TOP_MCP3008_H_
#define _SYSC_TOP_MCP3008_H_
#include "scc/signal_target_mixin.h"
#include "scc/signal_initiator_mixin.h"
#include "sysc/tlm_extensions.h"
#include <tlm/tlm_signal.h>
#include "cci_configuration"
#include <sysc/utils/sc_vector.h>
#include <sysc/kernel/sc_module.h>
namespace sysc {
class mcp3008: public sc_core::sc_module {
public:
SC_HAS_PROCESS(mcp3008);
scc::tlm_signal_logic_in sck_i;
scc::tlm_signal_logic_out miso_o;
scc::tlm_signal_logic_in mosi_i;
scc::tlm_signal_logic_in cs_i;
sc_core::sc_in<double> vref_i;
sc_core::sc_vector<sc_core::sc_in<double>> ch_i;
mcp3008(sc_core::sc_module_name nm);
virtual ~mcp3008();
private:
tlm::tlm_sync_enum receive(tlm::tlm_signal_gp<sc_dt::sc_logic> &, tlm::tlm_phase &, sc_core::sc_time &);
void do_conversion();
unsigned idx, rx_bits;
std::array<uint8_t, 3> rx_bytes, tx_bytes;
sc_dt::sc_logic mosi_v, miso_v, cs_v;
sysc::tlm_signal_spi_extension* ext, tx_ext;
sc_core::sc_time last_tx_start;
};
} /* namespace sysc */
#endif /* _SYSC_TOP_MCP3008_H_ */

View File

@ -0,0 +1,42 @@
/*
* system.h
*
* Created on: 11.07.2018
* Author: eyck
*/
#ifndef __SYSC_GENERAL_SYSTEM_H_
#define __SYSC_GENERAL_SYSTEM_H_
#include <systemc>
#include "sysc/SiFive/hifive1.h"
#include "mcp3008.h"
#include "terminal.h"
#include "h_bridge.h"
#include "dcmotor.h"
namespace sysc {
class system: sc_core::sc_module {
public:
SC_HAS_PROCESS(system);
system(sc_core::sc_module_name nm);
virtual ~system();
private:
sc_core::sc_vector<tlm::tlm_signal<sc_dt::sc_logic>> s_gpio;
sc_core::sc_signal<bool> s_rst_n;
sc_core::sc_signal<double> s_vref, s_va, s_vb, s_vc, s_vasens, s_vbsens, s_vcsens;
sc_core::sc_vector<sc_core::sc_signal<double>> s_ana;
sysc::hifive1 i_platform;
sysc::terminal i_terminal;
sysc::mcp3008 i_adc;
sysc::h_bridge i_h_bridge;
sysc::dc_motor i_motor;
void gen_por();
};
}
#endif /* __SYSC_GENERAL_SYSTEM_H_ */

View File

@ -0,0 +1,44 @@
/*
* terminal.h
*
* Created on: 07.07.2018
* Author: eyck
*/
#ifndef _SYSC_TOP_TERMINAL_H_
#define _SYSC_TOP_TERMINAL_H_
#include "scc/signal_target_mixin.h"
#include "scc/signal_initiator_mixin.h"
#include "tlm/tlm_signal.h"
#include "cci_configuration"
#include <sysc/kernel/sc_module.h>
#include <memory>
namespace sysc {
class WsHandler;
class terminal: public sc_core::sc_module {
public:
scc::tlm_signal_logic_out tx_o;
scc::tlm_signal_logic_in rx_i;
terminal();
terminal(const sc_core::sc_module_name& nm);
virtual ~terminal();
cci::cci_param<bool> write_to_ws;
protected:
void before_end_of_elaboration();
void receive(tlm::tlm_signal_gp<sc_dt::sc_logic>& gp, sc_core::sc_time& delay);
std::vector<uint8_t> queue;
std::shared_ptr<sysc::WsHandler> handler;
sc_core::sc_time last_tx_start=sc_core::SC_ZERO_TIME;
};
}
#endif /* _SYSC_TOP_TERMINAL_H_ */