cvl-robot's diary

研究ノート メモメモ https://github.com/dotchang/

モータドライバをシリアル通信で制御するためにInstaSPINの重要パラメータの確認

F28027Fのproj_lab05bのmain.hを参考にします.
gMotorVarsという構造体変数に重要なパラメータがまとめられています.

typedef struct _MOTOR_Vars_t_
{
  bool Flag_enableSys;
  bool Flag_Run_Identify;
  bool Flag_MotorIdentified;
  bool Flag_enableForceAngle;
  bool Flag_enableFieldWeakening;
  bool Flag_enableRsRecalc;
  bool Flag_enableUserParams;
  bool Flag_enableOffsetcalc;
  bool Flag_enablePowerWarp;
  bool Flag_enableSpeedCtrl;

  bool Flag_enableRun;
  bool Flag_RunState;
  bool Flag_enableFlyingStart;

  CTRL_State_e CtrlState;         // Read Only
  EST_State_e EstState;           // Read Only

  USER_ErrorCode_e UserErrorCode;

  CTRL_Version CtrlVersion;

  _iq IdRef_A;
  _iq IqRef_A;
  _iq SpeedRef_pu;
  _iq SpeedRef_krpm;
  _iq SpeedTraj_krpm;             // Read Only
  _iq MaxAccel_krpmps;
  _iq Speed_krpm;                 // Read Only
  _iq OverModulation;
  _iq RsOnLineCurrent_A;
  _iq SvgenMaxModulation_ticks;
  _iq Flux_Wb;                    // Read Only
  _iq Torque_Nm;                  // Read Only

  float_t MagnCurr_A;             // Read Only
  float_t Rr_Ohm;                 // Read Only
  float_t Rs_Ohm;                 // Read Only
  float_t RsOnLine_Ohm;
  float_t Lsd_H;                  // Read Only
  float_t Lsq_H;                  // Read Only
  float_t Flux_VpHz;              // Read Only

  float_t ipd_excFreq_Hz;
  _iq     ipd_Kspd;
  _iq     ipd_excMag_coarse_pu;
  _iq     ipd_excMag_fine_pu;
  float   ipd_waitTime_coarse_sec;
  float   ipd_waitTime_fine_sec;

  _iq Kp_spd;
  _iq Ki_spd;

  _iq Kp_Idq;
  _iq Ki_Idq;

  _iq Vd;
  _iq Vq;
  _iq Vs;
  _iq VsRef;
  _iq VdcBus_kV;                   // Read Only

  _iq Id_A;
  _iq Iq_A;
  _iq Is_A;

  MATH_vec3 I_bias;
  MATH_vec3 V_bias;

  _iq SpeedSet_krpm;

  _iq angle_sen_pu;
  _iq angle_est_pu;
  _iq speed_sen_pu;
  _iq speed_est_pu;

  _iq speedHigh_hall2fast_pu;
  _iq speedLow_hall2fast_pu;
}MOTOR_Vars_t;

コメントのパラメータはループ内で更新されるので、読み込み専用。
これらのデータをシリアルでやり取りするために、それぞれの変数型のメモリサイズを調べておきます。

sizeof(bool)=1
sizeof(CTRL_State_e)=1
sizeof(EST_State_e)=1
sizeof(USER_ErrorCode_e)=1
sizeof(CTRL_Version)=4
sizeof(float_t)=2
sizeof(float)=2
sizeof(_iq)=2
sizeof(MATH_vec3)=6

_iqは標準では、24ビット目に小数点を置く.

#define _IQ24(A) (long) ((A) * 16777216.0L)

計算はこのように行われる.

#include <stdio.h>

long float_to_iq24(float a, unsigned char* lower, unsigned char* upper)
{
    long b = (long)(a * 16777216.0L) >> 8;
    *lower = (b%0x100)&0xff;
    *upper = (b/0x100)&0xff;
    return b;
}

float _iq24l_to_float(long b)
{
    float a = (b<<8)/16777216.0;
    return a;
}

float _iq24_to_float(unsigned char lower, unsigned char upper)
{
    long b = (upper<<8) + lower;
    return _iq24l_to_float(b);
}


int main(void){
    float a = 0.1;
    long b = (long)(a * 16777216.0L) >> 8;
    printf("dec=%f, _iq=%ld, lower_byte=%d, upper_byte=%d\n", a, b, (b%0x100)&0xff, (b/0x100)&0xff);

    unsigned char l, u;
    long lo;
    lo = float_to_iq24(a, &l, &u);
    printf("float_to_iq24: %f %ld %d %d\n", a, lo, l, u);
    
    float f;
    f = _iq24_to_float(l, u);
    printf("_iq24_to_float: %f %d %d\n", f, l, u);
    
    f = _iq24l_to_float(lo);
    printf("_iq24_to_float: %f %ld", f, lo);
}

ちょっとしたテストにはWEBサービスが便利。
Web-based online coding environment | paiza.IO
実行例
dec=0.100000, _iq=6553, lower_byte=153, upper_byte=25

f:id:cvl-robot:20161228215056p:plain
f:id:cvl-robot:20161228215110p:plain


ctrl_state.h

//! \brief Enumeration for the controller states
//!
typedef enum {
  CTRL_State_Error=0,           //!< the controller error state
  CTRL_State_Idle,              //!< the controller idle state
  CTRL_State_OffLine,           //!< the controller offline state
  CTRL_State_OnLine,            //!< the controller online state
  CTRL_numStates                //!< the number of controller states
} CTRL_State_e;

est_state.h

//! \brief Enumeration for the estimator error codes
//!
typedef enum
{
  EST_ErrorCode_NoError=0,               //!< no error error code
  EST_ErrorCode_Flux_OL_ShiftOverFlow,   //!< flux open loop shift overflow error code
  EST_ErrorCode_FluxError,               //!< flux estimator error code
  EST_ErrorCode_Dir_ShiftOverFlow,       //!< direction shift overflow error code
  EST_ErrorCode_Ind_ShiftOverFlow,       //!< inductance shift overflow error code
  EST_numErrorCodes                      //!< the number of estimator error codes
} EST_ErrorCode_e;


