Interference current stimulation program with kaji-lab ES device.

Dependencies:   mbed SerialInputReactionHandler AMPulseTrain SwArr16MOSFET StrCommandHandler KajiLabES

Committer:
aktk
Date:
Wed Nov 27 23:41:55 2019 +0000
Revision:
2:5cb68cc8ecaa
Child:
3:ef730909a664
nov 27th 2019 digital sin works

Who changed what in which revision?

UserRevisionLine numberNew contents of line
aktk 2:5cb68cc8ecaa 1 #include "subroutines.h"
aktk 2:5cb68cc8ecaa 2
aktk 2:5cb68cc8ecaa 3 #include "KajiLabES.h"
aktk 2:5cb68cc8ecaa 4
aktk 2:5cb68cc8ecaa 5 #include "SwArr16MOSFET.h"
aktk 2:5cb68cc8ecaa 6
aktk 2:5cb68cc8ecaa 7 #include "DSinGenerator.h"
aktk 2:5cb68cc8ecaa 8 #include "StrCommandHandler.h"
aktk 2:5cb68cc8ecaa 9 #include "SerialInputReactionHandler.h"
aktk 2:5cb68cc8ecaa 10
aktk 2:5cb68cc8ecaa 11 Serial pc(USBTX, USBRX, 921600); // tx, rx
aktk 2:5cb68cc8ecaa 12 Ticker ticker;
aktk 2:5cb68cc8ecaa 13 KajiLabES stimulator;
aktk 2:5cb68cc8ecaa 14 SwArr16MOSFET swBrd(4, p11, p12, p13, p14, p10);
aktk 2:5cb68cc8ecaa 15 DSinGenerator singen (
aktk 2:5cb68cc8ecaa 16 /*Initial Amplitude*/ 0,
aktk 2:5cb68cc8ecaa 17 /*Initial Frequency*/ 4000,
aktk 2:5cb68cc8ecaa 18 /*Discret.-fineness*/ 16
aktk 2:5cb68cc8ecaa 19 );
aktk 2:5cb68cc8ecaa 20 StrCommandHandler command_handler;
aktk 2:5cb68cc8ecaa 21 SerialInputReactionHandler reactor; //todo: implement function replace sigbind.cpp/h
aktk 2:5cb68cc8ecaa 22
aktk 2:5cb68cc8ecaa 23
aktk 2:5cb68cc8ecaa 24 void init (void)
aktk 2:5cb68cc8ecaa 25 {
aktk 2:5cb68cc8ecaa 26 //void init_Hardware(void)
aktk 2:5cb68cc8ecaa 27 {
aktk 2:5cb68cc8ecaa 28 stimulator.init();
aktk 2:5cb68cc8ecaa 29 swBrd.allHiZ();
aktk 2:5cb68cc8ecaa 30 swBrd.setPol(SwArr16MOSFET::Cathodic);
aktk 2:5cb68cc8ecaa 31 swBrd.setTwin(1,2);
aktk 2:5cb68cc8ecaa 32 }
aktk 2:5cb68cc8ecaa 33 myled1 = 1;
aktk 2:5cb68cc8ecaa 34
aktk 2:5cb68cc8ecaa 35 NVIC_SetPriority(TIMER3_IRQn, 1);
aktk 2:5cb68cc8ecaa 36
aktk 2:5cb68cc8ecaa 37 //void init_commands(void)
aktk 2:5cb68cc8ecaa 38 {
aktk 2:5cb68cc8ecaa 39 command_handler.map("a", &switchState);
aktk 2:5cb68cc8ecaa 40 command_handler.map("E", &terminateLoop);
aktk 2:5cb68cc8ecaa 41 command_handler.map("S", &startLoop);
aktk 2:5cb68cc8ecaa 42 command_handler.map("P", &pauseLoop);
aktk 2:5cb68cc8ecaa 43 command_handler.map("v", &beginParamsSetting);
aktk 2:5cb68cc8ecaa 44 command_handler.map("p", &printStatus);
aktk 2:5cb68cc8ecaa 45 command_handler.map(StrCommandHandler::ARROW_UP, &increaseCurrent);
aktk 2:5cb68cc8ecaa 46 command_handler.map(StrCommandHandler::ARROW_DOWN, &decreaseCurrent);
aktk 2:5cb68cc8ecaa 47 command_handler.map(StrCommandHandler::ARROW_RIGHT, &increaseFrequency);
aktk 2:5cb68cc8ecaa 48 command_handler.map(StrCommandHandler::ARROW_LEFT, &decreaseFrequency);
aktk 2:5cb68cc8ecaa 49 reactor.attach(callback(&command_handler, &StrCommandHandler::exe));
aktk 2:5cb68cc8ecaa 50 reactor.attach_PostProc(&calleddefault);
aktk 2:5cb68cc8ecaa 51 reactor.startReception(&pc, SerialInputReactionHandler::KB_SINGLE_INPUT);
aktk 2:5cb68cc8ecaa 52 }
aktk 2:5cb68cc8ecaa 53 printKBManual();
aktk 2:5cb68cc8ecaa 54 printDSinSamples();
aktk 2:5cb68cc8ecaa 55 wait(.1);
aktk 2:5cb68cc8ecaa 56 myled2 = 1;
aktk 2:5cb68cc8ecaa 57 }
aktk 2:5cb68cc8ecaa 58
aktk 2:5cb68cc8ecaa 59
aktk 2:5cb68cc8ecaa 60
aktk 2:5cb68cc8ecaa 61 void loop()
aktk 2:5cb68cc8ecaa 62 {
aktk 2:5cb68cc8ecaa 63 static int ph = 0;
aktk 2:5cb68cc8ecaa 64 static int ph_sign = 0;
aktk 2:5cb68cc8ecaa 65
aktk 2:5cb68cc8ecaa 66 myled4 = 1;
aktk 2:5cb68cc8ecaa 67
aktk 2:5cb68cc8ecaa 68 ph = singen.getValue_p16m16();
aktk 2:5cb68cc8ecaa 69 if(ph > 0) {
aktk 2:5cb68cc8ecaa 70 ph_sign = 1;
aktk 2:5cb68cc8ecaa 71 }
aktk 2:5cb68cc8ecaa 72 // when ph is negaive, make it positive
aktk 2:5cb68cc8ecaa 73 else if (ph < 0) {
aktk 2:5cb68cc8ecaa 74 ph = -ph;
aktk 2:5cb68cc8ecaa 75 ph_sign = -1;
aktk 2:5cb68cc8ecaa 76 }
aktk 2:5cb68cc8ecaa 77 stimulator.DAAD(ph);
aktk 2:5cb68cc8ecaa 78
aktk 2:5cb68cc8ecaa 79 if(ph == 0) {
aktk 2:5cb68cc8ecaa 80 if (ph_sign > 0)
aktk 2:5cb68cc8ecaa 81 swBrd.setTwin(1, 4);
aktk 2:5cb68cc8ecaa 82
aktk 2:5cb68cc8ecaa 83 else if (ph_sign < 0)
aktk 2:5cb68cc8ecaa 84 swBrd.setTwin(4, 1);
aktk 2:5cb68cc8ecaa 85 else;
aktk 2:5cb68cc8ecaa 86 ph_sign = 0;
aktk 2:5cb68cc8ecaa 87 }
aktk 2:5cb68cc8ecaa 88
aktk 2:5cb68cc8ecaa 89 myled4 = 0;
aktk 2:5cb68cc8ecaa 90 }
aktk 2:5cb68cc8ecaa 91
aktk 2:5cb68cc8ecaa 92
aktk 2:5cb68cc8ecaa 93
aktk 2:5cb68cc8ecaa 94 void calleddefault(char const * const arg_command, void * arg_errorcode)
aktk 2:5cb68cc8ecaa 95 {
aktk 2:5cb68cc8ecaa 96 int errorcode = *(int*)arg_errorcode;
aktk 2:5cb68cc8ecaa 97 if (errorcode != 0xFFFFFFFC) return;
aktk 2:5cb68cc8ecaa 98 printKBManual();
aktk 2:5cb68cc8ecaa 99 pc.printf("Sent data was: %d(%c)(%s)\n", arg_command[0], arg_command[0], arg_command);
aktk 2:5cb68cc8ecaa 100 }
aktk 2:5cb68cc8ecaa 101
aktk 2:5cb68cc8ecaa 102
aktk 2:5cb68cc8ecaa 103 void * switchState()
aktk 2:5cb68cc8ecaa 104 {
aktk 2:5cb68cc8ecaa 105 if (pstate == MAIN_ROUTINE)
aktk 2:5cb68cc8ecaa 106 pauseLoop();
aktk 2:5cb68cc8ecaa 107 else if (pstate == WAIT_A_CERTAIN_KEY) {
aktk 2:5cb68cc8ecaa 108 startLoop();
aktk 2:5cb68cc8ecaa 109
aktk 2:5cb68cc8ecaa 110 }
aktk 2:5cb68cc8ecaa 111 return NULL;
aktk 2:5cb68cc8ecaa 112 }
aktk 2:5cb68cc8ecaa 113
aktk 2:5cb68cc8ecaa 114
aktk 2:5cb68cc8ecaa 115 void * startLoop(void)
aktk 2:5cb68cc8ecaa 116 {
aktk 2:5cb68cc8ecaa 117 if (pstate != WAIT_A_CERTAIN_KEY) return NULL;
aktk 2:5cb68cc8ecaa 118
aktk 2:5cb68cc8ecaa 119 ticker.attach_us(loop, singen.getPulseWidth());
aktk 2:5cb68cc8ecaa 120 pstate = MAIN_ROUTINE;
aktk 2:5cb68cc8ecaa 121 pc.printf("start\n");
aktk 2:5cb68cc8ecaa 122 return NULL;
aktk 2:5cb68cc8ecaa 123 }
aktk 2:5cb68cc8ecaa 124
aktk 2:5cb68cc8ecaa 125
aktk 2:5cb68cc8ecaa 126
aktk 2:5cb68cc8ecaa 127 void * pauseLoop(void)
aktk 2:5cb68cc8ecaa 128 {
aktk 2:5cb68cc8ecaa 129 if (pstate != MAIN_ROUTINE) return NULL;
aktk 2:5cb68cc8ecaa 130
aktk 2:5cb68cc8ecaa 131 stimulator.DAAD(0);
aktk 2:5cb68cc8ecaa 132 ticker.detach();
aktk 2:5cb68cc8ecaa 133 pstate = WAIT_A_CERTAIN_KEY;
aktk 2:5cb68cc8ecaa 134 pc.printf("stop\n");
aktk 2:5cb68cc8ecaa 135 return NULL;
aktk 2:5cb68cc8ecaa 136 }
aktk 2:5cb68cc8ecaa 137
aktk 2:5cb68cc8ecaa 138
aktk 2:5cb68cc8ecaa 139
aktk 2:5cb68cc8ecaa 140 void * terminateLoop(void)
aktk 2:5cb68cc8ecaa 141 {
aktk 2:5cb68cc8ecaa 142 stimulator.DAAD(0);
aktk 2:5cb68cc8ecaa 143 ticker.detach();
aktk 2:5cb68cc8ecaa 144 pstate = TERMINATED;
aktk 2:5cb68cc8ecaa 145 pc.puts("TERMINATED");
aktk 2:5cb68cc8ecaa 146 return NULL;
aktk 2:5cb68cc8ecaa 147 }
aktk 2:5cb68cc8ecaa 148
aktk 2:5cb68cc8ecaa 149
aktk 2:5cb68cc8ecaa 150
aktk 2:5cb68cc8ecaa 151 void * increaseCurrent(void)
aktk 2:5cb68cc8ecaa 152 {
aktk 2:5cb68cc8ecaa 153 float lampl = singen.getAmplitude();
aktk 2:5cb68cc8ecaa 154 if(lampl < singen.ampl_max - 0.5)
aktk 2:5cb68cc8ecaa 155 lampl += 0.5;
aktk 2:5cb68cc8ecaa 156 else
aktk 2:5cb68cc8ecaa 157 lampl = singen.ampl_max;
aktk 2:5cb68cc8ecaa 158 singen.setAmplitude(lampl);
aktk 2:5cb68cc8ecaa 159 printStatus();
aktk 2:5cb68cc8ecaa 160 return NULL;
aktk 2:5cb68cc8ecaa 161 }
aktk 2:5cb68cc8ecaa 162
aktk 2:5cb68cc8ecaa 163
aktk 2:5cb68cc8ecaa 164
aktk 2:5cb68cc8ecaa 165 void * decreaseCurrent(void)
aktk 2:5cb68cc8ecaa 166 {
aktk 2:5cb68cc8ecaa 167 float lampl = singen.getAmplitude();
aktk 2:5cb68cc8ecaa 168 if(1 <= lampl )
aktk 2:5cb68cc8ecaa 169 lampl -= 0.5;
aktk 2:5cb68cc8ecaa 170 else
aktk 2:5cb68cc8ecaa 171 lampl = 0;
aktk 2:5cb68cc8ecaa 172 singen.setAmplitude(lampl);
aktk 2:5cb68cc8ecaa 173 printStatus();
aktk 2:5cb68cc8ecaa 174 return NULL;
aktk 2:5cb68cc8ecaa 175 }
aktk 2:5cb68cc8ecaa 176
aktk 2:5cb68cc8ecaa 177
aktk 2:5cb68cc8ecaa 178
aktk 2:5cb68cc8ecaa 179 void * increaseFrequency(void)
aktk 2:5cb68cc8ecaa 180 {
aktk 2:5cb68cc8ecaa 181 uint16_t lfreq = singen.getFrequency();
aktk 2:5cb68cc8ecaa 182 if(lfreq < singen.freq_max - 10)
aktk 2:5cb68cc8ecaa 183 lfreq += 10;
aktk 2:5cb68cc8ecaa 184 else
aktk 2:5cb68cc8ecaa 185 lfreq = 5000;
aktk 2:5cb68cc8ecaa 186 singen.setFrequency(lfreq);
aktk 2:5cb68cc8ecaa 187 ticker.attach_us(loop, singen.getPulseWidth());
aktk 2:5cb68cc8ecaa 188 printStatus();
aktk 2:5cb68cc8ecaa 189 return NULL;
aktk 2:5cb68cc8ecaa 190 }
aktk 2:5cb68cc8ecaa 191
aktk 2:5cb68cc8ecaa 192
aktk 2:5cb68cc8ecaa 193
aktk 2:5cb68cc8ecaa 194 void * decreaseFrequency(void)
aktk 2:5cb68cc8ecaa 195 {
aktk 2:5cb68cc8ecaa 196 uint16_t lfreq = singen.getFrequency();
aktk 2:5cb68cc8ecaa 197 if(20 <= lfreq )
aktk 2:5cb68cc8ecaa 198 lfreq -= 10;
aktk 2:5cb68cc8ecaa 199 else
aktk 2:5cb68cc8ecaa 200 lfreq = 10;
aktk 2:5cb68cc8ecaa 201 singen.setFrequency(lfreq);
aktk 2:5cb68cc8ecaa 202 ticker.attach_us(loop, singen.getPulseWidth());
aktk 2:5cb68cc8ecaa 203 printStatus();
aktk 2:5cb68cc8ecaa 204 return NULL;
aktk 2:5cb68cc8ecaa 205 }
aktk 2:5cb68cc8ecaa 206
aktk 2:5cb68cc8ecaa 207
aktk 2:5cb68cc8ecaa 208
aktk 2:5cb68cc8ecaa 209 template <typename T>
aktk 2:5cb68cc8ecaa 210 bool scanValue(char const * const arg_digits, T * const arg_dest)
aktk 2:5cb68cc8ecaa 211 {
aktk 2:5cb68cc8ecaa 212 int l_len = 0;
aktk 2:5cb68cc8ecaa 213 int l_digit = 0;
aktk 2:5cb68cc8ecaa 214 int l_value = 0;
aktk 2:5cb68cc8ecaa 215 bool l_isfloat = false;
aktk 2:5cb68cc8ecaa 216
aktk 2:5cb68cc8ecaa 217 while (arg_digits[l_len] != '\0') {
aktk 2:5cb68cc8ecaa 218
aktk 2:5cb68cc8ecaa 219 if (l_len > 50) {
aktk 2:5cb68cc8ecaa 220 pc.puts("\nerror: too long number of digits\n");
aktk 2:5cb68cc8ecaa 221 return false;
aktk 2:5cb68cc8ecaa 222 }
aktk 2:5cb68cc8ecaa 223
aktk 2:5cb68cc8ecaa 224 if ('0' <= arg_digits[l_len] && arg_digits[l_len] <= '9')
aktk 2:5cb68cc8ecaa 225 l_digit = arg_digits[l_len] - '0';
aktk 2:5cb68cc8ecaa 226 else if(arg_digits[l_len] != '.')
aktk 2:5cb68cc8ecaa 227 if(l_isfloat)
aktk 2:5cb68cc8ecaa 228 return false;
aktk 2:5cb68cc8ecaa 229 else
aktk 2:5cb68cc8ecaa 230 l_isfloat = true;
aktk 2:5cb68cc8ecaa 231 else return false;
aktk 2:5cb68cc8ecaa 232
aktk 2:5cb68cc8ecaa 233 if(l_isfloat) l_digit /= 10;
aktk 2:5cb68cc8ecaa 234 else l_value *= 10;
aktk 2:5cb68cc8ecaa 235
aktk 2:5cb68cc8ecaa 236 l_value += l_digit;
aktk 2:5cb68cc8ecaa 237 l_len++;
aktk 2:5cb68cc8ecaa 238 }
aktk 2:5cb68cc8ecaa 239
aktk 2:5cb68cc8ecaa 240 *arg_dest = static_cast<T>(l_value);
aktk 2:5cb68cc8ecaa 241 return true;
aktk 2:5cb68cc8ecaa 242 }
aktk 2:5cb68cc8ecaa 243
aktk 2:5cb68cc8ecaa 244
aktk 2:5cb68cc8ecaa 245
aktk 2:5cb68cc8ecaa 246
aktk 2:5cb68cc8ecaa 247 void * beginParamsSetting(void)
aktk 2:5cb68cc8ecaa 248 {
aktk 2:5cb68cc8ecaa 249 pauseLoop();
aktk 2:5cb68cc8ecaa 250 reactor.changeMode(SerialInputReactionHandler::KB_TILL_ENTER);
aktk 2:5cb68cc8ecaa 251
aktk 2:5cb68cc8ecaa 252 pc.puts("---\n");
aktk 2:5cb68cc8ecaa 253 pc.printf("set amplitude:");
aktk 2:5cb68cc8ecaa 254 reactor.attach(SetAmplitude);
aktk 2:5cb68cc8ecaa 255 return NULL;
aktk 2:5cb68cc8ecaa 256 }
aktk 2:5cb68cc8ecaa 257
aktk 2:5cb68cc8ecaa 258 void * SetAmplitude(char const * const arg_digits)
aktk 2:5cb68cc8ecaa 259 {
aktk 2:5cb68cc8ecaa 260 float lampl = singen.getAmplitude();
aktk 2:5cb68cc8ecaa 261
aktk 2:5cb68cc8ecaa 262 // read values
aktk 2:5cb68cc8ecaa 263 if (scanValue(arg_digits, &lampl));
aktk 2:5cb68cc8ecaa 264
aktk 2:5cb68cc8ecaa 265 // set values
aktk 2:5cb68cc8ecaa 266 if( lampl < 0 || singen.ampl_max < lampl) lampl = singen.getAmplitude();
aktk 2:5cb68cc8ecaa 267 singen.setAmplitude(lampl);
aktk 2:5cb68cc8ecaa 268
aktk 2:5cb68cc8ecaa 269 pc.puts("===\n");
aktk 2:5cb68cc8ecaa 270 pc.printf("set frequency:");
aktk 2:5cb68cc8ecaa 271 reactor.attach(SetFrequency);
aktk 2:5cb68cc8ecaa 272 return NULL;
aktk 2:5cb68cc8ecaa 273 }
aktk 2:5cb68cc8ecaa 274
aktk 2:5cb68cc8ecaa 275 void * SetFrequency(char const * const arg_digits)
aktk 2:5cb68cc8ecaa 276 {
aktk 2:5cb68cc8ecaa 277 uint16_t lfreq = singen.getFrequency();
aktk 2:5cb68cc8ecaa 278
aktk 2:5cb68cc8ecaa 279 if (scanValue(arg_digits, &lfreq));
aktk 2:5cb68cc8ecaa 280
aktk 2:5cb68cc8ecaa 281 if( lfreq < 500 || singen.freq_max < lfreq) lfreq = singen.getFrequency();
aktk 2:5cb68cc8ecaa 282 singen.setFrequency(lfreq);
aktk 2:5cb68cc8ecaa 283
aktk 2:5cb68cc8ecaa 284 pc.puts("...\n");
aktk 2:5cb68cc8ecaa 285 printStatus();
aktk 2:5cb68cc8ecaa 286 endParamsSetting();
aktk 2:5cb68cc8ecaa 287 return NULL;
aktk 2:5cb68cc8ecaa 288 }
aktk 2:5cb68cc8ecaa 289
aktk 2:5cb68cc8ecaa 290 void * endParamsSetting(void)
aktk 2:5cb68cc8ecaa 291 {
aktk 2:5cb68cc8ecaa 292 reactor.changeMode(SerialInputReactionHandler::KB_SINGLE_INPUT);
aktk 2:5cb68cc8ecaa 293 reactor.attach(callback(&command_handler, &StrCommandHandler::exe));
aktk 2:5cb68cc8ecaa 294 startLoop();
aktk 2:5cb68cc8ecaa 295 return NULL;
aktk 2:5cb68cc8ecaa 296 }
aktk 2:5cb68cc8ecaa 297
aktk 2:5cb68cc8ecaa 298
aktk 2:5cb68cc8ecaa 299
aktk 2:5cb68cc8ecaa 300 void * printKBManual(void)
aktk 2:5cb68cc8ecaa 301 {
aktk 2:5cb68cc8ecaa 302 pc.puts(
aktk 2:5cb68cc8ecaa 303 "\n"
aktk 2:5cb68cc8ecaa 304 "keybind are following:\n"
aktk 2:5cb68cc8ecaa 305 " ---\n"
aktk 2:5cb68cc8ecaa 306 " v: set all paramater by arbitrary value\n"
aktk 2:5cb68cc8ecaa 307 " ---\n"
aktk 2:5cb68cc8ecaa 308 " UP: Amplitude + 1(mA)\n"
aktk 2:5cb68cc8ecaa 309 " Down: Amplitude - 1(mA)\n"
aktk 2:5cb68cc8ecaa 310 " Right: Frequency +10(Hz)\n"
aktk 2:5cb68cc8ecaa 311 " Left: Frequency -10(Hz)\n"
aktk 2:5cb68cc8ecaa 312 " ---\n"
aktk 2:5cb68cc8ecaa 313 " p: print wave parameter\n"
aktk 2:5cb68cc8ecaa 314 " ---\n"
aktk 2:5cb68cc8ecaa 315 " a: Start or Pause main loop\n"
aktk 2:5cb68cc8ecaa 316 " S: Start or Resume Stimulation\n"
aktk 2:5cb68cc8ecaa 317 " P: Pause Stimulation\n"
aktk 2:5cb68cc8ecaa 318 " E(shift+a): terminate the loop\n"
aktk 2:5cb68cc8ecaa 319 "\n");
aktk 2:5cb68cc8ecaa 320 return NULL;
aktk 2:5cb68cc8ecaa 321 }
aktk 2:5cb68cc8ecaa 322
aktk 2:5cb68cc8ecaa 323 void * printStatus(void)
aktk 2:5cb68cc8ecaa 324 {
aktk 2:5cb68cc8ecaa 325 pc.printf(
aktk 2:5cb68cc8ecaa 326 "Amplitude: %2.3f "
aktk 2:5cb68cc8ecaa 327 "Frequency: %05d "
aktk 2:5cb68cc8ecaa 328 "Pulse Width:%05d\n"
aktk 2:5cb68cc8ecaa 329 , singen.getAmplitude(), singen.getFrequency(), singen.getPulseWidth());
aktk 2:5cb68cc8ecaa 330 return NULL;
aktk 2:5cb68cc8ecaa 331 }
aktk 2:5cb68cc8ecaa 332
aktk 2:5cb68cc8ecaa 333 void * printDSinSamples(void)
aktk 2:5cb68cc8ecaa 334 {
aktk 2:5cb68cc8ecaa 335 pc.printf("resolution of sin: %d\n", singen.resolution_ofsin);
aktk 2:5cb68cc8ecaa 336
aktk 2:5cb68cc8ecaa 337 float dsin[singen.resolution_ofsin];
aktk 2:5cb68cc8ecaa 338 singen.getValueofSamplePoints(dsin);
aktk 2:5cb68cc8ecaa 339 for ( int i = 0; i < singen.resolution_ofsin; i++ )
aktk 2:5cb68cc8ecaa 340 pc.printf("sin[%02d]: %2.2f\n", i, dsin[i]);
aktk 2:5cb68cc8ecaa 341
aktk 2:5cb68cc8ecaa 342 return NULL;
aktk 2:5cb68cc8ecaa 343 }
aktk 2:5cb68cc8ecaa 344