//-------------------------------------------------------------------- // EXTERNAL FUNCTIONS //-------------------------------------------------------------------- int8_t execute(dvm_state_t* dvm_st, DvmState *eventState) { DVMBasiclib_state_t *s = (&dvm_st->basiclib_st); DvmContext *context = &(eventState->context); while ((context->state == DVM_STATE_RUN) && (context->num_executed < DVM_CPU_SLICE)) { DvmOpcode instr = getOpcode(dvm_st, context->which, context->pc); DEBUG("-----------------------------------------------\n"); DEBUG("[BASIC_LIB] execute: (%d) PC: %d. INSTR: %d\n",context->which, context->pc, instr); if(instr & LIB_ID_BIT) { //Extension Library opcode encountered return SOS_OK; } context->num_executed++; switch(instr) { case OP_START: { __asm __volatile("__sleep_measure_start:"); context->pc += 1; break; } case OP_STOP: { context->pc += 1; break; } case OP_HALT: { DEBUG("<<<<<<<<<<<=====================>>>>>>>>>>>\n"); DEBUG("[BASIC_LIB] execute: (%d): HALT executed.\n", (int)context->which); haltContext(dvm_st, context); context->state = DVM_STATE_HALT; context->pc = 0; break; } case OP_LED: { DvmStackVariable* arg = popOperand( eventState); led_op(arg->value.var); context->pc += 1; break; } case OP_GETVAR + 0: case OP_GETVAR + 1: case OP_GETVAR + 2: case OP_GETVAR + 3: case OP_GETVAR + 4: case OP_GETVAR + 5: case OP_GETVAR + 6: case OP_GETVAR + 7: { uint8_t arg = instr - OP_GETVAR; DEBUG("[BASIC_LIB] execute: OPGETVAR (%d):: Pushing value %d.\n", (int)arg,(int)s->shared_vars[arg].value.var); pushOperand( eventState, &s->shared_vars[arg]); context->pc += 1; break; } case OP_SETVAR + 0: case OP_SETVAR + 1: case OP_SETVAR + 2: case OP_SETVAR + 3: case OP_SETVAR + 4: case OP_SETVAR + 5: case OP_SETVAR + 6: case OP_SETVAR + 7: { uint8_t arg = instr - OP_SETVAR; DvmStackVariable* var = popOperand( eventState); DEBUG("[BASIC_LIB] execute: OPSETVAR (%d):: Setting value to %d.\n",(int)arg,(int)var->value.var); s->shared_vars[arg] = *var; context->pc += 1; break; } case OP_GETVARF + 0: case OP_GETVARF + 1: case OP_GETVARF + 2: case OP_GETVARF + 3: case OP_GETVARF + 4: case OP_GETVARF + 5: case OP_GETVARF + 6: case OP_GETVARF + 7: { // Use for type casting an integer shared var to float uint8_t arg = instr - OP_GETVARF; int32_t res = 0; uint16_t res_part = 0; DEBUG("[BASIC_LIB] execute: OPGETVARF (%d):: Pushing value %d.\n", (int)arg,(int)s->shared_vars[arg].value.var); res = (int32_t)(s->shared_vars[arg].value.var * FLOAT_PRECISION); res_part = res & 0xFFFF; pushValue( eventState, res_part, DVM_TYPE_FLOAT_DEC); res_part = res >> 16; pushValue( eventState, res_part, DVM_TYPE_FLOAT); context->pc += 1; break; } case OP_SETVARF + 0: case OP_SETVARF + 1: case OP_SETVARF + 2: case OP_SETVARF + 3: case OP_SETVARF + 4: case OP_SETVARF + 5: case OP_SETVARF + 6: { // Type-casting an integer to float and saving it in shared var uint8_t arg = instr - OP_SETVARF; DvmStackVariable* var = popOperand( eventState); int32_t res = 0; uint16_t res_part; DEBUG("[BASIC_LIB] execute: OPSETVARF (%d):: Setting value to %d.\n",(int)arg,(int)var->value.var); res = (int32_t)(var->value.var * FLOAT_PRECISION); res_part = res & 0xFFFF; s->shared_vars[arg+1].type = DVM_TYPE_FLOAT_DEC; s->shared_vars[arg+1].value.var = res_part; res_part = res >> 16; s->shared_vars[arg].type = DVM_TYPE_FLOAT; s->shared_vars[arg].value.var = res_part; context->pc += 1; break; } case OP_SETTIMER + 0: case OP_SETTIMER + 1: case OP_SETTIMER + 2: case OP_SETTIMER + 3: case OP_SETTIMER + 4: case OP_SETTIMER + 5: case OP_SETTIMER + 6: case OP_SETTIMER + 7: { uint32_t msec; uint8_t timerID = instr - OP_SETTIMER; DvmStackVariable* arg = popOperand( eventState); DEBUG("[BASIC_LIB] execute: Setting Timer %d period to %d.\n", timerID, arg->value.var); //msec = 102 * arg->value.var + (4 * arg->value.var) / 10; // Set the timer timeout argument in seconds msec = arg->value.var * 4;// * 1000; DEBUG("[BASIC_LIB] execute: <<<<< WARNING - Timer %d not being stopped >>>>\n", timerID); // sys_timer_stop(timerID); if (msec > 0) { // Ram - Where is the init ?? sys_timer_start(timerID, msec, TIMER_REPEAT); DEBUG("[BASIC_LIB] execute: Timer ID: %d started. Period: %d msec.\n", timerID, msec); } context->pc += 1; break; } case OP_RAND: { DvmStackVariable* arg = popOperand( eventState); uint16_t rnd; rnd = sys_rand() % arg->value.var; pushValue( eventState, rnd, DVM_TYPE_INTEGER); context->pc += 1; break; } /* case OP_JMP: case OP_JNZ: case OP_JZ: case OP_JG: case OP_JGE: case OP_JL: case OP_JLE: case OP_JE: case OP_JNE: case OP_ADD: case OP_SUB: case OP_DIV: case OP_MUL: case OP_ABS: case OP_MOD: case OP_INCR: case OP_DECR: { mathlib_executeDL(s->mathlib_execute, eventState, instr); break; } */ // Math Lib case OP_ADD: case OP_SUB: case OP_DIV: case OP_MUL: { DvmStackVariable* arg1 = popOperand( eventState); DvmStackVariable* arg2 = popOperand( eventState); DvmStackVariable* arg3 = NULL, *arg4 = NULL; int32_t fl_arg1, fl_arg2; int32_t res = 0; uint16_t res_part; int16_t int_res = 0; if (arg1->type == DVM_TYPE_FLOAT) { fl_arg1 = convert_to_float(arg1, arg2); arg3 = popOperand( eventState); if (arg3->type == DVM_TYPE_FLOAT) { // FLOAT <op> FLOAT arg4 = popOperand( eventState); fl_arg2 = convert_to_float(arg3, arg4); if(instr == OP_ADD) { res = (int32_t)(fl_arg1 + fl_arg2); DEBUG("[BASIC_LIB] execute: FLOAT ADD FLOAT %d\n", res); } else if(instr == OP_SUB) { res = (int32_t)(fl_arg1 - fl_arg2); DEBUG("[BASIC_LIB] execute: FLOAT SUB FLOAT %d\n", res); } else if(instr == OP_DIV) { res = (int32_t)((fl_arg1 * FLOAT_PRECISION) / fl_arg2); DEBUG("[BASIC_LIB] execute: FLOAT DIV FLOAT: %d\n", res); } else if(instr == OP_MUL) { res = (int32_t)((fl_arg1 * fl_arg2) / FLOAT_PRECISION); DEBUG("[BASIC_LIB] execute: FLOAT MULT FLOAT %d\n", res); } } else { // FLOAT <OP> INTEGER if(instr == OP_ADD) { res = (int32_t)(fl_arg1 + (arg3->value.var * FLOAT_PRECISION)); DEBUG("[BASIC_LIB] execute: FLOAT ADD INT: %d\n", res); } else if(instr == OP_SUB) { res = (int32_t)(fl_arg1 - (arg3->value.var * FLOAT_PRECISION)); DEBUG("[BASIC_LIB] execute: FLOAT SUB INT: %d\n", res); } else if(instr == OP_DIV) { res = (int32_t)(fl_arg1 / arg3->value.var); DEBUG("[BASIC_LIB] execute: FLOAT DIV INT: %d\n", res); sys_led(LED_RED_TOGGLE); #ifdef OUTLIER_SCRIPT_DBG int32_t* post_avg; post_avg = (int32_t*)sys_malloc(sizeof(int32_t)); *post_avg = res; sys_post_uart(OUTLIER_DETECTION_PID, MSG_AVERAGE, sizeof(int32_t), post_avg, SOS_MSG_RELEASE, UART_ADDRESS); #endif } else if(instr == OP_MUL) { res = (int32_t)(fl_arg1 * arg3->value.var); DEBUG("[BASIC_LIB] execute: FLOAT MULT INT %d\n", res); } } res_part = res & 0xFFFF; pushValue( eventState, res_part, DVM_TYPE_FLOAT_DEC); res_part = res >> 16; pushValue( eventState, res_part, DVM_TYPE_FLOAT); context->pc += 1; break; } else if (arg2->type == DVM_TYPE_FLOAT) { arg3 = popOperand( eventState); fl_arg2 = convert_to_float(arg2, arg3); if(instr == OP_ADD) { res = (int32_t)((arg1->value.var * FLOAT_PRECISION) + fl_arg2) ; DEBUG("[BASIC_LIB] execute: INT ADD FLOAT: %d\n", res); } else if(instr == OP_SUB) { res = (int32_t)((arg1->value.var * FLOAT_PRECISION) - fl_arg2); DEBUG("[BASIC_LIB] execute: INT SUB FLOAT: %d\n", res); } else if(instr == OP_DIV) { res = (int32_t)((arg1->value.var * FLOAT_PRECISION) / fl_arg2); DEBUG("[BASIC_LIB] execute: INT DIV FLOAT: %d\n", res); } else if(instr == OP_MUL) { res = (int32_t)((arg1->value.var * FLOAT_PRECISION) * fl_arg2); DEBUG("[BASIC_LIB] execute: INT MULT FLOAT: %d\n", res); } res_part = res & 0xFFFF; pushValue( eventState, res_part, DVM_TYPE_FLOAT_DEC); res_part = res >> 16; pushValue( eventState, res_part, DVM_TYPE_FLOAT); context->pc += 1; break; } if(instr == OP_ADD) { int_res = arg1->value.var + arg2->value.var; DEBUG("[BASIC_LIB] execute: INT ADD INT: %d\n", int_res); } else if(instr == OP_SUB) { int_res = arg1->value.var - arg2->value.var; DEBUG("[BASIC_LIB] execute: INT SUB INT: %d\n", int_res); } else if(instr == OP_DIV) { int_res = (int16_t)(arg1->value.var / arg2->value.var); DEBUG("[BASIC_LIB] execute: INT DIV INT: %d\n", int_res); } else if(instr == OP_MUL) { int_res = (int16_t)(arg1->value.var * arg2->value.var); DEBUG("[BASIC_LIB] execute: INT MULT INT: %d\n", int_res); } pushValue( eventState, int_res, DVM_TYPE_INTEGER); context->pc += 1; break; }
inline void led3_op(int cmd, uint8_t type, uint32_t delay, uint32_t interval) { led_op(led3_fd, cmd, type, delay, interval); }