//! \brief Enumeration for the estimator states
//!
typedef enum
{
  EST_State_Error=0,            //!< error
  EST_State_Idle,               //!< idle
  EST_State_RoverL,             //!< R/L estimation
  EST_State_Rs,                 //!< Rs estimation state
  EST_State_RampUp,             //!< ramp up the speed
#if !defined(FAST_ROM_V1p6) && !defined(FAST_ROM_V1p7)
  EST_State_ConstSpeed,         //!< constant speed after ramp up
#endif
  EST_State_IdRated,            //!< control Id and estimate the rated flux
  EST_State_RatedFlux_OL,       //!< estimate the open loop rated flux
  EST_State_RatedFlux,          //!< estimate the rated flux 
  EST_State_RampDown,           //!< ramp down the speed 
  EST_State_LockRotor,          //!< lock the rotor
  EST_State_Ls,                 //!< stator inductance estimation state
  EST_State_Rr,                 //!< rotor resistance estimation state
  EST_State_MotorIdentified,    //!< motor identified state
  EST_State_OnLine,             //!< online parameter estimation
  EST_numStates                 //!< the number of estimator states
} EST_State_e;
//! \brief Enumeration for the user error codes
//!
typedef enum
{
  USER_ErrorCode_NoError=0,                           //!< no error error code
  USER_ErrorCode_iqFullScaleCurrent_A_High=1,         //!< iqFullScaleCurrent_A too high error code
  USER_ErrorCode_iqFullScaleCurrent_A_Low=2,          //!< iqFullScaleCurrent_A too low error code
  USER_ErrorCode_iqFullScaleVoltage_V_High=3,         //!< iqFullScaleVoltage_V too high error code
  USER_ErrorCode_iqFullScaleVoltage_V_Low=4,          //!< iqFullScaleVoltage_V too low error code
  USER_ErrorCode_iqFullScaleFreq_Hz_High=5,           //!< iqFullScaleFreq_Hz too high error code
  USER_ErrorCode_iqFullScaleFreq_Hz_Low=6,            //!< iqFullScaleFreq_Hz too low error code
  USER_ErrorCode_numPwmTicksPerIsrTick_High=7,        //!< numPwmTicksPerIsrTick too high error code
  USER_ErrorCode_numPwmTicksPerIsrTick_Low=8,         //!< numPwmTicksPerIsrTick too low error code
  USER_ErrorCode_numIsrTicksPerCtrlTick_High=9,       //!< numIsrTicksPerCtrlTick too high error code
  USER_ErrorCode_numIsrTicksPerCtrlTick_Low=10,       //!< numIsrTicksPerCtrlTick too low error code
  USER_ErrorCode_numCtrlTicksPerCurrentTick_High=11,  //!< numCtrlTicksPerCurrentTick too high error code
  USER_ErrorCode_numCtrlTicksPerCurrentTick_Low=12,   //!< numCtrlTicksPerCurrentTick too low error code
  USER_ErrorCode_numCtrlTicksPerEstTick_High=13,      //!< numCtrlTicksPerEstTick too high error code
  USER_ErrorCode_numCtrlTicksPerEstTick_Low=14,       //!< numCtrlTicksPerEstTick too low error code
  USER_ErrorCode_numCtrlTicksPerSpeedTick_High=15,    //!< numCtrlTicksPerSpeedTick too high error code
  USER_ErrorCode_numCtrlTicksPerSpeedTick_Low=16,     //!< numCtrlTicksPerSpeedTick too low error code
  USER_ErrorCode_numCtrlTicksPerTrajTick_High=17,     //!< numCtrlTicksPerTrajTick too high error code
  USER_ErrorCode_numCtrlTicksPerTrajTick_Low=18,      //!< numCtrlTicksPerTrajTick too low error code
  USER_ErrorCode_numCurrentSensors_High=19,           //!< numCurrentSensors too high error code
  USER_ErrorCode_numCurrentSensors_Low=20,            //!< numCurrentSensors too low error code
  USER_ErrorCode_numVoltageSensors_High=21,           //!< numVoltageSensors too high error code
  USER_ErrorCode_numVoltageSensors_Low=22,            //!< numVoltageSensors too low error code
  USER_ErrorCode_offsetPole_rps_High=23,              //!< offsetPole_rps too high error code
  USER_ErrorCode_offsetPole_rps_Low=24,               //!< offsetPole_rps too low error code
  USER_ErrorCode_fluxPole_rps_High=25,                //!< fluxPole_rps too high error code
  USER_ErrorCode_fluxPole_rps_Low=26,                 //!< fluxPole_rps too low error code
  USER_ErrorCode_zeroSpeedLimit_High=27,              //!< zeroSpeedLimit too high error code
  USER_ErrorCode_zeroSpeedLimit_Low=28,               //!< zeroSpeedLimit too low error code
  USER_ErrorCode_forceAngleFreq_Hz_High=29,           //!< forceAngleFreq_Hz too high error code
  USER_ErrorCode_forceAngleFreq_Hz_Low=30,            //!< forceAngleFreq_Hz too low error code
  USER_ErrorCode_maxAccel_Hzps_High=31,               //!< maxAccel_Hzps too high error code
  USER_ErrorCode_maxAccel_Hzps_Low=32,                //!< maxAccel_Hzps too low error code
  USER_ErrorCode_maxAccel_est_Hzps_High=33,           //!< maxAccel_est_Hzps too high error code
  USER_ErrorCode_maxAccel_est_Hzps_Low=34,            //!< maxAccel_est_Hzps too low error code
  USER_ErrorCode_directionPole_rps_High=35,           //!< directionPole_rps too high error code
  USER_ErrorCode_directionPole_rps_Low=36,            //!< directionPole_rps too low error code
  USER_ErrorCode_speedPole_rps_High=37,               //!< speedPole_rps too high error code
  USER_ErrorCode_speedPole_rps_Low=38,                //!< speedPole_rps too low error code
  USER_ErrorCode_dcBusPole_rps_High=39,               //!< dcBusPole_rps too high error code
  USER_ErrorCode_dcBusPole_rps_Low=40,                //!< dcBusPole_rps too low error code
  USER_ErrorCode_fluxFraction_High=41,                //!< fluxFraction too high error code
  USER_ErrorCode_fluxFraction_Low=42,                 //!< fluxFraction too low error code
  USER_ErrorCode_indEst_speedMaxFraction_High=43,     //!< indEst_speedMaxFraction too high error code
  USER_ErrorCode_indEst_speedMaxFraction_Low=44,      //!< indEst_speedMaxFraction too low error code
  USER_ErrorCode_powerWarpGain_High=45,               //!< powerWarpGain too high error code
  USER_ErrorCode_powerWarpGain_Low=46,                //!< powerWarpGain too low error code
  USER_ErrorCode_systemFreq_MHz_High=47,              //!< systemFreq_MHz too high error code
  USER_ErrorCode_systemFreq_MHz_Low=48,               //!< systemFreq_MHz too low error code
  USER_ErrorCode_pwmFreq_kHz_High=49,                 //!< pwmFreq_kHz too high error code
  USER_ErrorCode_pwmFreq_kHz_Low=50,                  //!< pwmFreq_kHz too low error code
  USER_ErrorCode_voltage_sf_High=51,                  //!< voltage_sf too high error code
  USER_ErrorCode_voltage_sf_Low=52,                   //!< voltage_sf too low error code
  USER_ErrorCode_current_sf_High=53,                  //!< current_sf too high error code
  USER_ErrorCode_current_sf_Low=54,                   //!< current_sf too low error code
  USER_ErrorCode_voltageFilterPole_Hz_High=55,        //!< voltageFilterPole_Hz too high error code
  USER_ErrorCode_voltageFilterPole_Hz_Low=56,         //!< voltageFilterPole_Hz too low error code
  USER_ErrorCode_maxVsMag_pu_High=57,                 //!< maxVsMag_pu too high error code
  USER_ErrorCode_maxVsMag_pu_Low=58,                  //!< maxVsMag_pu too low error code
  USER_ErrorCode_estKappa_High=59,                    //!< estKappa too high error code
  USER_ErrorCode_estKappa_Low=60,                     //!< estKappa too low error code
  USER_ErrorCode_motor_type_Unknown=61,               //!< motor type unknown error code
  USER_ErrorCode_motor_numPolePairs_High=62,          //!< motor_numPolePairs too high error code
  USER_ErrorCode_motor_numPolePairs_Low=63,           //!< motor_numPolePairs too low error code
  USER_ErrorCode_motor_ratedFlux_High=64,             //!< motor_ratedFlux too high error code
  USER_ErrorCode_motor_ratedFlux_Low=65,              //!< motor_ratedFlux too low error code
  USER_ErrorCode_motor_Rr_High=66,                    //!< motor_Rr too high error code
  USER_ErrorCode_motor_Rr_Low=67,                     //!< motor_Rr too low error code
  USER_ErrorCode_motor_Rs_High=68,                    //!< motor_Rs too high error code
  USER_ErrorCode_motor_Rs_Low=69,                     //!< motor_Rs too low error code
  USER_ErrorCode_motor_Ls_d_High=70,                  //!< motor_Ls_d too high error code
  USER_ErrorCode_motor_Ls_d_Low=71,                   //!< motor_Ls_d too low error code
  USER_ErrorCode_motor_Ls_q_High=72,                  //!< motor_Ls_q too high error code
  USER_ErrorCode_motor_Ls_q_Low=73,                   //!< motor_Ls_q too low error code
  USER_ErrorCode_maxCurrent_High=74,                  //!< maxCurrent too high error code
  USER_ErrorCode_maxCurrent_Low=75,                   //!< maxCurrent too low error code
  USER_ErrorCode_maxCurrent_resEst_High=76,           //!< maxCurrent_resEst too high error code
  USER_ErrorCode_maxCurrent_resEst_Low=77,            //!< maxCurrent_resEst too low error code
  USER_ErrorCode_maxCurrent_indEst_High=78,           //!< maxCurrent_indEst too high error code
  USER_ErrorCode_maxCurrent_indEst_Low=79,            //!< maxCurrent_indEst too low error code
  USER_ErrorCode_maxCurrentSlope_High=80,             //!< maxCurrentSlope too high error code
  USER_ErrorCode_maxCurrentSlope_Low=81,              //!< maxCurrentSlope too low error code
  USER_ErrorCode_maxCurrentSlope_powerWarp_High=82,   //!< maxCurrentSlope_powerWarp too high error code
  USER_ErrorCode_maxCurrentSlope_powerWarp_Low=83,    //!< maxCurrentSlope_powerWarp too low error code
  USER_ErrorCode_IdRated_High=84,                     //!< IdRated too high error code
  USER_ErrorCode_IdRated_Low=85,                      //!< IdRated too low error code
  USER_ErrorCode_IdRatedFraction_indEst_High=86,      //!< IdRatedFraction_indEst too high error code
  USER_ErrorCode_IdRatedFraction_indEst_Low=87,       //!< IdRatedFraction_indEst too low error code
  USER_ErrorCode_IdRatedFraction_ratedFlux_High=88,   //!< IdRatedFraction_ratedFlux too high error code
  USER_ErrorCode_IdRatedFraction_ratedFlux_Low=89,    //!< IdRatedFraction_ratedFlux too low error code
  USER_ErrorCode_IdRated_delta_High=90,               //!< IdRated_delta too high error code
  USER_ErrorCode_IdRated_delta_Low=91,                //!< IdRated_delta too low error code
  USER_ErrorCode_fluxEstFreq_Hz_High=92,              //!< fluxEstFreq_Hz too high error code
  USER_ErrorCode_fluxEstFreq_Hz_Low=93,               //!< fluxEstFreq_Hz too low error code
  USER_ErrorCode_ctrlFreq_Hz_High=94,                 //!< ctrlFreq_Hz too high error code
  USER_ErrorCode_ctrlFreq_Hz_Low=95,                  //!< ctrlFreq_Hz too low error code
  USER_ErrorCode_estFreq_Hz_High=96,                  //!< estFreq_Hz too high error code
  USER_ErrorCode_estFreq_Hz_Low=97,                   //!< estFreq_Hz too low error code
  USER_ErrorCode_RoverL_estFreq_Hz_High=98,           //!< RoverL_estFreq_Hz too high error code
  USER_ErrorCode_RoverL_estFreq_Hz_Low=99,            //!< RoverL_estFreq_Hz too low error code
  USER_ErrorCode_trajFreq_Hz_High=100,                //!< trajFreq_Hz too high error code
  USER_ErrorCode_trajFreq_Hz_Low=101,                 //!< trajFreq_Hz too low error code
  USER_ErrorCode_ctrlPeriod_sec_High=102,             //!< ctrlPeriod_sec too high error code
  USER_ErrorCode_ctrlPeriod_sec_Low=103,              //!< ctrlPeriod_sec too low error code
  USER_ErrorCode_maxNegativeIdCurrent_a_High=104,     //!< maxNegativeIdCurrent_a too high error code
  USER_ErrorCode_maxNegativeIdCurrent_a_Low=105,      //!< maxNegativeIdCurrent_a too low error code
  USER_numErrorCodes=106                              //!< the number of user error codes
} USER_ErrorCode_e;
//! \brief Defines the controller (CTRL) version number
//!
typedef struct _CTRL_Version_
{
  uint16_t rsvd;                 //!< reserved value
  CTRL_TargetProc_e targetProc;  //!< the target processor
  uint16_t major;                //!< the major release number
  uint16_t minor;                //!< the minor release number
} CTRL_Version;

