TI社のBLDCモータードライバDRV8301を コントロールするためのユーティリティのようなクラスです。 できるだけユーザーにわかりやすく レジスタの設定・読み取りなどを行います。 尚、データシートは必須の模様。
Dependents: BLDC1Axis_DRV8301CTRL
DRV8301CTRL.cpp
- Committer:
- Yajirushi
- Date:
- 2016-08-31
- Revision:
- 0:72d833823fd5
File content as of revision 0:72d833823fd5:
#include "DRV8301CTRL.h" //ショートカット #define DRV8301_CS_ACTIVE cs->write(0) #define DRV8301_CS_INACTIVE cs->write(1) #define DRV8301_GATE_ACTIVE gate->write(1) #define DRV8301_GATE_INACTIVE gate->write(0) //コンストラクタ(オーバーロード +3) ================================= /* * シリアルとSPIのアドレス、CSとEN_GATEのピンネームを指定してインスタンスを生成 */ drv8301ctrl::drv8301ctrl(Serial *serial, SPI *spi, PinName csel, PinName en_gate){ pc = serial; si = spi; cs = new DigitalOut(csel); gate = new DigitalOut(en_gate); hasSerial = !(pc == NULL); } //コンストラクタ(オーバーロード +3) ================================= /* * シリアルとSPIのアドレス、CSとEN_GATEのアドレスを指定してインスタンスを生成 */ drv8301ctrl::drv8301ctrl(Serial *serial, SPI *spi, DigitalOut *csel, DigitalOut *en_gate){ pc = serial; si = spi; cs = csel; gate = en_gate; hasSerial = !(pc == NULL); } //コンストラクタ(オーバーロード +3) ================================= /* * SPIのアドレス、CSとEN_GATEのピンネームを指定してインスタンスを生成 * この場合、デバッグ(シリアルでのSPI通信内容の出力)は使用できない */ drv8301ctrl::drv8301ctrl(SPI *spi, PinName csel, PinName en_gate){ si = spi; cs = new DigitalOut(csel); gate = new DigitalOut(en_gate); hasSerial = false; } //コンストラクタ(オーバーロード +3) ================================= /* * SPIのアドレス、CSとEN_GATEのアドレスを指定してインスタンスを生成 * この場合、デバッグ(シリアルでのSPI通信内容の出力)は使用できない */ drv8301ctrl::drv8301ctrl(SPI *spi, DigitalOut *csel, DigitalOut *en_gate){ si = spi; cs = csel; gate = en_gate; hasSerial = false; } //デストラクタ ================================================= drv8301ctrl::~drv8301ctrl(){ delete pc; delete si; delete cs; delete gate; } //private:SPIコマンド送信 ====================================== /* * SPIコマンドを送信し、DRV8301からの返答を受け取って返す * DRV8301は16bitの命令を送信した際、次回送信時に前回の返答を返す * つまり1回目でコマンドを送信し、2回目の空送信で返答を得る * * 引数debugを有効にした場合、SPIでのやりとりの内容をシリアルに出力する * 引数debugはデフォルトでtrue */ int drv8301ctrl::spi_cmd(int val, bool debug){ DRV8301_CS_ACTIVE; wait_us(1); //送信 si->write(val); wait_us(1); DRV8301_CS_INACTIVE; wait_us(1); DRV8301_CS_ACTIVE; //返答 int ret = si->write(0x0000); if(debug && hasSerial){ pc->printf("CS ACTIVE\r\n\tSPI SEND >>>> values = 0x%08x\r\n\tRECEIVE <<<< return = 0x%08x\r\nCS INACTIVE\r\n", val, ret); } wait_us(1); DRV8301_CS_INACTIVE; wait_us(1); return ret; } //private:SPI関連の初期化とか ==================================== /* * SPIインターフェースの初期化およびDRV8301への初期化コマンドの送信 * * 引数reset_ifaceをfalseにすることでSPIインタフェースの初期化をスキップ * すでに外部でSPIインターフェースを使用している等の場合はfalseを指定 * 引数reset_ifaceはデフォルトでtrue * */ void drv8301ctrl::init(bool reset_iface){ //SPI初期化 if(reset_iface){ si->frequency(DRV8301CTRL_FREQ); si->format(16, 1); } //EN_GATEの状態をリセット gateReset(); //CS状態をセット DRV8301_CS_INACTIVE; //現在のレジスタ内容を出力 if(hasSerial){ pc->printf( "1\tSTATUS 1 NOW : 0x%08x, STATUS 2 NOW : 0x%08x\r\n", (spi_cmd(DRV8301REG_READMODE | DRV8301REG_STATUS1, false) & 0x07FF), (spi_cmd(DRV8301REG_READMODE | DRV8301REG_STATUS2, false) & 0x07FF) ); pc->printf( "1\tREGISTER 1 NOW : 0x%08x, REGISTER 2 NOW : 0x%08x\r\n", (spi_cmd(DRV8301REG_READMODE | DRV8301REG_CTRL1, false) & 0x07FF), (spi_cmd(DRV8301REG_READMODE | DRV8301REG_CTRL2, false) & 0x07FF) ); } //初期設定 /* * コントロールレジスタは、自分で格納用の値を作って列挙体の値を論理和でくっつけた後 * updateWriteValueやwriteCtrl(引数あり)で値を直接更新する方法と、 * クラスのメンバ変数が所持している値をメソッドで更新してから * writeCtrl1(引数なし)で更新する方法などがある。 * 基本的にはクラスメソッドで値を更新して、writeCtrlを引数なしで呼ぶことが妥当。 * * 下記の方法は前者。 */ unsigned short settingVal1 = GATE_CURRENT_PEAKCURRENT_1_7A | GATE_RESET_NORMAL | PWM_MODE_PWMLINES_3 | OCP_MODE_CURRENTLIMIT | OC_ADJ_SET_ADJUST_0_358 ; //上記をメソッド更新版で書いた場合 //setGATE_CURRENT(1.7f); //setGATE_RESET(true); //setPWM_MODE(false); //setOCP_MODE(0x00); //setOC_ADJ(0.358f); //初期設定内容を書き込む //メソッド更新のみで値を書き換えた場合は引数は不要 //writeCtrl1(); //メソッドで更新した場合 コントロールレジスタ1 //writeCtrl2(); //メソッドで更新した場合 コントロールレジスタ2 writeCtrl1(settingVal1); //コントロールレジスタ1 //現在のレジスタ内容を出力 if(hasSerial){ pc->printf( "2\tSTATUS 1 NOW : 0x%08x, STATUS 2 NOW : 0x%08x\r\n", (spi_cmd(DRV8301REG_READMODE | DRV8301REG_STATUS1, false) & 0x07FF), (spi_cmd(DRV8301REG_READMODE | DRV8301REG_STATUS2, false) & 0x07FF) ); pc->printf( "2\tREGISTER 1 NOW : 0x%08x, REGISTER 2 NOW : 0x%08x\r\n", (spi_cmd(DRV8301REG_READMODE | DRV8301REG_CTRL1, false) & 0x07FF), (spi_cmd(DRV8301REG_READMODE | DRV8301REG_CTRL2, false) & 0x07FF) ); } unsigned short settingVal2 = OCTW_MODE_REPORT_OT_OC_BOTH | SHUNTGAIN_GAIN_40V_PER_V | DC_CAL_CH1_ENABLE | DC_CAL_CH2_ENABLE | OC_TOFF_CYCLE_BY_CYCLE ; //上記をメソッド更新版で書いた場合 //setOCTW_MODE(0x00); //setGAIN(2); //setDC_CAL_CH1_Enabled(true); //setDC_CAL_CH2_Enabled(true); //setOC_TOFF_CycleByCycle(true); //初期設定内容を書き込む //メソッド更新のみで値を書き換えた場合は引数は不要 //writeCtrl1(); //メソッドで更新した場合 コントロールレジスタ1 //writeCtrl2(); //メソッドで更新した場合 コントロールレジスタ2 writeCtrl2(settingVal2); //コントロールレジスタ1 //デバイスIDを取得 devID = readDEVICE_ID(); //シリアル出力 if(hasSerial){ pc->printf("INITIALIZE BEGIN\r\n\tSPI Freq = %d[Hz], SPI Mode = 16, 1\r\n", (int)DRV8301CTRL_FREQ); pc->printf("\tDEVICE ID = [%d]\r\n", (int)devID); } //現在のレジスタ内容を出力 if(hasSerial){ pc->printf( "3\tSTATUS 1 NOW : 0x%08x, STATUS 2 NOW : 0x%08x\r\n", (spi_cmd(DRV8301REG_READMODE | DRV8301REG_STATUS1, false) & 0x07FF), (spi_cmd(DRV8301REG_READMODE | DRV8301REG_STATUS2, false) & 0x07FF) ); pc->printf( "3\tREGISTER 1 NOW : 0x%08x, REGISTER 2 NOW : 0x%08x\r\n", (spi_cmd(DRV8301REG_READMODE | DRV8301REG_CTRL1, false) & 0x07FF), (spi_cmd(DRV8301REG_READMODE | DRV8301REG_CTRL2, false) & 0x07FF) ); pc->printf("\tINITIAL CTRL1 REG = 0x%08x\r\n\tINITIAL CTRL2 REG = 0x%08x\r\n", settingVal1, settingVal2); } //シリアル出力 if(hasSerial){ pc->printf("INITIALIZE END\r\n ---===---===--- \r\n"); } //待ち時間 wait_ms(5); } //ステータスレジスタ1の読み取り ======================================== /* * DRV8301の現在の状態を読み取り、返す(ステータスレジスタ1) * * この情報で読み取れるものは、 * FAULT(何らかの異常), GVDD_UV(GVDD電圧下降), PVDD_UV(PVDD電圧下降), * OTSD(温度上昇シャットダウン), OTW(温度上昇警告), * FETHA_OC(A相FETハイサイド過電流), FETLA_OC(A相FETローサイド過電流), * FETHB_OC(B相FETハイサイド過電流), FETLB_OC(B相FETローサイド過電流), * FETHC_OC(B相FETハイサイド過電流), FETLC_OC(B相FETローサイド過電流) * * 異常がなければ0, 異常があれば1が設定される */ unsigned short drv8301ctrl::readStatus1(){ //SPIで値を読み取り、返す return (unsigned short)(spi_cmd(DRV8301REG_READMODE | DRV8301REG_STATUS1) & 0x07FF); } //ステータスレジスタ2の読み取り ======================================== /* * DRV8301の現在の状態を読み取り、返す(ステータスレジスタ2) * * この情報で読み取れるものは、 * GVDD_OV(GVDD過電圧)、DEVICE_ID(デバイスID) * * GVDD_OVは異常がなければ0, 異常があれば1が設定される * デバイスIDは4bitの値で、通常は1(0x0001)を返す */ unsigned short drv8301ctrl::readStatus2(){ //SPIで値を読み取り、返す return (unsigned short)(spi_cmd(DRV8301REG_READMODE | DRV8301REG_STATUS2) & 0x07FF); } //ステータスレジスタ:FAULTの読み取り =================================== /* * ステータスレジスタからFAULTの状態だけを切り取って返す * 戻り値がtrueであればFAULT(何らかの異常)が発生している */ bool drv8301ctrl::readFault(){ return (((readStatus1() >> 10) & 0x0001) == 1); } //ステータスレジスタ:GVDD_UVの読み取り ================================= /* * ステータスレジスタからGVDD_UVの状態だけを切り取って返す * 戻り値がtrueであればGVDD_UV(GVDDの電圧下降)が発生している */ bool drv8301ctrl::readGVDD_UV(){ return (((readStatus1() >> 9) & 0x0001) == 1); } //ステータスレジスタ:PVDD_UVの読み取り ================================= /* * ステータスレジスタからPVDD_UVの状態だけを切り取って返す * 戻り値がtrueであればPVDD_UV(PVDDの電圧下降)が発生している */ bool drv8301ctrl::readPVDD_UV(){ return (((readStatus1() >> 8) & 0x0001) == 1); } //ステータスレジスタ:OTSDの読み取り ==================================== /* * ステータスレジスタからOTSDの状態だけを切り取って返す * 戻り値がtrueであればOTSD(温度上昇によるシャットダウン)が発生している * * 温度上昇によるシャットダウンは摂氏150度で設定される */ bool drv8301ctrl::readOTSD(){ return (((readStatus1() >> 7) & 0x0001) == 1); } //ステータスレジスタ:OTWの読み取り ===================================== /* * ステータスレジスタからOTWの状態だけを切り取って返す * 戻り値がtrueであればOTW(温度上昇による警告)が発生している * * 温度上昇による警告は摂氏130度で設定される * この警告は摂氏115度になるまで発生し続ける */ bool drv8301ctrl::readOTW(){ return (((readStatus1() >> 6) & 0x0001) == 1); } //ステータスレジスタ:FETHA_OCの読み取り ================================ /* * ステータスレジスタからFETHA_OCの状態だけを切り取って返す * 戻り値がtrueであればFETHA_OC(A相FETハイサイド過電流)が発生している */ bool drv8301ctrl::readFETHA_OC(){ return (((readStatus1() >> 5) & 0x0001) == 1); } //ステータスレジスタ:FETLA_OCの読み取り ================================ /* * ステータスレジスタからFETLA_OCの状態だけを切り取って返す * 戻り値がtrueであればFETLA_OC(A相FETローサイド過電流)が発生している */ bool drv8301ctrl::readFETLA_OC(){ return (((readStatus1() >> 4) & 0x0001) == 1); } //ステータスレジスタ:FETHB_OCの読み取り ================================ /* * ステータスレジスタからFETHB_OCの状態だけを切り取って返す * 戻り値がtrueであればFETHB_OC(B相FETハイサイド過電流)が発生している */ bool drv8301ctrl::readFETHB_OC(){ return (((readStatus1() >> 3) & 0x0001) == 1); } //ステータスレジスタ:FETLB_OCの読み取り ================================ /* * ステータスレジスタからFETLB_OCの状態だけを切り取って返す * 戻り値がtrueであればFETLB_OC(B相FETローサイド過電流)が発生している */ bool drv8301ctrl::readFETLB_OC(){ return (((readStatus1() >> 2) & 0x0001) == 1); } //ステータスレジスタ:FETHC_OCの読み取り ================================ /* * ステータスレジスタからFETHC_OCの状態だけを切り取って返す * 戻り値がtrueであればFETHC_OC(C相FETハイサイド過電流)が発生している */ bool drv8301ctrl::readFETHC_OC(){ return (((readStatus1() >> 1) & 0x0001) == 1); } //ステータスレジスタ:FETLC_OCの読み取り ================================ /* * ステータスレジスタからFETLC_OCの状態だけを切り取って返す * 戻り値がtrueであればFETLC_OC(C相FETローサイド過電流)が発生している */ bool drv8301ctrl::readFETLC_OC(){ return ((readStatus1() & 0x0001) == 1); } //ステータスレジスタ:GVDD_OVの読み取り ================================= /* * ステータスレジスタからGVDD_OVの状態だけを切り取って返す * 戻り値がtrueであればGVDD_OV(GVDD過電圧)が発生している */ bool drv8301ctrl::readGVDD_OV(){ return (((readStatus2() >> 7) & 0x0001) == 1); } //ステータスレジスタ:Device IDの読み取り =============================== /* * ステータスレジスタからDevideIDの状態だけを切り取って返す * 戻り値は4bitの値、0 - 15の中のいずれか */ unsigned char drv8301ctrl::readDEVICE_ID(){ return (unsigned char)(readStatus2() & 0x0F); } //コントロールレジスタ1の読み取り ======================================= /* * DRV8301の現在の状態を読み取り、返す(コントロールレジスタ1) * 読み取った情報は、内部の保存用変数に格納する * * この情報で読み取れるものは、 * GATE_CURRENT(FETゲートカレント設定), GATE_RESET(ゲートリセット監視), * PWM_MODE(PWM信号送出方法), OCP_MODE(過電流監視モード), * OC_ADJ_SET(過電流調整値) * * 設定値はデフォルトであればOC_ADJ_SET以外は0を返す */ unsigned short drv8301ctrl::readCtrl1(){ //取得した値を次回書き込み用変数に格納 writeValue1 = (unsigned short)(spi_cmd(DRV8301REG_READMODE | DRV8301REG_CTRL1) & 0x07FF); return writeValue1; } //コントロールレジスタ2の読み取り ======================================= /* * DRV8301の現在の状態を読み取り、返す(コントロールレジスタ2) * 読み取った情報は、内部の保存用変数に格納する * * この情報で読み取れるものは、 * OCTW_MODE(過電流、温度上昇監視方法), GAIN(電流読み取り値増幅), * DC_CAL_CH1(電流読み取り値オフセットch1), * DC_CAL_CH2(電流読み取り値オフセットch2), * OC_TOFF(過電流発生時オフタイム設定) * * 設定値はデフォルトであれば0を返す */ unsigned short drv8301ctrl::readCtrl2(){ //取得した値を次回書き込み用変数に格納 writeValue2 = (unsigned short)(spi_cmd(DRV8301REG_READMODE | DRV8301REG_CTRL2) & 0x07FF); return writeValue2; } //コントロールレジスタ:GATE_CURRENTの読み取り =========================== /* * コントロールレジスタからGATE_CURRENTの状態だけを切り取って返す * * 戻り値の値は0 - 3の4種類 * Gate drive peak current 1.7 A = 0 * Gate drive peak current 0.7 A = 1 * Gate drive peak current 0.25 A = 2 * Reserved = 3 */ unsigned char drv8301ctrl::readGATE_CURRENT(){ return (unsigned char)(readCtrl1() & 0x03); } //コントロールレジスタ:GATE_CURRENTの読み取り:実際の値で返す =================== /* * コントロールレジスタからGATE_CURRENTの状態だけを切り取って返す * * 戻り値の値は4種類 * Gate drive peak current 1.7 A = 1.7f * Gate drive peak current 0.7 A = 0.7f * Gate drive peak current 0.25 A = 0.25f * Reserved = -1.0f */ float drv8301ctrl::readValGATE_CURRENT(){ float ret = 0.0f; switch(readCtrl1() & 0x03){ case 0: //1.7A ret = 1.7f; break; case 1: //0.7A ret = 0.7f; break; case 2: //0.25A ret = 0.25f; break; default: //reserved ret = -1.0f; } return ret; } //コントロールレジスタ:GATE_RESETの読み取り ============================= /* * コントロールレジスタからGATE_RESETの状態だけを切り取って返す * * 戻り値がtrueならNormal mode * falseならReset gate driver latched faults (reverts to 0) */ bool drv8301ctrl::readGATE_RESETisNormal(){ //設定がNormalならtrue、そうでないならfalseを返す return (((readCtrl1() >> 2) & 0x01) == 0); } //コントロールレジスタ:PWM_MODEの読み取り =============================== /* * コントロールレジスタからPWM_MODEの状態だけを切り取って返す * * 戻り値がtrueなら6線式PWMモード * falseなら3線式PWMモード */ bool drv8301ctrl::readPWM_MODEis6PWM(){ //設定が6-PWM Modeならtrue、3-PWM Modeならfalseを返す return (((readCtrl1() >> 3) & 0x01) == 0); } //コントロールレジスタ:OCP_MODEの読み取り =============================== /* * コントロールレジスタからOCP_MODEの状態だけを切り取って返す * * 戻り値の値は0 - 3の4種類 * Current limit = 0 * OC latch shut down = 1 * Report only = 2 * OC disabled = 3 */ unsigned char drv8301ctrl::readOCP_MODE(){ return (unsigned char)((readCtrl1() >> 4) & 0x03); } //コントロールレジスタ:OC_ADJ_SETの読み取り ============================= /* * コントロールレジスタからOC_ADJ_SETの状態だけを切り取って返す * * 戻り値の値は設定値の5bit(0 - 32) */ unsigned char drv8301ctrl::readOC_ADJ_SET(){ return (unsigned char)((readCtrl1() >> 6) & 0x1F); } //コントロールレジスタ:OC_ADJ_SETの読み取り:実際の値で返す ===================== /* * コントロールレジスタからOC_ADJ_SETの状態だけを切り取って返す * * 戻り値の値は設定値の実際の値 */ float drv8301ctrl::readValOC_ADJ_SET(){ float ret = 0.0f; switch(readCtrl1() & 0x07C0){ case 0x0000: ret = 0.060; break; case 0x0040: ret = 0.068; break; case 0x0080: ret = 0.076; break; case 0x00C0: ret = 0.086; break; case 0x0100: ret = 0.097; break; case 0x0140: ret = 0.109; break; case 0x0180: ret = 0.123; break; case 0x01C0: ret = 0.138; break; case 0x0200: ret = 0.155; break; case 0x0240: ret = 0.175; break; case 0x0280: ret = 0.197; break; case 0x02C0: ret = 0.222; break; case 0x0300: ret = 0.250; break; case 0x0340: ret = 0.282; break; case 0x0380: ret = 0.317; break; case 0x03C0: ret = 0.358; break; case 0x0400: ret = 0.403; break; case 0x0440: ret = 0.454; break; case 0x0480: ret = 0.511; break; case 0x04C0: ret = 0.576; break; case 0x0500: ret = 0.648; break; case 0x0540: ret = 0.730; break; case 0x0580: ret = 0.822; break; case 0x05C0: ret = 0.926; break; case 0x0600: ret = 1.043; break; case 0x0640: ret = 1.175; break; case 0x0680: ret = 1.324; break; case 0x06C0: ret = 1.491; break; case 0x0700: ret = 1.679; break; case 0x0740: ret = 1.892; break; case 0x0780: ret = 2.131; break; case 0x07C0: ret = 2.400; break; } return ret; } //コントロールレジスタ:OCTW_MODEの読み取り ============================== /* * コントロールレジスタからOCTW_MODEの状態だけを切り取って返す * * 戻り値の値は0 - 3の4種類 * Report both OT and OC at nOCTW pin = 0 * Report OT only = 1 * Report OC only = 2 * Report OC only (reserved) = 3 */ unsigned char drv8301ctrl::readOCTW_MODE(){ return (unsigned char)(readCtrl2() & 0x03); } //コントロールレジスタ:GAINの読み取り =================================== /* * コントロールレジスタからGAINの状態だけを切り取って返す * * 戻り値の値は0 - 3の4種類 * Gain of shunt amplifier: 10 V/V = 0 * Gain of shunt amplifier: 20 V/V = 1 * Gain of shunt amplifier: 40 V/V = 2 * Gain of shunt amplifier: 80 V/V = 3 */ unsigned char drv8301ctrl::readGAIN(){ return (unsigned char)((readCtrl2() >> 2) & 0x03); } //コントロールレジスタ:DC_CAL_CH1の読み取り ============================= /* * コントロールレジスタからDC_CAL_CH1の状態だけを切り取って返す * * 戻り値がtrueならオフセット有効 * falseならオフセット無効 */ bool drv8301ctrl::readDC_CAL_CH1isEnabled(){ //設定が有効(Enabled)ならtrue、そうでないならfalseを返す return (((readCtrl2() >> 4) & 0x01) == 0); } //コントロールレジスタ:DC_CAL_CH2の読み取り ============================= /* * コントロールレジスタからDC_CAL_CH2の状態だけを切り取って返す * * 戻り値がtrueならオフセット有効 * falseならオフセット無効 */ bool drv8301ctrl::readDC_CAL_CH2isEnabled(){ //設定が有効(Enabled)ならtrue、そうでないならfalseを返す return (((readCtrl2() >> 5) & 0x01) == 0); } //コントロールレジスタ:OC_TOFFの読み取り ================================ /* * コントロールレジスタからOC_TOFFの状態だけを切り取って返す * * 戻り値がtrueならCycle by cycle * falseならOff-time control */ bool drv8301ctrl::readOC_TOFFisCycleByCycle(){ //設定がCycle by Cycleならtrue、そうでないならfalseを返す return (((readCtrl2() >> 6) & 0x01) == 0); } //コントロールレジスタ1への書き込み:valが0xffffならwriteValue1を使用する ========= /* * コントロールレジスタ1へ値を書き込む * 引数valが指定されていれば、引数の中の値を書き込み * 引数valが指定されていないか、もしくは引数valが0xffffであれば * 内部に保存しているwriteValue1の中の値を書き込む * * 戻り値がtrueであれば書き込み成功 */ bool drv8301ctrl::writeCtrl1(unsigned short val){ //シリアル出力 if(hasSerial){ pc->printf("CURRENT SETTING = 0x%08x\r\n", (spi_cmd(DRV8301REG_READMODE | DRV8301REG_CTRL1, false) & 0x07FF)); pc->printf(">>>>WRITE CTRL1 REGISTER\r\n\tval = 0x%08x\r\n\twriteValue1 = 0x%08x\r\n", val, writeValue1); } //値の書き込み(先頭(MSB)に1がついていたら書き込み失敗) unsigned short ret = spi_cmd(DRV8301REG_WRITEMODE | DRV8301REG_CTRL1 | ((val == 0xffff)? writeValue1 : val)); //値の書き込みが終わったら現在の値を取得して値をリセットする resetWriteValue1(); //先頭ビットに1がついていなければ(32768未満であれば)書き込み成功(trueを返す) return (ret < 32768); } //コントロールレジスタ2への書き込み:valが0xffffならwriteValue2を使用する ========= /* * コントロールレジスタ2へ値を書き込む * 引数valが指定されていれば、引数の中の値を書き込み * 引数valが指定されていないか、もしくは引数valが0xffffであれば * 内部に保存しているwriteValue2の中の値を書き込む * * 戻り値がtrueであれば書き込み成功 */ bool drv8301ctrl::writeCtrl2(unsigned short val){ //シリアル出力 if(hasSerial){ pc->printf("CURRENT SETTING = 0x%08x\r\n", (spi_cmd(DRV8301REG_READMODE | DRV8301REG_CTRL2, false) & 0x07FF)); pc->printf(">>>>WRITE CTRL2 REGISTER\r\n\tval = 0x%08x\r\n\twriteValue2 = 0x%08x\r\n", val, writeValue2); } //値の書き込み(先頭(MSB)に1がついていたら書き込み失敗) unsigned short ret = spi_cmd(DRV8301REG_WRITEMODE | DRV8301REG_CTRL2 | ((val == 0xffff)? writeValue2 : val)); //値の書き込みが終わったら現在の値を取得して値をリセットする resetWriteValue2(); //先頭ビットに1がついていなければ(32768未満であれば)書き込み成功(trueを返す) return (ret < 32768); } //コントロールレジスタ1に設定する内容を格納した変数をリセット ========================= void drv8301ctrl::resetWriteValue1(){ writeValue1 = (unsigned short)(spi_cmd(DRV8301REG_READMODE | DRV8301REG_CTRL1) & 0x07FF); } //コントロールレジスタ2に設定する内容を格納した変数をリセット ========================= void drv8301ctrl::resetWriteValue2(){ writeValue2 = (unsigned short)(spi_cmd(DRV8301REG_READMODE | DRV8301REG_CTRL2) & 0x07FF); } //コントロールレジスタ1に設定する内容を格納した変数を直接アップデート ===================== void drv8301ctrl::updateWriteValue1(unsigned short val){ writeValue1 = val; } //コントロールレジスタ2に設定する内容を格納した変数を直接アップデート ===================== void drv8301ctrl::updateWriteValue2(unsigned short val){ writeValue2 = val; } //コントロールレジスタ:GATE_CURRENTの書き込み =========================== void drv8301ctrl::setGATE_CURRENT(unsigned char val){ //値は0x00,0x01,0x10,0x11の4種類。値が3(0x11)以上のものは0x00として扱う if(val > 3) val = 0; //writeValueの対象部分をゼロにして、論理和をとる writeValue1 &= 0xFFFC; writeValue1 |= val; //シリアル出力 if(hasSerial){ pc->printf("Register1 temporary value changed, [GATE_CURRENT]\r\n\tval = 0x%08x, writeValue1 = 0x%08x\r\n", val, writeValue1); } } //コントロールレジスタ:GATE_CURRENTの書き込み:実際の値に近いものを書き込む ============ void drv8301ctrl::setGATE_CURRENT(float realVal){ //値は0.0(reserved),0.25,0.7,1.7の4種類。値が1.7以上は1.7として扱う realVal = (realVal < 0.0f) ? 0.0f : (realVal > 1.7f) ? 1.7f : realVal; //writeValueの対象部分をゼロにする writeValue1 &= 0xFFFC; if(realVal < 0.25f){ writeValue1 |= GATE_CURRENT_PEAKCURRENT_RESERVED; //reserved }else if(realVal < 0.7f){ writeValue1 |= GATE_CURRENT_PEAKCURRENT_0_25A; //0.25A }else if(realVal < 1.7f){ writeValue1 |= GATE_CURRENT_PEAKCURRENT_0_7A; //0.7A }else{ writeValue1 |= GATE_CURRENT_PEAKCURRENT_1_7A; //1.7A } //シリアル出力 if(hasSerial){ pc->printf("Register1 temporary value changed, [GATE_CURRENT]\r\n\tval = %01.2f, writeValue1 = 0x%08x\r\n", realVal, writeValue1); } } //コントロールレジスタ:GATE_RESETの書き込み ============================= void drv8301ctrl::setGATE_RESET(bool isNormal){ //writeValueの対象部分をゼロにする writeValue1 &= 0xFFFB; writeValue1 |= isNormal ? GATE_RESET_NORMAL : GATE_RESET_RESETGATE_LATCHED_FAULT; //シリアル出力 if(hasSerial){ pc->printf( "Register1 temporary value changed, [GATE_RESET]\r\n\tisNormal = %s, writeValue1 = 0x%08x\r\n", (isNormal ? "true" : "false"), writeValue1 ); } } //コントロールレジスタ:PWM_MODEの書き込み =============================== void drv8301ctrl::setPWM_MODE(bool is6PWM){ //writeValueの対象部分をゼロにする writeValue1 &= 0xFFF7; writeValue1 |= is6PWM ? PWM_MODE_PWMLINES_6 : PWM_MODE_PWMLINES_3; //シリアル出力 if(hasSerial){ pc->printf( "Register1 temporary value changed, [PWM_MODE]\r\n\tis6PWM = %s, writeValue1 = 0x%08x\r\n", (is6PWM ? "true" : "false"), writeValue1 ); } } //コントロールレジスタ:OCP_MODEの書き込み =============================== void drv8301ctrl::setOCP_MODE(unsigned char val){ //値は0x00,0x01,0x10,0x11の4種類。値が3(0x11)以上のものは0x00として扱う if(val > 3) val = 0; //writeValueの対象部分をゼロにする writeValue1 &= 0xFFCF; switch(val){ case 0: writeValue1 |= OCP_MODE_CURRENTLIMIT; break; case 1: writeValue1 |= OCP_MODE_OC_LATCH_SHUTDOWN; break; case 2: writeValue1 |= OCP_MODE_REPORTONLY; break; case 3: writeValue1 |= OCP_MODE_OC_DISABLE; break; } //シリアル出力 if(hasSerial){ pc->printf("Register1 temporary value changed, [GATE_CURRENT]\r\n\tval = 0x%08x, writeValue1 = 0x%08x\r\n", val, writeValue1); } } //コントロールレジスタ:OC_ADJ_SETの書き込み ============================= void drv8301ctrl::setOC_ADJ(unsigned char val){ //値は0(0x00)から31(0x1f)まで。31以上は0として扱う if(val > 31) val = 0; //writeValueの対象部分をゼロにする writeValue1 &= 0xF83F; switch(val){ case 0: writeValue1 |= OC_ADJ_SET_ADJUST_0_060; break; case 1: writeValue1 |= OC_ADJ_SET_ADJUST_0_068; break; case 2: writeValue1 |= OC_ADJ_SET_ADJUST_0_076; break; case 3: writeValue1 |= OC_ADJ_SET_ADJUST_0_086; break; case 4: writeValue1 |= OC_ADJ_SET_ADJUST_0_097; break; case 5: writeValue1 |= OC_ADJ_SET_ADJUST_0_109; break; case 6: writeValue1 |= OC_ADJ_SET_ADJUST_0_123; break; case 7: writeValue1 |= OC_ADJ_SET_ADJUST_0_138; break; case 8: writeValue1 |= OC_ADJ_SET_ADJUST_0_155; break; case 9: writeValue1 |= OC_ADJ_SET_ADJUST_0_175; break; case 10: writeValue1 |= OC_ADJ_SET_ADJUST_0_197; break; case 11: writeValue1 |= OC_ADJ_SET_ADJUST_0_222; break; case 12: writeValue1 |= OC_ADJ_SET_ADJUST_0_250; break; case 13: writeValue1 |= OC_ADJ_SET_ADJUST_0_282; break; case 14: writeValue1 |= OC_ADJ_SET_ADJUST_0_317; break; case 15: writeValue1 |= OC_ADJ_SET_ADJUST_0_358; break; case 16: writeValue1 |= OC_ADJ_SET_ADJUST_0_403; break; case 17: writeValue1 |= OC_ADJ_SET_ADJUST_0_454; break; case 18: writeValue1 |= OC_ADJ_SET_ADJUST_0_511; break; case 19: writeValue1 |= OC_ADJ_SET_ADJUST_0_576; break; case 20: writeValue1 |= OC_ADJ_SET_ADJUST_0_648; break; case 21: writeValue1 |= OC_ADJ_SET_ADJUST_0_730; break; case 22: writeValue1 |= OC_ADJ_SET_ADJUST_0_822; break; case 23: writeValue1 |= OC_ADJ_SET_ADJUST_0_926; break; case 24: writeValue1 |= OC_ADJ_SET_ADJUST_1_043; break; case 25: writeValue1 |= OC_ADJ_SET_ADJUST_1_175; break; case 26: writeValue1 |= OC_ADJ_SET_ADJUST_1_324; break; case 27: writeValue1 |= OC_ADJ_SET_ADJUST_1_491; break; case 28: writeValue1 |= OC_ADJ_SET_ADJUST_1_679; break; case 29: writeValue1 |= OC_ADJ_SET_ADJUST_1_892; break; case 30: writeValue1 |= OC_ADJ_SET_ADJUST_2_131; break; case 31: writeValue1 |= OC_ADJ_SET_ADJUST_2_400; break; } //シリアル出力 if(hasSerial){ pc->printf("Register1 temporary value changed, [OC_ADJ_SET]\r\n\tval = 0x%08x, writeValue1 = 0x%08x\r\n", val, writeValue1); } } //コントロールレジスタ:OC_ADJ_SETの書き込み:実際の値に近いものを書き込む ============== void drv8301ctrl::setOC_ADJ(float realVal){ //値は0.06から2.4まで。それ以上は0.06として扱う realVal = (realVal < 0.06f) ? 0.06f : (realVal > 2.4f) ? 2.4f : realVal; //writeValueの対象部分をゼロにする writeValue1 &= 0xF83F; //ifで振り分けていく・・・しかないのか・・・? if(realVal < 0.068f) writeValue1 |= OC_ADJ_SET_ADJUST_0_060; else if(realVal < 0.076f) writeValue1 |= OC_ADJ_SET_ADJUST_0_068; else if(realVal < 0.086f) writeValue1 |= OC_ADJ_SET_ADJUST_0_076; else if(realVal < 0.097f) writeValue1 |= OC_ADJ_SET_ADJUST_0_086; else if(realVal < 0.109f) writeValue1 |= OC_ADJ_SET_ADJUST_0_097; else if(realVal < 0.123f) writeValue1 |= OC_ADJ_SET_ADJUST_0_109; else if(realVal < 0.138f) writeValue1 |= OC_ADJ_SET_ADJUST_0_123; else if(realVal < 0.155f) writeValue1 |= OC_ADJ_SET_ADJUST_0_138; else if(realVal < 0.175f) writeValue1 |= OC_ADJ_SET_ADJUST_0_155; else if(realVal < 0.197f) writeValue1 |= OC_ADJ_SET_ADJUST_0_175; else if(realVal < 0.222f) writeValue1 |= OC_ADJ_SET_ADJUST_0_197; else if(realVal < 0.250f) writeValue1 |= OC_ADJ_SET_ADJUST_0_222; else if(realVal < 0.282f) writeValue1 |= OC_ADJ_SET_ADJUST_0_250; else if(realVal < 0.317f) writeValue1 |= OC_ADJ_SET_ADJUST_0_282; else if(realVal < 0.358f) writeValue1 |= OC_ADJ_SET_ADJUST_0_317; else if(realVal < 0.403f) writeValue1 |= OC_ADJ_SET_ADJUST_0_358; else if(realVal < 0.454f) writeValue1 |= OC_ADJ_SET_ADJUST_0_403; else if(realVal < 0.511f) writeValue1 |= OC_ADJ_SET_ADJUST_0_454; else if(realVal < 0.576f) writeValue1 |= OC_ADJ_SET_ADJUST_0_511; else if(realVal < 0.648f) writeValue1 |= OC_ADJ_SET_ADJUST_0_576; else if(realVal < 0.730f) writeValue1 |= OC_ADJ_SET_ADJUST_0_648; else if(realVal < 0.822f) writeValue1 |= OC_ADJ_SET_ADJUST_0_730; else if(realVal < 0.926f) writeValue1 |= OC_ADJ_SET_ADJUST_0_822; else if(realVal < 1.043f) writeValue1 |= OC_ADJ_SET_ADJUST_0_926; else if(realVal < 1.175f) writeValue1 |= OC_ADJ_SET_ADJUST_1_043; else if(realVal < 1.324f) writeValue1 |= OC_ADJ_SET_ADJUST_1_175; else if(realVal < 1.491f) writeValue1 |= OC_ADJ_SET_ADJUST_1_324; else if(realVal < 1.679f) writeValue1 |= OC_ADJ_SET_ADJUST_1_491; else if(realVal < 1.892f) writeValue1 |= OC_ADJ_SET_ADJUST_1_679; else if(realVal < 2.131f) writeValue1 |= OC_ADJ_SET_ADJUST_1_892; else if(realVal < 2.400f) writeValue1 |= OC_ADJ_SET_ADJUST_2_131; else writeValue1 |= OC_ADJ_SET_ADJUST_2_400; //シリアル出力 if(hasSerial){ pc->printf("Register1 temporary value changed, [OC_ADJ_SET]\r\n\tval = %2.3f, writeValue1 = 0x%08x\r\n", realVal, writeValue1); } } //コントロールレジスタ:OCTW_MODEの書き込み ============================== void drv8301ctrl::setOCTW_MODE(unsigned char val){ //値は0x00,0x01,0x10,0x11の4種類。値が3(0x11)以上のものは0x00として扱う if(val > 3) val = 0; //writeValueの対象部分をゼロにする writeValue2 &= 0xFFFC; switch(val){ case 0: writeValue2 |= OCTW_MODE_REPORT_OT_OC_BOTH; break; case 1: writeValue2 |= OCTW_MODE_REPORT_OVERTEMP_ONLY; break; case 2: writeValue2 |= OCTW_MODE_REPORT_OVERCURRENT_ONLY; break; case 3: writeValue2 |= OCTW_MODE_REPORT_RESERVED; break; } //シリアル出力 if(hasSerial){ pc->printf("Register2 temporary value changed, [OCTW_MODE]\r\n\tval = 0x%08x, writeValue1 = 0x%08x\r\n", val, writeValue2); } } //コントロールレジスタ:GAINの書き込み =================================== void drv8301ctrl::setGAIN(unsigned char val){ //値は0x00,0x01,0x10,0x11の4種類。値が3(0x11)以上のものは0x00として扱う if(val > 3) val = 0; //writeValueの対象部分をゼロにする writeValue2 &= 0xFFF3; switch(val){ case 0: writeValue2 |= SHUNTGAIN_GAIN_10V_PER_V; break; case 1: writeValue2 |= SHUNTGAIN_GAIN_20V_PER_V; break; case 2: writeValue2 |= SHUNTGAIN_GAIN_40V_PER_V; break; case 3: writeValue2 |= SHUNTGAIN_GAIN_80V_PER_V; break; } //シリアル出力 if(hasSerial){ pc->printf("Register2 temporary value changed, [GAIN]\r\n\tval = 0x%08x, writeValue1 = 0x%08x\r\n", val, writeValue2); } } //コントロールレジスタ:DC_CAL_CH1の書き込み ============================= void drv8301ctrl::setDC_CAL_CH1_Enabled(bool enable){ //writeValueの対象部分をゼロにする writeValue2 &= 0xFFEF; //引数がtrueならDC_CALを有効にする writeValue2 |= enable ? DC_CAL_CH1_ENABLE : DC_CAL_CH1_DISABLE; //シリアル出力 if(hasSerial){ pc->printf( "Register2 temporary value changed, [DC_CAL_CH1]\r\n\tval = %s, writeValue1 = 0x%08x\r\n", enable ? "true" : "false", writeValue2 ); } } //コントロールレジスタ:DC_CAL_CH2の書き込み ============================= void drv8301ctrl::setDC_CAL_CH2_Enabled(bool enable){ //writeValueの対象部分をゼロにする writeValue2 &= 0xFFDF; //引数がtrueならDC_CALを有効にする writeValue2 |= enable ? DC_CAL_CH1_ENABLE : DC_CAL_CH1_DISABLE; //シリアル出力 if(hasSerial){ pc->printf( "Register2 temporary value changed, [DC_CAL_CH2]\r\n\tval = %s, writeValue1 = 0x%08x\r\n", enable ? "true" : "false", writeValue2 ); } } //コントロールレジスタ:OC_TOFFの書き込み ================================ void drv8301ctrl::setOC_TOFF_CycleByCycle(bool enable){ //writeValueの対象部分をゼロにする writeValue2 &= 0xFFBF; //引数がtrueならOC_TOFFをCycleByCycleにする writeValue2 |= enable ? OC_TOFF_CYCLE_BY_CYCLE : OC_TOFF_OFF_TIME_CONTROL; //シリアル出力 if(hasSerial){ pc->printf( "Register2 temporary value changed, [OC_TOFF]\r\n\tval = %s, writeValue1 = 0x%08x\r\n", enable ? "true" : "false", writeValue2 ); } } //EN_GATEを有効にする void drv8301ctrl::gateEnable(){ DRV8301_GATE_ACTIVE; wait_us(20); } //EN_GATEを無効にする void drv8301ctrl::gateDisable(){ DRV8301_GATE_INACTIVE; wait_us(20); } //状態をリセットする(ON-OFF-ON) void drv8301ctrl::gateReset(){ DRV8301_GATE_ACTIVE; wait_us(15); DRV8301_GATE_INACTIVE; wait_us(15); DRV8301_GATE_ACTIVE; wait_us(15); }