├── README.md ├── example ├── 066906032A.csv ├── 066906032A.kp ├── 066906032A.mod └── 066906032A.ori └── src └── boostcontroller.asm /README.md: -------------------------------------------------------------------------------- 1 | # C167 Boost PID 2 | 3 | ## Description 4 | Custom boost PID controller implementation targeted for use in Bosch ME7 control units for N/A engines with aftermarket turbo installs. 5 | 6 | ## Features 7 | - 3D Precontrol map 8 | - Setpoint map per gear 9 | - Steady state and Dynamic modes 10 | - Operation windowing for on/off 11 | - Runs from pssol_w as setpoint and ps_w as actual measurement, compatible with MAF or MAP 12 | - Application mode for calibrating precontrol - open loop duty per RPM 13 | - Anti wind-up, D-kick prevention 14 | 15 | ## Installation 16 | Keil C167 assembler can be used to assemble the file. 17 | 18 | The main function should be placed into a scheduled task, that gets run not less than every 20ms. 19 | The frequency at which the PID is executed basically defines the scale of the units in the P, I and D maps. 20 | 21 | You need to re-configure a PWM output. Usually on ME7 with a boosted engine PW1 is the N75 output, on N/A they use that output for the manifold changeover flap, see the example file on how to do this. 22 | Any native output writes to the PWM need to be disabled also (CC 00). 23 | 24 | The function call to the last part of the code should go where rlsol_w is assigned. 25 | 26 | ## Hardware 27 | Just use a normal N75 from e.g. 1.8T and wire it into the manifold changeover output. 28 | 29 | ## Description of cal parameters from asm 30 | **fixdcmap** - Fixed DC map for application mode 31 | **fixdcflag** - When set to 1 the PID is turned off and fixdcmap values are output directly 32 | **pilotmap** - Pre-control DC map based on RPM and pssol_w. If you are going to be using it at significant elevation changes, it is a good idea to subtract pu_w from pssol_w when reading this map. 33 | **dcmax** - maximum allowed PWM 34 | **dcmin** - minimum allowed PWM 35 | **piden** - minimum pssol_w for enabling PID, should be at around spring cracking pressure 36 | **imaxthres** - threshold lderr to switch from dynamic (P/D mode) to steady state (PID mode) 37 | **pidpmap** - P-term 38 | **pidimap** - I-term 39 | **piddmap** - D-term 40 | **ldrxn** - requested load based on RPM and gear 41 | -------------------------------------------------------------------------------- /example/066906032A.csv: -------------------------------------------------------------------------------- 1 | Name;IdName;FolderName;Type;ViewMode;RWin;DataOrg;bReciprocal;bSigned;bDelta;bPercent;bOriginal;bOriginalValues;Columns;Rows;Radix;Comment;Precision;SkipBytes;LineSkipBytes;Fieldvalues.Name;Fieldvalues.Unit;Fieldvalues.Factor;Fieldvalues.Offset;Fieldvalues.StartAddr;AxisX.Name;AxisX.IdName;AxisX.Unit;AxisX.Factor;AxisX.Offset;AxisX.Radix;AxisX.bBackwards;AxisX.bReciprocal;AxisX.bSigned;AxisX.Precision;AxisX.DataSrc;AxisX.DataHeader;AxisX.DataAddr;AxisX.DataOrg;AxisX.SignatureByte;AxisX.SkipBytes;AxisY.Name;AxisY.IdName;AxisY.Unit;AxisY.Factor;AxisY.Offset;AxisY.Radix;AxisY.bBackwards;AxisY.bReciprocal;AxisY.bSigned;AxisY.Precision;AxisY.DataSrc;AxisY.DataHeader;AxisY.DataAddr;AxisY.DataOrg;AxisY.SignatureByte;AxisY.SkipBytes 2 | N75 fixed DC;;Boostcontrol;eEindim;eViewText;eBars;eLoHi;0;0;0;0;0;0;12;1;10;;1;0;0;-;-;0.008031;0;$17244;nmot_w;;-;0.25;0;10;0;0;0;-1;eRom;2;$1722C;eLoHi;0x0;0;-;;-;1;0;10;0;0;0;-1;eDataSrcNone;0;$0;eLoHi;0x0;0 3 | Force N75 fixed DC. 1:enabled, 0:disabled;;Boostcontrol;eEinzel;eViewText;eBars;eLoHi;0;0;0;0;1;0;1;1;10;;-1;0;0;-;-;1;0;$1725C;-;;-;1;0;10;0;0;0;-1;eDataSrcNone;0;$0;eLoHi;0x-1;0;-;;-;1;0;10;0;0;0;-1;eDataSrcNone;0;$0;eLoHi;0x-1;0 4 | Pilot map;;Boostcontrol;eZweidim;eViewText;eBars;eLoHi;0;0;0;0;0;0;8;16;10;;1;0;0;-;-;0.008031;0;$17292;-;;-;0.039063;0;10;0;0;0;0;eRom;4;$17282;eLoHi;0x-1;0;nmot_w;;-;0.25;0;10;0;0;0;-1;eRom;4;$17262;eLoHi;0x-1;0 5 | DCmax;;Boostcontrol;eEinzel;eViewText;eBars;eLoHi;0;0;0;0;0;0;1;1;10;;1;0;0;-;-;0.008031;0;$17392;-;;-;1;0;10;0;0;0;-1;eDataSrcNone;0;$0;eLoHi;0x-1;0;-;;-;1;0;10;0;0;0;-1;eDataSrcNone;0;$0;eLoHi;0x-1;0 6 | DCmin;;Boostcontrol;eEinzel;eViewText;eBars;eLoHi;0;0;0;0;0;0;1;1;10;;1;0;0;-;-;0.008031;0;$17394;-;;-;1;0;10;0;0;0;-1;eDataSrcNone;0;$0;eLoHi;0x-1;0;-;;-;1;0;10;0;0;0;-1;eDataSrcNone;0;$0;eLoHi;0x-1;0 7 | PID enable pssol threshold;;Boostcontrol;eEinzel;eViewText;eBars;eLoHi;0;0;0;0;0;0;1;1;10;;-1;0;0;pssol_w;mbar;0.039063;0;$17396;-;;-;1;0;10;0;0;0;-1;eDataSrcNone;0;$0;eLoHi;0x-1;0;-;;-;1;0;10;0;0;0;-1;eDataSrcNone;0;$0;eLoHi;0x-1;0 8 | I enable threshold;;Boostcontrol;eEinzel;eViewText;eBars;eLoHi;0;0;0;0;0;0;1;1;10;;-1;0;0;lderr_w;mbar;0.039063;0;$17398;-;;-;1;0;10;0;0;0;-1;eDataSrcNone;0;$0;eLoHi;0x-1;0;-;;-;1;0;10;0;0;0;-1;eDataSrcNone;0;$0;eLoHi;0x-1;0 9 | PID P;;Boostcontrol;eEindim;eViewText;eBars;eLoHi;0;1;0;0;0;0;12;1;10;;2;0;0;% per 100 hpa;-;0.002504;0;$173B4;nmot_w;;-;0.25;0;10;0;0;0;-1;eRom;2;$1739C;eLoHi;0x3BFF;0;-;;-;1;0;10;0;0;0;-1;eDataSrcNone;0;$0;eLoHi;0x2E35;0 10 | PID I;;Boostcontrol;eEindim;eViewText;eBars;eLoHi;0;1;0;0;0;0;12;1;10;;2;0;0;% per 100 hpa;-;0.002504;0;$173E6;-;;-;0.25;0;10;0;0;0;-1;eRom;2;$173CE;eLoHi;0xFFFF;0;-;;-;1;0;10;0;0;0;-1;eDataSrcNone;0;$0;eLoHi;0xFFFF;0 11 | PID D;;Boostcontrol;eZweidim;eViewText;eBars;eLoHi;0;1;0;0;0;0;4;8;10;;2;0;0;% per 100 hpa;-;0.002504;0;$1741A;lderr_w;;-;0.039063;0;10;0;0;0;-1;eRom;4;$17412;eLoHi;0x-1;0;nmot_w;;-;0.25;0;10;0;0;0;0;eRom;4;$17402;eLoHi;0x-1;0 12 | LDRXN;;Boostcontrol;eZweidim;eViewText;eBars;eLoHi;0;0;0;0;0;0;16;7;10;;0;0;0;-;-;0.023438;0;$1748C;-;;-;0.25;0;10;0;0;0;-1;eRom;4;$1746C;eLoHi;0x-1;0;-;;-;1;0;10;0;0;0;-1;eRom;4;$1745E;eLoHi;0x-1;0 13 | -------------------------------------------------------------------------------- /example/066906032A.kp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prj/C167BoostControl/01824ef846206c4b1cdefeaadd774857a696a3e0/example/066906032A.kp -------------------------------------------------------------------------------- /example/066906032A.mod: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prj/C167BoostControl/01824ef846206c4b1cdefeaadd774857a696a3e0/example/066906032A.mod -------------------------------------------------------------------------------- /example/066906032A.ori: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prj/C167BoostControl/01824ef846206c4b1cdefeaadd774857a696a3e0/example/066906032A.ori -------------------------------------------------------------------------------- /src/boostcontroller.asm: -------------------------------------------------------------------------------- 1 | $MOD167 2 | $SEGMENTED 3 | 4 | ; Functions 5 | READ_2D_MAP equ 05A7Eh 6 | READ_3D_MAP equ 073DEh 7 | 8 | ; Variables 9 | nmot_w equ 0F888h 10 | rlsol_w equ 01F50h + 0x8000 11 | gangi equ 09A7h + 0x8000 12 | ps_w EQU 0F9A4h 13 | PW1 DEFR 0FE32H 14 | pssol_w equ 01F02h + 0x8000 15 | lderr equ 04300h 16 | abserr equ 04302h 17 | pterm equ 04304h 18 | iterm equ 04306h 19 | dterm equ 04308h 20 | ps_w_prev EQU 0430Ah 21 | pilot_prev EQU 0430Ch 22 | dynamic_mode EQU 0430Eh 23 | ps_w_prev_1 EQU 04310h 24 | ps_w_prev_2 EQU 04312h 25 | ps_w_prev_3 EQU 04314h 26 | ps_delta_w EQU 04316h 27 | 28 | 29 | ; Maps 30 | fixdcmap EQU 0322Ah 31 | map_seg EQU 0205h 32 | fixdcflag EQU 0325Ch 33 | pilotmap EQU 0725Eh 34 | dcmax EQU 03392h 35 | dcmin EQU 03394h 36 | piden EQU 03396h 37 | imaxthres EQU 03398h 38 | pidpmap EQU 0339Ah 39 | pidimap EQU 033CCh 40 | piddmap EQU 073FEh 41 | ldrxn EQU 0745Ah 42 | 43 | subcheckbounds MACRO 44 | LOCAL check_negative, ok 45 | JMPR cc_C, check_negative 46 | JMPR cc_NN, ok 47 | MOV R4, #7FFFh 48 | JMPR cc_UC, ok 49 | check_negative: 50 | JMPR cc_N, ok 51 | MOV R4, #8000h 52 | ok: 53 | ENDM 54 | 55 | addcheckbounds MACRO 56 | LOCAL overflow2, ok2, maxpos2 57 | JMPR cc_V, overflow2 58 | JMPR cc_UC, ok2 59 | overflow2: 60 | JMPR cc_N, maxpos2 61 | MOV R4, #08000h 62 | JMPR cc_UC, ok2 63 | maxpos2: 64 | MOV R4, #07FFFh 65 | ok2: 66 | ENDM 67 | 68 | shiftval MACRO 69 | LOCAL boundscheck, doshift, finished, maxpos 70 | MOV R12, MDH 71 | JMPR cc_NN boundscheck 72 | NEG R12 73 | boundscheck: 74 | AND R12, #0F000h 75 | JMPR cc_Z, doshift 76 | MOV R12, MDH 77 | JMPR cc_NN maxpos 78 | MOV R12, #8000h 79 | JMPR cc_UC, finished 80 | maxpos: 81 | MOV R12, #7FFFh 82 | JMPR cc_UC, finished 83 | doshift: 84 | MOV R12, MDH 85 | MOV R13, MDL 86 | SHL R12, #3d 87 | SHR R13, #15d 88 | OR R12, R13 89 | finished: 90 | ENDM 91 | 92 | boostcontrol SECTION CODE 'NCODE' 93 | controltest proc far 94 | EXTP #map_seg, #1 95 | MOV R4, fixdcflag 96 | JMP CC_z, standard 97 | MOV R12, #fixdcmap 98 | MOV R13, #map_seg 99 | MOV R14, nmot_w 100 | CALLS 082h, READ_2D_MAP 101 | MOV PW1, R4 102 | RETS 103 | standard: 104 | MOV R4, pssol_w 105 | EXTP #map_seg, #1 106 | CMP R4, piden 107 | JMPR cc_NC, pidon 108 | MOV R4, ps_w 109 | EXTS #38h, #4 110 | MOV ps_w_prev, R4 111 | MOV ps_w_prev_1, R4 112 | MOV ps_w_prev_2, R4 113 | MOV ps_w_prev_3, R4 114 | EXTP #map_seg, #1 115 | MOV R4, dcmin 116 | MOV PW1, R4 117 | RETS 118 | pidon: 119 | MOV R4, pssol_w 120 | SUB R4, ps_w 121 | subcheckbounds 122 | EXTS #38h, #1 123 | MOV lderr, R4 124 | JMPR cc_NN, checkforcepidout 125 | NEG R4 126 | 127 | checkforcepidout: 128 | EXTS #38h, #1 129 | MOV abserr, R4 130 | MOV R4, #00h 131 | EXTS #38h, #2 132 | MOV dynamic_mode, R4 133 | MOV R4, lderr 134 | JMPR cc_N, fullcontrol 135 | EXTP #map_seg, #1 136 | CMP R4, imaxthres 137 | JMPR cc_N, fullcontrol 138 | MOV R4, #01h 139 | EXTS #38h, #1 140 | MOV dynamic_mode, R4 141 | 142 | fullcontrol: 143 | ;Read pilot 144 | MOV R12, #pilotmap 145 | MOV R13, nmot_w 146 | MOV R14, pssol_w 147 | CALLS 00h, READ_3D_MAP 148 | EXTS #38h, #1 149 | MOV R5, dynamic_mode 150 | JMPR cc_Z, calci 151 | ;Dynamic mode, I fixed to pilot 152 | EXTS #38h, #2 153 | MOV iterm, R4 154 | MOV pilot_prev, R4 155 | JMPR cc_UC, calcp 156 | ;Steady state, I control 157 | calci: 158 | EXTS #38h, #2 159 | MOV R5, pilot_prev 160 | MOV pilot_prev, R4 161 | SUB R4, R5 162 | subcheckbounds 163 | MOV R8, R4 164 | MOV R12, #pidimap 165 | MOV R13, #map_seg 166 | MOV R14, nmot_w 167 | CALLS 082h, READ_2D_MAP 168 | EXTS #38h, #1 169 | MOV R6, lderr 170 | MUL R4, R6 171 | shiftval 172 | MOV R4, R8 173 | ADD R4, R12 174 | addcheckbounds 175 | EXTS #38h, #1 176 | ADD R4, iterm 177 | addcheckbounds 178 | EXTP #map_seg, #1 179 | CMP R4, dcmax 180 | JMPR cc_N, checklower 181 | EXTP #map_seg, #1 182 | MOV R4, dcmax 183 | JMPR cc_UC, storei 184 | checklower: 185 | EXTP #map_seg, #1 186 | CMP R4, dcmin 187 | JMPR cc_NN, storei 188 | EXTP #map_seg, #1 189 | MOV R4, dcmin 190 | storei: 191 | EXTS #38h, #1 192 | MOV iterm, R4 193 | 194 | calcp: 195 | MOV R12, #pidpmap 196 | MOV R13, #map_seg 197 | MOV R14, nmot_w 198 | CALLS 082h, READ_2D_MAP 199 | EXTS #38h, #1 200 | MOV R5, lderr 201 | MUL R4, R5 202 | shiftval 203 | EXTS #38h, #1 204 | MOV pterm, R12 205 | 206 | calcd: 207 | MOV R8, ps_w 208 | EXTS #38h, #1 209 | MOV R4, ps_w_prev_3 210 | SUB R4, R8 211 | subcheckbounds 212 | EXTS #38h, #1 213 | MOV ps_delta_w, R4 214 | MOV R8, R4 215 | MOV R12, #piddmap 216 | MOV R13, nmot_w 217 | EXTS #38h, #1 218 | MOV R14, abserr 219 | CALLS 00h, READ_3D_MAP 220 | MUL R4, R8 221 | shiftval 222 | EXTS #38h, #1 223 | MOV dterm, R12 224 | ; Store ps_w history 225 | MOV R4, ps_w 226 | EXTS #38h, #3 227 | MOV R5, ps_w_prev 228 | MOV R6, ps_w_prev_1 229 | MOV R7, ps_w_prev_2 230 | EXTS #38h, #4 231 | MOV ps_w_prev, R4 232 | MOV ps_w_prev_1, R5 233 | MOV ps_w_prev_2, R6 234 | MOV ps_w_prev_3, R7 235 | 236 | calcpid: 237 | MOV R4, #00h 238 | EXTS #38h, #1 239 | ADD R4, dterm 240 | addcheckbounds 241 | EXTS #38h, #1 242 | ADD R4, pterm 243 | addcheckbounds 244 | EXTS #38h, #1 245 | ADD R4, iterm 246 | addcheckbounds 247 | EXTP #map_seg, #1 248 | CMP R4, dcmax 249 | JMPR cc_N, checklowerpid 250 | EXTP #map_seg, #1 251 | MOV R4, dcmax 252 | JMPR cc_UC, storepid 253 | checklowerpid: 254 | EXTP #map_seg, #1 255 | CMP R4, dcmin 256 | JMPR cc_NN, storepid 257 | EXTP #map_seg, #1 258 | MOV R4, dcmin 259 | 260 | storepid: 261 | 262 | MOV PW1, R4 263 | RETS 264 | 265 | NOP 266 | NOP 267 | NOP 268 | NOP 269 | 270 | MOV R12, #ldrxn 271 | MOVBZ R13, gangi 272 | MOV R14, nmot_w 273 | CALLS 00h, READ_3D_MAP 274 | CMP R4, rlsol_w 275 | JMPR cc_NC, nolimit 276 | MOV rlsol_w, R4 277 | nolimit: 278 | MOV R4, rlsol_w 279 | RETS 280 | 281 | controltest endp 282 | boostcontrol ENDS 283 | END --------------------------------------------------------------------------------