proj_lab05bのフローチャート
f:id:cvl-robot:20161221183251p:plain

f:id:cvl-robot:20161221232949p:plain
FlagCtrlStateChangedの中身
f:id:cvl-robot:20161221232610p:plain

mainスレッド
f:id:cvl-robot:20161221230408p:plain

続きを読む

APM(ArduPilot)のローバーをいじる前に資料収集

EMLID Navio2
APM installation and running - Navio2 docs

ardupilot Rover Home
Rover Home — Rover documentation

Ailerocket/エルロケット
ailerocket.com

ailerocket.com

Drone Japan/ArduPilot入門
技術ブログ – Drone Japan



HKPilot Mega 2.7 Series Episode 2 - APM Rover - HobbyKing Live


Apm rover in tractor mission planner control


APM 3.1 Rover X8R D16 Test

WordpressでIPアドレスを変更したときに、管理画面がおかしくなってしまった時の対処法

(メモ)

amazon EC2WordpressにElastic IPで固定IPを振ろうとしたときに、いろいろおかしくなってしまうことが良くあります。

1.データベース上のIPアドレスを変更します。

www.agilegroup.co.jp
ここを参考にします。

2.なおかつwp-admin画面がおかしい場合,アドレスの指定がくるっているので、wordpressを再更新します。

f:id:cvl-robot:20161101181626p:plain
こんな感じの画面になることがある。

http://52.*.*.*/wp-admin/about.php
のように、リンクをたどるのではなく、WEBサーバー上のファイルのアドレスを直接していして管理画面を出し、wordpressを更新する。



Jetpackでhomeがおかしい、と言われた時の対処

たぶん、SettingsのSite Address(URL)の
"http://"
が抜けてる。

Jetpackでこのサイトにアクセスできません、と言われたときの対処

jetpack.com
このサイトにURLを貼り付けて、対処方法を教えてもらう。

一部のテーマで使われているTestimonials Sectionなどを有効にする方法

WordpressのSettingsのWrittingの中のカスタムコンテンツタイプのチェックを入れる。

wp-kyoto.net

WordpressのShapelyテーマを使って、今どきのホームページを立ててみる

(編集中)

1.Wordpressを準備する

Wordpressを自分でインストールするのは手間がかかります。しかし、有料サービスを使うとか、NASのプリインストール版を使う、とかすると簡単に用意できます。
個人用にオススメなのは、ASUSTORのNASを使うことです。

買ってきて2時間ぐらいでセットアップできます。
「自分ブログ」をNASで簡単に作ってみよう、世界標準「WordPress」をインストール - 知られざるNASアプリの世界 - 窓の杜
WordPressでブログサーバを立てる!〜WordPressをインストールしてセットアップする〜

