Example #1
0
//--------------------------------------------------------------------
// 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;
        }
Example #2
0
inline void led3_op(int cmd, uint8_t type, uint32_t delay, uint32_t interval)
{
  led_op(led3_fd, cmd, type, delay, interval);
}