Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
fpga.cpp@48:71aec693a7dc, 2019-02-24 (annotated)
- Committer:
- MasashiNomura
- Date:
- Sun Feb 24 10:33:34 2019 +0000
- Revision:
- 48:71aec693a7dc
- Parent:
- 45:3b51dd26b579
20190224 add cmd pid mode etc.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| MasashiNomura | 45:3b51dd26b579 | 1 | /** |
| MasashiNomura | 45:3b51dd26b579 | 2 | * @file fpga.cpp |
| MasashiNomura | 45:3b51dd26b579 | 3 | * @brief FPGAにSPI通信でやり取りするための関数群 |
| MasashiNomura | 45:3b51dd26b579 | 4 | * @author Shirota |
| MasashiNomura | 45:3b51dd26b579 | 5 | * @date 2018/10/01 ? |
| MasashiNomura | 45:3b51dd26b579 | 6 | */ |
| MasashiNomura | 45:3b51dd26b579 | 7 | |
| takeru0x1103 | 0:ecd925601fc6 | 8 | #include "mbed.h" |
| takeru0x1103 | 0:ecd925601fc6 | 9 | #include "fpga.h" |
| takeru0x1103 | 18:5aa48aec9cae | 10 | #include "globalFlags.h" |
| takeru0x1103 | 8:1ca49cb18290 | 11 | |
| takeru0x1103 | 8:1ca49cb18290 | 12 | #define CLK_CYC 20.83 //FPGAのクロック周期 |
| takeru0x1103 | 0:ecd925601fc6 | 13 | |
| takeru0x1103 | 8:1ca49cb18290 | 14 | //----------------------------- |
| takeru0x1103 | 8:1ca49cb18290 | 15 | //FPGAレジスタアドレスマップ |
| takeru0x1103 | 0:ecd925601fc6 | 16 | #define ADR_TEST_REG 0x0 //テストレジスタ |
| takeru0x1103 | 0:ecd925601fc6 | 17 | #define ADR_RPM_FLSB 0x1 //エンジン回転数 前 LSB |
| takeru0x1103 | 0:ecd925601fc6 | 18 | #define ADR_RPM_FMSB 0x2 //エンジン回転数 前 MSB |
| takeru0x1103 | 0:ecd925601fc6 | 19 | #define ADR_RPM_BLSB 0x3 //エンジン回転数 後ろ LSB |
| takeru0x1103 | 0:ecd925601fc6 | 20 | #define ADR_RPM_BMSB 0x4 //エンジン回転数 後ろ MSB |
| takeru0x1103 | 0:ecd925601fc6 | 21 | |
| takeru0x1103 | 0:ecd925601fc6 | 22 | #define ADR_SUB_FL_I 0x5 //前 ◀ in |
| takeru0x1103 | 0:ecd925601fc6 | 23 | #define ADR_SUB_FL_O 0x6 //前 ◀ out |
| takeru0x1103 | 0:ecd925601fc6 | 24 | #define ADR_SUB_FR_I 0x7 //前 ▶ in |
| takeru0x1103 | 0:ecd925601fc6 | 25 | #define ADR_SUB_FR_O 0x8 //前 ▶ out |
| takeru0x1103 | 0:ecd925601fc6 | 26 | |
| takeru0x1103 | 0:ecd925601fc6 | 27 | #define ADR_SUB_BL_I 0x9 //後ろ ◀ in |
| takeru0x1103 | 0:ecd925601fc6 | 28 | #define ADR_SUB_BL_O 0xA //後ろ ◀ out |
| takeru0x1103 | 0:ecd925601fc6 | 29 | #define ADR_SUB_BR_I 0xB //後ろ ▶ in |
| takeru0x1103 | 0:ecd925601fc6 | 30 | #define ADR_SUB_BR_O 0xC //後ろ ▶ out |
| takeru0x1103 | 0:ecd925601fc6 | 31 | |
| takeru0x1103 | 0:ecd925601fc6 | 32 | #define ADR_USER_SW 0xD //ユーザースイッチ |
| takeru0x1103 | 0:ecd925601fc6 | 33 | #define ADR_ACCEL_F 0xE //アクセル前 |
| takeru0x1103 | 0:ecd925601fc6 | 34 | #define ADR_ACCEL_B 0xF //アクセル後ろ |
| takeru0x1103 | 8:1ca49cb18290 | 35 | //----------------------------- |
| takeru0x1103 | 0:ecd925601fc6 | 36 | |
| takeru0x1103 | 0:ecd925601fc6 | 37 | // ################################################################ |
| takeru0x1103 | 0:ecd925601fc6 | 38 | // SPI通信フォーマットに合わせた供用体定義 |
| takeru0x1103 | 0:ecd925601fc6 | 39 | // bit |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| |
| takeru0x1103 | 0:ecd925601fc6 | 40 | // function | ID | Data | |
| takeru0x1103 | 0:ecd925601fc6 | 41 | // ################################################################ |
| takeru0x1103 | 0:ecd925601fc6 | 42 | typedef union{ |
| takeru0x1103 | 0:ecd925601fc6 | 43 | UINT16 spiCmd; |
| takeru0x1103 | 0:ecd925601fc6 | 44 | struct{ |
| takeru0x1103 | 0:ecd925601fc6 | 45 | UINT16 val : 12;//bit[11: 0] 書き込みデータ |
| takeru0x1103 | 0:ecd925601fc6 | 46 | UINT16 id : 4 ;//bit[15:12] レジスタアドレス |
| takeru0x1103 | 0:ecd925601fc6 | 47 | }bf; |
| takeru0x1103 | 0:ecd925601fc6 | 48 | }SPI_CMD; |
| takeru0x1103 | 0:ecd925601fc6 | 49 | |
| takeru0x1103 | 0:ecd925601fc6 | 50 | // ############################################################### |
| takeru0x1103 | 0:ecd925601fc6 | 51 | // グローバル変数 |
| takeru0x1103 | 0:ecd925601fc6 | 52 | // ############################################################### |
| takeru0x1103 | 0:ecd925601fc6 | 53 | static SPI spi (p5,p6,p7) ;//SPI通信ポート定義: mosi, miso, clk |
| takeru0x1103 | 8:1ca49cb18290 | 54 | static DigitalOut CS_n(p8) ;//SPIのチップセレクトピン |
| takeru0x1103 | 0:ecd925601fc6 | 55 | |
| takeru0x1103 | 8:1ca49cb18290 | 56 | //----------------------------------- |
| takeru0x1103 | 0:ecd925601fc6 | 57 | //SPIデータ送出 |
| takeru0x1103 | 8:1ca49cb18290 | 58 | //----------------------------------- |
| takeru0x1103 | 8:1ca49cb18290 | 59 | static UINT16 xSpi16bitSend(UINT16 dat){ |
| takeru0x1103 | 0:ecd925601fc6 | 60 | unsigned int rtn; |
| takeru0x1103 | 0:ecd925601fc6 | 61 | |
| takeru0x1103 | 0:ecd925601fc6 | 62 | CS_n= 0; //チップセレクトアサート |
| takeru0x1103 | 0:ecd925601fc6 | 63 | rtn = spi.write(dat); //データ出力 |
| takeru0x1103 | 0:ecd925601fc6 | 64 | CS_n = 1; //チップセレクトネゲート |
| takeru0x1103 | 8:1ca49cb18290 | 65 | return rtn; //SPIリードデータを返す |
| takeru0x1103 | 8:1ca49cb18290 | 66 | } |
| takeru0x1103 | 8:1ca49cb18290 | 67 | //----------------------------------- |
| takeru0x1103 | 8:1ca49cb18290 | 68 | //SPI送出データの組み立てて通信 |
| takeru0x1103 | 8:1ca49cb18290 | 69 | //----------------------------------- |
| takeru0x1103 | 8:1ca49cb18290 | 70 | static UINT16 xSpi(UCHAR id , UINT16 val){ |
| takeru0x1103 | 8:1ca49cb18290 | 71 | UINT16 spiRtn=0; |
| takeru0x1103 | 8:1ca49cb18290 | 72 | SPI_CMD cmd; |
| takeru0x1103 | 8:1ca49cb18290 | 73 | |
| takeru0x1103 | 8:1ca49cb18290 | 74 | //引数を送信するコマンドに成形 |
| takeru0x1103 | 8:1ca49cb18290 | 75 | cmd.bf.id = id; |
| takeru0x1103 | 8:1ca49cb18290 | 76 | cmd.bf.val = val; |
| takeru0x1103 | 8:1ca49cb18290 | 77 | //SPIデータ送出し読み出し値を取得 |
| takeru0x1103 | 8:1ca49cb18290 | 78 | spiRtn = xSpi16bitSend(cmd.spiCmd); |
| takeru0x1103 | 8:1ca49cb18290 | 79 | //レジスタ読み出し値を返す |
| takeru0x1103 | 8:1ca49cb18290 | 80 | return spiRtn; |
| takeru0x1103 | 0:ecd925601fc6 | 81 | } |
| takeru0x1103 | 0:ecd925601fc6 | 82 | |
| takeru0x1103 | 0:ecd925601fc6 | 83 | //================================================================ |
| takeru0x1103 | 0:ecd925601fc6 | 84 | //テストレジスタアクセス |
| takeru0x1103 | 0:ecd925601fc6 | 85 | //================================================================ |
| takeru0x1103 | 8:1ca49cb18290 | 86 | UINT16 fpgaTest(UINT16 val){ |
| takeru0x1103 | 8:1ca49cb18290 | 87 | //SPI通信 |
| takeru0x1103 | 8:1ca49cb18290 | 88 | UINT16 spiRtn = xSpi(ADR_TEST_REG , val); |
| takeru0x1103 | 8:1ca49cb18290 | 89 | //レジスタ読み出し値を返す |
| takeru0x1103 | 0:ecd925601fc6 | 90 | return spiRtn; |
| takeru0x1103 | 0:ecd925601fc6 | 91 | } |
| takeru0x1103 | 0:ecd925601fc6 | 92 | //================================================================ |
| takeru0x1103 | 0:ecd925601fc6 | 93 | //エンジン回転数を取得 |
| takeru0x1103 | 0:ecd925601fc6 | 94 | //================================================================ |
| takeru0x1103 | 0:ecd925601fc6 | 95 | UINT16 fpgaGetRpm(bool frontFlg){ |
| takeru0x1103 | 0:ecd925601fc6 | 96 | UINT16 RpmMsb=0; |
| takeru0x1103 | 0:ecd925601fc6 | 97 | UINT16 RpmLsb=0; |
| takeru0x1103 | 0:ecd925601fc6 | 98 | UINT32 Rpm=0; |
| takeru0x1103 | 0:ecd925601fc6 | 99 | double clc; |
| takeru0x1103 | 0:ecd925601fc6 | 100 | |
| takeru0x1103 | 8:1ca49cb18290 | 101 | RpmLsb = xSpi((frontFlg==true) ? ADR_RPM_FLSB : ADR_RPM_BLSB , 0);//下位12bit読み出し |
| takeru0x1103 | 8:1ca49cb18290 | 102 | RpmMsb = xSpi((frontFlg==true) ? ADR_RPM_FMSB : ADR_RPM_BMSB , 0);//上位12bit読み出し |
| takeru0x1103 | 0:ecd925601fc6 | 103 | |
| takeru0x1103 | 0:ecd925601fc6 | 104 | //24bit連結:48MHzのクロックサイクル数換算 |
| takeru0x1103 | 0:ecd925601fc6 | 105 | Rpm = (RpmMsb << 12) | RpmLsb; |
| takeru0x1103 | 0:ecd925601fc6 | 106 | |
| takeru0x1103 | 0:ecd925601fc6 | 107 | //RPM換算 |
| takeru0x1103 | 0:ecd925601fc6 | 108 | clc = (double)Rpm * CLK_CYC; |
| takeru0x1103 | 0:ecd925601fc6 | 109 | clc = clc / 1000; |
| takeru0x1103 | 0:ecd925601fc6 | 110 | clc = 30000000 / clc; |
| takeru0x1103 | 8:1ca49cb18290 | 111 | //回転数rpmを返す |
| takeru0x1103 | 0:ecd925601fc6 | 112 | return (UINT16)clc; |
| takeru0x1103 | 0:ecd925601fc6 | 113 | } |
| takeru0x1103 | 0:ecd925601fc6 | 114 | //================================================================ |
| takeru0x1103 | 8:1ca49cb18290 | 115 | //サブプロペラ設定 位置 0:前左 1:前右 2:後左 3:後右 |
| takeru0x1103 | 0:ecd925601fc6 | 116 | //================================================================ |
| takeru0x1103 | 18:5aa48aec9cae | 117 | bool fpgaSubProp(UCHAR iPos,INT16 iVal){ |
| takeru0x1103 | 18:5aa48aec9cae | 118 | UCHAR regAdr[1]; |
| takeru0x1103 | 18:5aa48aec9cae | 119 | UINT16 regVal; |
| takeru0x1103 | 0:ecd925601fc6 | 120 | |
| takeru0x1103 | 0:ecd925601fc6 | 121 | switch (iPos){ |
| takeru0x1103 | 0:ecd925601fc6 | 122 | case 0x0:// |
| takeru0x1103 | 18:5aa48aec9cae | 123 | regAdr[0] = ADR_SUB_FL_I; |
| takeru0x1103 | 18:5aa48aec9cae | 124 | regAdr[1] = ADR_SUB_FL_O; |
| takeru0x1103 | 0:ecd925601fc6 | 125 | break; |
| takeru0x1103 | 0:ecd925601fc6 | 126 | case 0x1:// |
| takeru0x1103 | 18:5aa48aec9cae | 127 | regAdr[0] = ADR_SUB_FR_I; |
| takeru0x1103 | 18:5aa48aec9cae | 128 | regAdr[1] = ADR_SUB_FR_O; |
| takeru0x1103 | 0:ecd925601fc6 | 129 | break; |
| takeru0x1103 | 0:ecd925601fc6 | 130 | case 0x2:// |
| takeru0x1103 | 18:5aa48aec9cae | 131 | regAdr[0] = ADR_SUB_BL_I; |
| takeru0x1103 | 18:5aa48aec9cae | 132 | regAdr[1] = ADR_SUB_BL_O; |
| takeru0x1103 | 0:ecd925601fc6 | 133 | break; |
| takeru0x1103 | 0:ecd925601fc6 | 134 | case 0x3:// |
| takeru0x1103 | 18:5aa48aec9cae | 135 | regAdr[0] = ADR_SUB_BR_I; |
| takeru0x1103 | 18:5aa48aec9cae | 136 | regAdr[1] = ADR_SUB_BR_O; |
| takeru0x1103 | 0:ecd925601fc6 | 137 | break; |
| takeru0x1103 | 0:ecd925601fc6 | 138 | default: |
| takeru0x1103 | 8:1ca49cb18290 | 139 | return false;//何もしないで終わる |
| takeru0x1103 | 0:ecd925601fc6 | 140 | } |
| takeru0x1103 | 18:5aa48aec9cae | 141 | |
| takeru0x1103 | 18:5aa48aec9cae | 142 | //レジスタ設定範囲内にリミット |
| takeru0x1103 | 20:0394e15412c3 | 143 | regVal = (iVal<0) ? 0 :(iVal>4095)? 4095 : iVal; |
| takeru0x1103 | 20:0394e15412c3 | 144 | // if(iVal<0){ |
| takeru0x1103 | 20:0394e15412c3 | 145 | // regVal = 0; |
| takeru0x1103 | 20:0394e15412c3 | 146 | // }else if(iVal>4095){ |
| takeru0x1103 | 20:0394e15412c3 | 147 | // regVal = 4095; |
| takeru0x1103 | 20:0394e15412c3 | 148 | // }else{ |
| takeru0x1103 | 20:0394e15412c3 | 149 | // regVal = iVal; |
| takeru0x1103 | 20:0394e15412c3 | 150 | // } |
| takeru0x1103 | 20:0394e15412c3 | 151 | |
| takeru0x1103 | 18:5aa48aec9cae | 152 | xSpi(regAdr[0] , regVal);//吸気側 |
| takeru0x1103 | 18:5aa48aec9cae | 153 | xSpi(regAdr[1] , regVal);//排気側 |
| takeru0x1103 | 8:1ca49cb18290 | 154 | |
| takeru0x1103 | 8:1ca49cb18290 | 155 | //正常終了 |
| takeru0x1103 | 8:1ca49cb18290 | 156 | return true; |
| takeru0x1103 | 8:1ca49cb18290 | 157 | } |
| takeru0x1103 | 8:1ca49cb18290 | 158 | |
| takeru0x1103 | 8:1ca49cb18290 | 159 | //================================================================ |
| takeru0x1103 | 20:0394e15412c3 | 160 | //モーター個別設定 |
| takeru0x1103 | 18:5aa48aec9cae | 161 | //================================================================ |
| takeru0x1103 | 20:0394e15412c3 | 162 | void fpgaMotor(UCHAR iPos,INT16 iVal){ |
| takeru0x1103 | 20:0394e15412c3 | 163 | UCHAR regAdr = ADR_SUB_FL_I;//モーターの先頭番地を指しておく |
| takeru0x1103 | 20:0394e15412c3 | 164 | UINT16 regVal; |
| takeru0x1103 | 18:5aa48aec9cae | 165 | |
| takeru0x1103 | 20:0394e15412c3 | 166 | if( iPos<8){ regAdr += iPos; } //指定位置だけオフセットさせる |
| MasashiNomura | 48:71aec693a7dc | 167 | // if(gf_Print.d1.bf.fb){ |
| MasashiNomura | 48:71aec693a7dc | 168 | // sp.printf("POS[%d] Val[%d]", iPos, iVal); |
| MasashiNomura | 48:71aec693a7dc | 169 | // } |
| takeru0x1103 | 20:0394e15412c3 | 170 | regVal = (iVal<0) ? 0 :(iVal>4095)? 4095 : iVal; //レジスタ設定範囲内にリミット |
| takeru0x1103 | 20:0394e15412c3 | 171 | xSpi(regAdr , regVal);// |
| takeru0x1103 | 18:5aa48aec9cae | 172 | } |
| takeru0x1103 | 18:5aa48aec9cae | 173 | |
| takeru0x1103 | 18:5aa48aec9cae | 174 | //================================================================ |
| takeru0x1103 | 8:1ca49cb18290 | 175 | //ユーザースイッチ読み取り |
| takeru0x1103 | 8:1ca49cb18290 | 176 | //================================================================ |
| takeru0x1103 | 8:1ca49cb18290 | 177 | UINT16 fpgaGetUserSw(){ |
| takeru0x1103 | 8:1ca49cb18290 | 178 | //SPIデータ送出/読み出し |
| takeru0x1103 | 8:1ca49cb18290 | 179 | UINT16 spiRtn = xSpi(ADR_USER_SW , 0); |
| takeru0x1103 | 8:1ca49cb18290 | 180 | //戻り値 |
| takeru0x1103 | 8:1ca49cb18290 | 181 | return spiRtn; |
| takeru0x1103 | 8:1ca49cb18290 | 182 | } |
| takeru0x1103 | 8:1ca49cb18290 | 183 | |
| takeru0x1103 | 8:1ca49cb18290 | 184 | //================================================================ |
| takeru0x1103 | 8:1ca49cb18290 | 185 | //アクセル設定 位置 0:前 1後 |
| takeru0x1103 | 8:1ca49cb18290 | 186 | //================================================================ |
| takeru0x1103 | 17:f9610f3cfa1b | 187 | void fpgaEngine(UCHAR iID , UINT16 iSlotl){ |
| takeru0x1103 | 17:f9610f3cfa1b | 188 | xSpi((iID==0)? ADR_ACCEL_F : ADR_ACCEL_B , iSlotl); |
| takeru0x1103 | 0:ecd925601fc6 | 189 | } |
| takeru0x1103 | 0:ecd925601fc6 | 190 | |
| takeru0x1103 | 0:ecd925601fc6 | 191 | //================================================================ |
| takeru0x1103 | 0:ecd925601fc6 | 192 | //FPGA初期化 |
| takeru0x1103 | 0:ecd925601fc6 | 193 | //================================================================ |
| takeru0x1103 | 0:ecd925601fc6 | 194 | void fpgaInit(){ |
| takeru0x1103 | 0:ecd925601fc6 | 195 | spi.format(16,3) ;//SPIのフォーマット指定(bit長、極性) |
| takeru0x1103 | 0:ecd925601fc6 | 196 | spi.frequency(500000) ;//クロック周波数 |
| takeru0x1103 | 0:ecd925601fc6 | 197 | CS_n =1 ;//Low有意なのでHighにしておく |
| takeru0x1103 | 20:0394e15412c3 | 198 | } |