もっと手軽に始めたい場合は、
Amazon EC2の1年間無料サービスを使って、Wordpressを立てると良いです。
AWS を無料でお試しください | アマゾン ウェブ サービス(AWS 日本語)

2. Shapelyテーマ

今どきのかっこいいデザインのテーマを探したら、これが一番今っぽかったのでShapelyテーマを使います。無料です。
Shapely - One Page WordPress Theme - Colorlib

背景が前景と独立して動いて立体感を感じさせるデザインを、「Parallax」と言うそうです。
ここ4年ぐらい主流になっている(けれど、Windows8などのせいで評判の悪い)デザイン手法をフラットデザインと呼ぶそうです。
つまり、Parallaxでフラットデザインにしておけば、今っぽく見えます。

中身を薄く写真で格好良く見せる必要がありますので、WEBページを作る前に良いカメラで良い写真をいっぱい撮って集めておいてください。

コマンド方式サーボモータのコマンド体系の研究

(編集中)
日本国内でよく使われているコマンド方式サーボモータのコマンド体系を調べて、良い方法を探ります。

1. 近藤科学

kondo-robot.com

送信コマンド
CMD + SC + 3~N-1(DATA)

返値
CMD + SC + 3~N-1(DATA) + R_CMD + SC + DATA(SPD)

SCはサブコマンドの略らしい。
チェックサムは、なし。
単純を目指しているようですが、いろいろなバージョンがありあまり整理されていない感じ。

2. FUTABA

www.futaba.co.jp

送信パケット
Header + ID + Flag + Address + Length + Count + Data + Checksum

リターンパケット
Header + ID + Flags + Address + Length + Count + Data + Sum

チェックサムは、
Check Sum=ID XOR Flag XOR Address XOR Count XOR Data

比較的使いやすい命令体系だと思いますが、イレギュラーな書式があったり、メモリ上のデータの配置が悪かったりして、ちょっと痒さが残る感じ。

3. Robotis-DYNAMIXEL

Dynamixel

命令コマンド
0xFF + 0xFF + ID + LENGTH + INSTRUCTION + PARAMETER1 + ・・・ + PARAMETER_N + CHECK_SUM

返信コマンド
0xFF + 0xFF + ID + LENGTH + ERROR + PARAMTER1 + PARAMTER2 + ・・・ + PARAMETER_N + CHECK_SUM

チェックサムは、
Check Sum=~(ID + Length + Instruction + Parameter1 + ・・・ + Parameter_N)
~はNOT Bit演算子。素直な足し算方式なので、パラメータの順番の入れ替わりに弱い。

命令体系やメモリ上のデータの並びはとても整理されていて、よくできています。
真似をするならコレですかね。


RS485
第125号(2010年11月2日発行) 技術レポート「RS-485の通信プロトコルについて」|ソフテックだより|株式会社ソフテック

チェックサムの例(単純足し算)
http://www.cypress.com/file/250776/download

特性の分からない3相DCブラシレスモーターをソフトウェアエンコーダを搭載したTiのマイコンボードLAUNCHXL-F28069MとモータドライバBOOSTXL-DRV8305EVMを使って動かす(その6)

(編集中)
アナログ入出力だけでなく、シリアル接続なども使えた方がシステム構築には便利です。
ただ、C2000シリーズのマイコンでSCI(UART)接続しようというのは、Linuxの10倍ぐらい面倒くさいです。

Githubからサンプルプログラム

LAUNCHXL-F28027F+BOOSTXL-DRV8305EVMの組み合わせで、SCI(UART)を使うサンプルプロジェクトとして、こちらの掲示板の
InstaSPIN F28069MPZT : how to use UART/SCI communication to terminal? - InstaSPIN Motor Solutions Forum - C2000™ Microcontrollers - TI E2E Community
のスレッドで紹介されているAndrew Buckinさんのproj_lab05aの改造版
github.com
を参照すると、理解が早そうです。

ソースコードのdiffを取って、変更箇所を見ていきましょう。6つのソースファイルがあります。

proj_lab05a.c
hal/hal.c
hal/hal.h
hal/hal_obj.h
sci/sci.c
sci/sci.h

比較元のファイルの場所は、次の通りです。
C:\ti\motorware\motorware_1_01_00_16\sw\solutions\instaspin_foc\src
C:\ti\motorware\motorware_1_01_00_16\sw\modules\hal\boards\boostxldrv8305_revA\f28x\f2806x\src
C:\ti\motorware\motorware_1_01_00_16\sw\drivers\sci\src\32b\f28x\f2802x

proj_lab05a.c

// **************************************************************************
// the defines

#define uint8_t char

#define ECHO_ON 1 // set 1 to show input and 0 to disable it

#define LED_BLINK_FREQ_Hz   5

#define BUF_LEN 8 // length of the command buffer


// **************************************************************************
// the globals

uint32_t ECap1IntCount = 0;
uint32_t CAP_DATA[] = {0,0/*,0,0*/};

char cmdBuf[BUF_LEN]; // Input/command buffer
uint8_t bufPos = 0; // Position of the next char in the buffer
uint8_t cmdReady = 0; // Indicates that a command is ready for execution and blocks further input until reset to 0.

//Added by Maya
#ifdef SCI
	char * msg;
	uint16_t ReceivedChar = 0;
	//uint16_t RXISRCount = 0;
	//uint16_t SysCounter = 0;

#endif
//Added by Maya
#ifdef SCI

interrupt void sciaISR(void) {
	//RXISRCount++;

	ReceivedChar = HAL_sciaRead(halHandle) & 0x00FF;

	//Handling escape.
	if(ReceivedChar != 27){
		//Handling carriage return/new line.
		if(ReceivedChar != '\r' && ReceivedChar != '\n' && cmdReady == 0){
			//Show input.
			if(ECHO_ON){
				HAL_sciaWrite(halHandle, ReceivedChar);
			}
			//Handling backspace/delete.
			if(ReceivedChar != 127 && ReceivedChar != 8){
				bufPos++;
				//If the end of the buffer wasn't reached, add new char to the buffer.
				if(bufPos < BUF_LEN){
					cmdBuf[bufPos-1] = (char)ReceivedChar; //Adding char.
					cmdBuf[bufPos] = '\0'; //Appending null to indicate the end of the string.
				}
			}else{
				//If the beginning of the buffer wasn't reached, remove the previous char from the buffer.
				if(bufPos > 0){
					bufPos--;
					//Only delete if within buffer range.
					if(bufPos < BUF_LEN){
						cmdBuf[bufPos] = '\0';
					}
				}
			}
		}else if(cmdReady == 0){ //If enter was pressed, start new line and set cmdReady flag.
			msg = "\n\r";
			HAL_sciaWriteMsg(halHandle, msg);
			cmdReady = 1;
		}
	}else{ //If escape is pressed, reset command buffer and clear cmdReady flag.
		cmdReady = 0;
		bufPos = 0;
		cmdBuf[0] = '\0';
	}

	HAL_sciaClearRxFifoOvf(halHandle);
	HAL_sciaClearRxFifoInt(halHandle);

	HAL_pieAckInt(halHandle,PIE_GroupNumber_9);		// Issue PIE ack INT9

	return;
}

#endif
//Added by Dmitri Ranfft on 16.09.2015
#ifdef CAP
__interrupt void ecap1ISR(void)
{
	//scia_msg("interrupt\n\r");
    // Cap input is syc'ed to SYSCLKOUT so there may be
    // a +/- 1 cycle variation

	CAP_DATA[0] = CAP_getCap1(halHandle->capHandle);
	CAP_DATA[1] = CAP_getCap2(halHandle->capHandle);
	//CAP_DATA[2] = CAP_getCap3(halHandle->capHandle);
	//CAP_DATA[3] = CAP_getCap4(halHandle->capHandle);

    ECap1IntCount++;

    CAP_clearInt(halHandle->capHandle, CAP_Int_Type_CEVT2);
    CAP_clearInt(halHandle->capHandle, CAP_Int_Type_Global);
    CAP_rearm(halHandle->capHandle);

    // Acknowledge this interrupt to receive more interrupts from group 4
    PIE_clearInt(halHandle->pieHandle, PIE_GroupNumber_4);
}
#endif

eCAPというのが、また聞きなれないC2000特有の機能で、こちらに解説があります。
C2000の便利なeCAP機能を使って見ましょう - プロセッサ(DSP / ARM / MCU) - Japanese E2E (日本語コミュニティ) - TI E2E Community

hal

hal.c

607--609

  // Added by Dmitri Ranfft on 16.09.2015
  // Initialize the eCAP
  obj->capHandle = CAP_init((void *)CAP1_BASE_ADDR, sizeof(CAP_Obj));

652--656

  //Added by Maya
  #ifdef SCI
  	// Init SCI A registers
  	obj->sciaHandle = SCI_init((void *) SCIA_BASE_ADDR, sizeof(SCI_Obj));
  #endif

787--795

 //Added by Maya
#ifdef SCI
 HAL_setupSCI(handle);
#endif

 //Added by Dmitri Ranfft on 16.09.2015
#ifdef CAP
 HAL_setupCAP(handle);
#endif

994--1020

  // PWMC_H
  // Edited by Dmitri Ranfft on 16.09.2015 (changed from EPWM3 to 4)
  GPIO_setMode(obj->gpioHandle,GPIO_Number_6,GPIO_6_Mode_EPWM4A);

  // PWMC_L
  // Edited by Dmitri Ranfft on 16.09.2015 (changed from EPWM3 to 4)
  GPIO_setMode(obj->gpioHandle,GPIO_Number_7,GPIO_7_Mode_EPWM4B);

  // eCAP1
  // Added by Dmitri Ranfft on 16.09.2015
  GPIO_setPullUp(obj->gpioHandle, GPIO_Number_5, GPIO_PullUp_Enable);
  GPIO_setQualification(obj->gpioHandle, GPIO_Number_5, GPIO_Qual_Sync);
  GPIO_setMode(obj->gpioHandle,GPIO_Number_5,GPIO_5_Mode_ECAP1);

    // EN_GATE
  // Edited by Dmitri Ranfft on 16.09.2015 (changed from GPIO 6 to 4)
  GPIO_setMode(obj->gpioHandle,GPIO_Number_4,GPIO_4_Mode_GeneralPurpose);
  GPIO_setLow(obj->gpioHandle,GPIO_Number_4);
  GPIO_setDirection(obj->gpioHandle,GPIO_Number_4,GPIO_Direction_Output);
  
    // WAKE
  // Edited by Dmitri Ranfft on 16.09.2015 (changed from GPIO 7 to 12)
  GPIO_setMode(obj->gpioHandle,GPIO_Number_12,GPIO_12_Mode_GeneralPurpose);
  GPIO_setHigh(obj->gpioHandle,GPIO_Number_12);
  GPIO_setDirection(obj->gpioHandle,GPIO_Number_12,GPIO_Direction_Output);

  // No Connection
  // Disabled by Dmitri Ranfft on 16.09.2015
  //GPIO_setMode(obj->gpioHandle,GPIO_Number_12,GPIO_12_Mode_GeneralPurpose);

修正前は、

  // PWMC_H
  GPIO_setMode(obj->gpioHandle,GPIO_Number_4,GPIO_4_Mode_EPWM3A);

  // PWMC_L
  GPIO_setMode(obj->gpioHandle,GPIO_Number_5,GPIO_5_Mode_EPWM3B);

    // EN_GATE
  GPIO_setMode(obj->gpioHandle,GPIO_Number_6,GPIO_6_Mode_GeneralPurpose);
  GPIO_setLow(obj->gpioHandle,GPIO_Number_6);
  GPIO_setDirection(obj->gpioHandle,GPIO_Number_6,GPIO_Direction_Output);
  
    // WAKE
  GPIO_setMode(obj->gpioHandle,GPIO_Number_7,GPIO_7_Mode_GeneralPurpose);
  GPIO_setHigh(obj->gpioHandle,GPIO_Number_7);
  GPIO_setDirection(obj->gpioHandle,GPIO_Number_7,GPIO_Direction_Output);

  // No Connection
  GPIO_setMode(obj->gpioHandle,GPIO_Number_12,GPIO_12_Mode_GeneralPurpose);

1037--1045

  // nFAULT
  //GPIO_setMode(obj->gpioHandle,GPIO_Number_28,GPIO_28_Mode_TZ2_NOT); // Edited by Dmitri Ranfft on 15.09.2015
  // SCI_RX
  GPIO_setMode(obj->gpioHandle,GPIO_Number_28,GPIO_28_Mode_SCIRXDA);

  // No connection (TX)
  //GPIO_setMode(obj->gpioHandle,GPIO_Number_29,GPIO_29_Mode_GeneralPurpose); // Edited by Dmitri Ranfft on 15.09.2015
  // SCI_TX
  GPIO_setMode(obj->gpioHandle,GPIO_Number_29,GPIO_29_Mode_SCITXDA);

修正前は、

  // nFAULT
  GPIO_setMode(obj->gpioHandle,GPIO_Number_28,GPIO_28_Mode_TZ2_NOT);

  // No connection (TX)
  GPIO_setMode(obj->gpioHandle,GPIO_Number_29,GPIO_29_Mode_GeneralPurpose);

1348--1502

//Added by Maya
void HAL_setupSCI(HAL_Handle handle) {
#ifdef SCI
	HAL_Obj *obj = (HAL_Obj *) handle;
	char *msg;
	//FIFO
	// SCIFFTX = 0xE040
		SCI_enableChannels(obj->sciaHandle);			// SCI reset
		SCI_enableTxFifoEnh(obj->sciaHandle);		// SCI FIFO transmit enable
		SCI_enableTxFifo(obj->sciaHandle);			// SCI FIFO transmit reset/reenable
		SCI_clearTxFifoInt(obj->sciaHandle);			// SCI clear FIFO transmit interrupt flag
		SCI_disableTxFifoInt(obj->sciaHandle);		// disable FIFO transmit interrupt
		SCI_setTxFifoIntLevel(obj->sciaHandle, SCI_FifoLevel_Empty);	// FIFO interrupt level
		// SCIFFRX = 0x2041
		SCI_enableRxFifo(obj->sciaHandle);			// SCI FIFO receive reset/reenable
		SCI_clearRxFifoInt(obj->sciaHandle);			// SCI clear FIFO receive interrupt flag
		SCI_disableRxFifoInt(obj->sciaHandle);		// disable FIFO receive interrupt
		SCI_setRxFifoIntLevel(obj->sciaHandle, SCI_FifoLevel_1_Word); // FIFO interrupt level

		SCI_enableRxFifoInt(obj->sciaHandle);

	// SCI stop bit, parity, loopback, char bits, idle/address mode (SCICCR = 0x07)
	SCI_setNumStopBits(obj->sciaHandle, SCI_NumStopBits_One);	// SCICCR bit 7
	SCI_setParity(obj->sciaHandle, SCI_Parity_Odd);				// SCICCR bit 6
	SCI_disableParity(obj->sciaHandle);							// SCICCR bit 5
	//SCI_enableParity(obj->sciaHandle);
	SCI_disableLoopBack(obj->sciaHandle);						// SCICCR bit 4
	SCI_setMode(obj->sciaHandle, SCI_Mode_IdleLine);			// SCICCR bit 3
	SCI_setCharLength(obj->sciaHandle, SCI_CharLength_8_Bits);// SCICCR bit 0-2

	// TX enable, RX enable, RX ERR INT enable, SLEEP, TXWAKE (SCICTL1 = 0x03)
	SCI_disableRxErrorInt(obj->sciaHandle);						// SCICTL1 bit 6
	SCI_disable(obj->sciaHandle);								// SCICTL1 bit 5
	SCI_disableTxWake(obj->sciaHandle);							// SCICTL1 bit 3
	SCI_disableSleep(obj->sciaHandle);							// SCICTL1 bit 2
	SCI_enableTx(obj->sciaHandle);								// SCICTL1 bit 1
	SCI_enableRx(obj->sciaHandle);								// SCICTL1 bit 0

	// TXINT enable, RXINT enable, TXEMPTY, TXRDY (SCICTL2 = 0x03)
	SCI_enableRxInt(obj->sciaHandle);							// SCICTL2 bit 1
	SCI_disableTxInt(obj->sciaHandle);							// SCICTL2 bit 0

	// SCIH-SCIL BAUD - SCI_BAUD = (LSPCLK/(SCI_BRR*8)) - 1
	SCI_setBaudRate(obj->sciaHandle, SCI_BaudRate_9_6_kBaud);

	// Reset SCI
	SCI_enable(obj->sciaHandle);

	msg = "\r\n\n  ********** SCI setup is done! **********\0";
	SCI_writeMsg(obj->sciaHandle, msg);
	//PIE_enableSciInt(obj->pieHandle, SCI_RXA);	// enable SCI interrupt
	PIE_enableInt(halHandle->pieHandle, PIE_GroupNumber_9, PIE_InterruptSource_SCIARX);
	CPU_enableInt(obj->cpuHandle, CPU_IntNumber_9);	// enable CPU interrupt

#endif // of SCI
}
#ifdef SCI
//Added by Maya
//SCIA
SCI_FifoStatus_e HAL_sciaGetRxFifoStatus(HAL_Handle handle) {
	HAL_Obj *obj = (HAL_Obj *) handle;
	return (SCI_getRxFifoStatus(obj->sciaHandle));
} // end of HAL_scigetRXFIFOStatus() function
//Added by Maya
void HAL_sciaWrite(HAL_Handle handle, const uint16_t data) {
	HAL_Obj *obj = (HAL_Obj *) handle;

	SCI_write(obj->sciaHandle, data);
}
//Added by Maya
void HAL_sciaWriteMsg(HAL_Handle handle, char * msg) {
	HAL_Obj *obj = (HAL_Obj *) handle;

	SCI_writeMsg(obj->sciaHandle, msg);
}
//Added by Maya
uint16_t HAL_sciaRead(HAL_Handle handle) {
	HAL_Obj *obj = (HAL_Obj *) handle;

	return (SCI_read(obj->sciaHandle));
}
//Added by Maya
void HAL_sciaClearRxFifoOvf(HAL_Handle handle) {
	HAL_Obj *obj = (HAL_Obj *) handle;
	SCI_clearRxFifoOvf(obj->sciaHandle);
}
//Added by Maya
void HAL_sciaClearRxFifoInt(HAL_Handle handle) {
	HAL_Obj *obj = (HAL_Obj *) handle;
	SCI_clearRxFifoInt(obj->sciaHandle);
}
//Added by Maya
void HAL_sciaClearTxFifoInt(HAL_Handle handle) {
	HAL_Obj *obj = (HAL_Obj *) handle;
	SCI_clearTxFifoInt(obj->sciaHandle);
}
void HAL_sciaEnableRxInt(HAL_Handle handle) {
	HAL_Obj *obj = (HAL_Obj *) handle;
	SCI_enableRxInt(obj->sciaHandle);
}
void HAL_sciaDisableRxInt(HAL_Handle handle) {
	HAL_Obj *obj = (HAL_Obj *) handle;
	SCI_disableRxInt(obj->sciaHandle);
}
void HAL_sciaEnableTxInt(HAL_Handle handle) {

	HAL_Obj *obj = (HAL_Obj *) handle;
	SCI_enableTxInt(obj->sciaHandle);
}
void HAL_sciaDisableTxInt(HAL_Handle handle) {
	HAL_Obj *obj = (HAL_Obj *) handle;
	SCI_disableTxInt(obj->sciaHandle);
}
bool HAL_sciaTxReady(HAL_Handle handle) {
	HAL_Obj *obj = (HAL_Obj *) handle;
	return (SCI_txReady(obj->sciaHandle));
}
bool HAL_sciaTxEmpty(HAL_Handle handle) {
	HAL_Obj *obj = (HAL_Obj *) handle;
	return (SCI_txEmpty(obj->sciaHandle));
}
bool HAL_sciaRxParityError(HAL_Handle handle) {
	HAL_Obj *obj = (HAL_Obj *) handle;
	return (SCI_rxParityError(obj->sciaHandle));
}
bool HAL_sciaRxOverrunError(HAL_Handle handle) {
	HAL_Obj *obj = (HAL_Obj *) handle;
	return (SCI_rxOverrunError(obj->sciaHandle));
}
bool HAL_sciaRxFrameError(HAL_Handle handle) {
	HAL_Obj *obj = (HAL_Obj *) handle;
	return (SCI_rxFrameError(obj->sciaHandle));
}
void HAL_sciaEnable(HAL_Handle handle) {
	HAL_Obj *obj = (HAL_Obj *) handle;
	SCI_enable(obj->sciaHandle);
}
void HAL_sciaDisable(HAL_Handle handle) {
	HAL_Obj *obj = (HAL_Obj *) handle;
	SCI_disable(obj->sciaHandle);
}
#endif //End of SCI
//Added by Maya, for PIE
void HAL_pieAckInt(HAL_Handle handle, const PIE_GroupNumber_e groupNumber) {
	HAL_Obj *obj = (HAL_Obj *) handle;
	PIE_clearInt(obj->pieHandle, groupNumber);
}
void HAL_enablePieInt(HAL_Handle handle) {
	HAL_Obj *obj = (HAL_Obj *) handle;
	PIE_enable(obj->pieHandle);
}
void HAL_disablePieInt(HAL_Handle handle) {
	HAL_Obj *obj = (HAL_Obj *) handle;
	PIE_disable(obj->pieHandle);
}

1513--1556

// Added by Dmitri Ranfft on 16.09.2015
void HAL_setupCAP(HAL_Handle handle)
{
#ifdef CAP
	HAL_Obj *obj = (HAL_Obj *) handle;
    CLK_enableEcap1Clock(obj->clkHandle);

    CAP_disableInt(obj->capHandle, CAP_Int_Type_All);    // Disable all capture interrupts
    CAP_clearInt(obj->capHandle, CAP_Int_Type_All);      // Clear all CAP interrupt flags
    CAP_disableCaptureLoad(obj->capHandle);              // Disable CAP1-CAP4 register loads
    CAP_disableTimestampCounter(obj->capHandle);         // Make sure the counter is stopped

    // Configure peripheral registers
    //CAP_setCapOneShot(obj->capHandle);                   // One-shot
    CAP_setCapContinuous(obj->capHandle);
    CAP_setStopWrap(obj->capHandle, CAP_Stop_Wrap_CEVT2);// Stop at 4 events
    CAP_setCapEvtPolarity(obj->capHandle, CAP_Event_1, CAP_Polarity_Rising);    // Falling edge
    CAP_setCapEvtPolarity(obj->capHandle, CAP_Event_2, CAP_Polarity_Falling);     // Rising edge
    //CAP_setCapEvtPolarity(obj->capHandle, CAP_Event_3, CAP_Polarity_Rising);    // Falling edge
    //CAP_setCapEvtPolarity(obj->capHandle, CAP_Event_4, CAP_Polarity_Falling);     // Rising edge

    CAP_setCapEvtReset(obj->capHandle, CAP_Event_1, CAP_Reset_Enable);   // Difference operation
    CAP_setCapEvtReset(obj->capHandle, CAP_Event_2, CAP_Reset_Enable);   // Difference operation
    //CAP_setCapEvtReset(obj->capHandle, CAP_Event_3, CAP_Reset_Enable);   // Difference operation
    //CAP_setCapEvtReset(obj->capHandle, CAP_Event_4, CAP_Reset_Enable);   // Difference operation

    CAP_enableSyncIn(obj->capHandle);                    // Enable sync in
    CAP_setSyncOut(obj->capHandle, CAP_SyncOut_SyncIn);  // Pass through

    CAP_enableCaptureLoad(obj->capHandle);

    CAP_enableTimestampCounter(obj->capHandle);          // Start Counter
    //CAP_rearm(obj->capHandle);                           // arm one-shot
    CAP_enableCaptureLoad(obj->capHandle);               // Enable CAP1-CAP4 register loads
    CAP_enableInt(obj->capHandle, CAP_Int_Type_CEVT2);   // 4 events = interrupt



    // Enable CPU INT4 which is connected to ECAP1-4 INT:
    CPU_enableInt(obj->cpuHandle, CPU_IntNumber_4);
    // Enable eCAP INTn in the PIE: Group 3 interrupt 1-6
    PIE_enableCaptureInt(obj->pieHandle);
#endif
}
hal.h

166--173

//Added by Maya
#ifdef SCI
	extern interrupt void sciaISR(void);
#endif
//Added by Dmitri Ranfft on 16.09.2015
#ifdef CAP
	extern __interrupt void ecap1ISR(void);
#endif

487--496

  //Added by Maya
#ifdef SCI
  pie->SCIRXINTA = &sciaISR;
#endif

  //Added by Dmitri Ranfft on 16.09.2015
#ifdef CAP
  pie->ECAP1_INT = &ecap1ISR;
  //PIE_registerPieIntHandler(obj->pieHandle, PIE_GroupNumber_4, PIE_SubGroupNumber_1, (intVec_t)&ecap1ISR);
#endif

1306--1333

// Added by Maya
extern HAL_Handle halHandle;
extern void HAL_setupSCI(HAL_Handle handle);
//SCIA
extern SCI_FifoStatus_e HAL_sciaGetRxFifoStatus(HAL_Handle handle);
extern void HAL_sciaWrite(HAL_Handle handle, const uint16_t data);
extern void HAL_sciaWriteMsg(HAL_Handle handle, char * msg);
extern uint16_t HAL_sciaRead(HAL_Handle handle);
extern void HAL_sciaClearRxFifoOvf(HAL_Handle handle);
extern void HAL_sciaClearRxFifoInt(HAL_Handle handle);
extern void HAL_sciaClearTxFifoInt(HAL_Handle handle);
extern void HAL_sciaEnableRxInt(HAL_Handle handle);
extern void HAL_sciaDisableRxInt(HAL_Handle handle);
extern void HAL_sciaEnableTxInt(HAL_Handle handle);
extern void HAL_sciaDisableTxInt(HAL_Handle handle);
extern bool HAL_sciaTxReady(HAL_Handle handle);
extern bool HAL_sciaTxEmpty(HAL_Handle handle);
extern bool HAL_sciaRxParityError(HAL_Handle handle);
extern bool HAL_sciaRxOverrunError(HAL_Handle handle);
extern bool HAL_sciaRxFrameError(HAL_Handle handle);
extern void HAL_sciaEnable(HAL_Handle handle);
extern void HAL_sciaDisable(HAL_Handle handle);
// Added by Maya
extern void HAL_pieAckInt(HAL_Handle handle, const PIE_GroupNumber_e groupNumber);
extern void HAL_enablePieInt(HAL_Handle handle);

// Added by Dmitri Ranfft on 16.09.2015
extern void HAL_setupCAP(HAL_Handle handle);
hal_obj.h

41--60

// drivers
#include "sw/drivers/adc/src/32b/f28x/f2802x/adc.h"
#include "sw/drivers/cap/src/32b/f28x/f2802x/cap.h" // Added by Dmitri Ranfft on 16.09.2015
#include "sw/drivers/clk/src/32b/f28x/f2802x/clk.h"
#include "sw/drivers/cpu/src/32b/f28x/f2802x/cpu.h"
#include "sw/drivers/flash/src/32b/f28x/f2802x/flash.h"
#include "sw/drivers/gpio/src/32b/f28x/f2802x/gpio.h"
#include "sw/drivers/osc/src/32b/f28x/f2802x/osc.h"
#include "sw/drivers/pie/src/32b/f28x/f2802x/pie.h"
#include "sw/drivers/pll/src/32b/f28x/f2802x/pll.h"
#include "sw/drivers/pwm/src/32b/f28x/f2802x/pwm.h"
#include "sw/drivers/pwmdac/src/32b/f28x/f2802x/pwmdac.h"
#include "sw/drivers/pwr/src/32b/f28x/f2802x/pwr.h"
#include "sw/drivers/spi/src/32b/f28x/f2802x/spi.h"
#include "sw/drivers/timer/src/32b/f28x/f2802x/timer.h"
#include "sw/drivers/wdog/src/32b/f28x/f2802x/wdog.h"
#include "sw/drivers/drvic/drv8305/src/32b/f28x/f2802x/drv8305.h"
//Added by Maya
//#include "sw/drivers/sci/src/32b/f28x/f2802x/sci.h"
#include "sci.h"

131-133

  //Added by Dmitri Ranfft on 16.09.2015
  CAP_Handle    capHandle;        //!< the eCAP handle

173

 SCI_Handle    sciaHandle;       //!< the sci handle, added by Maya

sci

sci.c

同一ファイルです。

sci.h

369--376

//Added by Maya
typedef enum
{
  SCI_RXA=0,      		//!< Denotes SCI receive A
  SCI_TXA=1,     			//!< Denotes SCI transmit A
  SCI_RXB=2,    			//!< Denotes SCI receive B
  SCI_TXB=3   			//!< Denotes SCI transmit B
} SCI_Type_e;

728--731 in static inline void SCI_write(SCI_Handle sciHandle,const uint16_t data)

  //Added by Maya
 #ifdef SCI_FIFO
   while(SCI_getTxFifoStatus(sciHandle) != 0) {};
 #endif

739--792

// Added by Maya
static inline bool SCI_txEmpty(SCI_Handle sciHandle)
{
  SCI_Obj *sci = (SCI_Obj *)sciHandle;
  bool status;

  status = (sci->SCICTL2 & SCI_SCICTL2_TXEMPTY_BITS) >> 6;

  return((bool)status);
} // end of SCI_txEmpty() function

//Added by Maya
static inline void SCI_writeMsg(SCI_Handle sciHandle, char * msg)
{
    int i;
    i = 0;
    while(msg[i] != '\0')
    {
    	SCI_write(sciHandle, msg[i]);
        i++;
    }
}

static inline bool SCI_rxParityError(SCI_Handle sciHandle)
{
  SCI_Obj *sci = (SCI_Obj *)sciHandle;
  bool status;

  status = (sci->SCIRXST & SCI_SCIRXST_PE_BITS) >> 2;

  return((bool)status);
} // end of SCI_rxParityError() function

static inline bool SCI_rxOverrunError(SCI_Handle sciHandle)
{
  SCI_Obj *sci = (SCI_Obj *)sciHandle;
  bool status;

  status = (sci->SCIRXST & SCI_SCIRXST_OE_BITS) >> 3;

  return((bool)status);
} // end of SCI_rxParityError() function

static inline bool SCI_rxFrameError(SCI_Handle sciHandle)
{
  SCI_Obj *sci = (SCI_Obj *)sciHandle;
  bool status;

  status = (sci->SCIRXST & SCI_SCIRXST_FE_BITS) >> 4;

  return((bool)status);
} // end of SCI_rxParityError() function

//End of addition by Maya

見比べる

差分の抽出が済みましたので、見比べていきましょう。
ピン変更までしてeCAPとやらを何に使っているのか、よくわかりませんね???
SCIを使うためには、基本的にMayaさんの変更箇所を見ていけばよいようです。
たかがシリアルで、こんなに面倒くさいと、このマイコン開発にリソースを割いていていいのかどうか不安になります。

動かして確認してみる

Mayaさんのコメント部分を自分のソースコードにコピーペーストし、sci.hとsci.cをプロジェクトに追加します。
また、sci.hの最初の方に

#define SCI 1

を書き加えます。

シリアル接続を確認するために、teratermでUSB COMPortに接続し、9600bpsの速度に設定します。
デバッグモードでFlashにproj_lab05b.outをアップロードすると、
"\r\n\n ********** SCI setup is done! **********\0";
の文字が表示されるはずなのですが、最初の3文字ぐらいしか出ません。

 ***9

ただ、何かは応答してくれているようです。
キーボードで文字を入力すると、エコーバックされてteraterm上に表示されます。BackSpaceキーを押すとカーソルが一つ戻ります。
Enterキーを押すと、ロックされた状態になりますが、Escを押すと、再び入力可能な状態になります。

ちゃんと動いているようですね。

FIFOを有効にして、通信欠落を減らす

sci.hのdefinesの中に
#define SCI 1
に加えて
#define SCI_FIFO 1
を追加します.

ところが、メモリの初期化がうまくいかずに起動直後はFIFOにゴミがあり、これを吐き出させる前にhal.cの中で文字列を出力させる次の2行を実行すると、わけのわからないゴミを延々と吐き続けて、クリアできないという状況に陥ります。
なので、この2行をコメントアウトします。

msg = "\r\n\n  ********** SCI setup is done! **********\0";
	SCI_writeMsg(obj->sciaHandle, msg);

sciaISRが回り始めた当初はまだゴミを少し吐くので、これを吐き出させた後に通信に使用するとうまい行くようです。
残念ながら、sci.hに定義されたどのコマンドを用いても、起動直後のバッファのゴミを削除することができませんでした。

重要な知見

LAUNCHXL-F28027F 不推奨のススメ

LAUNCHXL-F28027FにBOOSTXL-DRV8305EVM経由で電源を供給したときに、うまく初期化できません。外部リセットを行う以外の解決方法が見つかりません。
したがって、組み込み用途で使用するときに、大変不便します。

LAUNCHXL-F28027Fは、メモリ上での開発ができずコンパイルしたバイナリを毎回Flashメモリに焼きこむ必要があります。
ところが、フラッシュの耐久性の問題か、ロムライタのソフトウェアの問題か50回もしないうちに書き込み不可能になってしまいます。
書き込み不可能になったマイコンボードは捨てるしかほかありませんので、コンパイル50回毎に2000円が飛んでいくことになります。
C2000PiccoloシリーズおよびInstaSPINは、かなり特殊なソフトウェア体系(整理されてない)ので、ある程度使えるエキスパートになるまでには相当な時間がかかります。

同じシリーズの上位機種LAUNCHXL-F28069Mはとりあえずこれらの問題はありませんので、サイズはデカいですが値段はあまり変わらないのでこちらを推奨します。

SCI受信割り込み(例えば、SCIRXINTに紐づけられたsciaISR)の中で一文字たりとも送信してはいけない

まれにモータの制御が飛び一瞬停止するなど異常動作を起こすので、大暴走して事故の原因になりかねません。
本来、SCITXINTを有効にして、適切な送信割り込みを掛けるべきなのだと思いますが、すると今度はモータ制御がうまく行かなくなります。まだ原因が特定できません。
main関数のforeverループの中でループ一回に一文字づつ送るなどの方が無難なようです。mainISRではありません。mainISRは、adcの割り込みの呼び出し先です。
文字列長など、セグメンテーションエラーを起こさないように十分留意してください。

//Added by Maya
#ifdef SCI

interrupt void sciaISR(void) {
	//RXISRCount++;

	ReceivedChar = HAL_sciaRead(halHandle) & 0x00FF;

	//Handling escape.
	if(ReceivedChar != 27){
		//Handling carriage return/new line.
		if(ReceivedChar != '\r' && ReceivedChar != '\n' && cmdReady == 0){
			//Show input.
			if(ECHO_ON){
				// \HAL_sciaWrite(halHandle, ReceivedChar); ///// Caution! Danger!
			}
			//Handling backspace/delete.
			if(ReceivedChar != 127 && ReceivedChar != 8){
				bufPos++;
				//If the end of the buffer wasn't reached, add new char to the buffer.
				if(bufPos < BUF_LEN){
					cmdBuf[bufPos-1] = (char)ReceivedChar; //Adding char.
					cmdBuf[bufPos] = '\0'; //Appending null to indicate the end of the string.
				}
			}else{
				//If the beginning of the buffer wasn't reached, remove the previous char from the buffer.
				if(bufPos > 0){
					bufPos--;
					//Only delete if within buffer range.
					if(bufPos < BUF_LEN){
						cmdBuf[bufPos] = '\0';
					}
				}
			}
		}else if(cmdReady == 0){ //If enter was pressed, start new line and set cmdReady flag.
			msg = "\n\r";
			// HAL_sciaWriteMsg(halHandle, msg); ///// Caution! Danger!
			cmdReady = 1;
		}
	}else{ //If escape is pressed, reset command buffer and clear cmdReady flag.
		cmdReady = 0;
		bufPos = 0;
		cmdBuf[0] = '\0';
	}

	HAL_sciaClearRxFifoOvf(halHandle);
	HAL_sciaClearRxFifoInt(halHandle);

	HAL_pieAckInt(halHandle,PIE_GroupNumber_9);		// Issue PIE ack INT9

	return;
}

#endif

今日の友達がいない漫画

タイトルに反して、主人公湯神くんの周りには登場人物多い。