void sml_run_toplevels(void (**topfuncs)(void)) { struct frame_stack_range dummy_range = {.top = NULL, .bottom = NULL}; struct sml_control *control = tlv_get_or_init(current_control); if (control != NULL) { for (; *topfuncs; topfuncs++) (*topfuncs)(); return; } /* Set up a control block with a dummy stack range. * This avoids frequent allocation and deallocation of thread local * heap due to sml_start and sml_end called at the beginning and end * of each top-level fragment. */ control = control_start(&dummy_range); control_leave(control); for (; *topfuncs; topfuncs++) (*topfuncs)(); /* NOTE: if an uncaught exception occurs, the following code will * not be executed. */ control_enter(control); assert(control->frame_stack == &dummy_range); control_destroy(control); }
int execute_command(enum COMMAND cmd) { switch (cmd) { case C_AHEAD: return control_goahead(4000); case C_GETCORNER: return control_getcorner(); case C_LEFT: return control_turnleft(); case C_RIGHT: return control_turnright(); case C_AROUND: return control_turnaround(); case C_BREAK: return control_break(); case C_START: return control_start(); case C_LETSWIN: return control_letswin(); case C_STOP: default: return control_stop(); } }
SML_PRIMITIVE void sml_start(void **arg) { struct frame_stack_range *range = (void*)arg; struct sml_control *control = tlv_get_or_init(current_control); range->bottom = CALLER_FRAME_END_ADDRESS(); range->top = NULL; if (control == NULL) { control_start(range); } else { control_enter(control); range->next = control->frame_stack; control->frame_stack = range; } }
/* Main function */ int main(void) { sc_time_t my_timer; int32_t value; dint(); #if USE_WATCHDOG init_watchdog(); #else WDTCTL = WDTCTL_INIT; //Init watchdog timer #endif init_ports(); init_clock(); sc_init_timer(); scandal_init(); config_read(); {volatile int i; for(i=0; i<100; i++) ; } /* Below here, we assume we have a config */ /* Send out the error that we've reset -- it's not fatal obviously, but we want to know when it happens, and it really is an error, since something that's solar powered should be fairly constantly powered */ scandal_do_user_err(UNSWMPPTNG_ERROR_WATCHDOG_RESET); /* Make sure our variables are set up properly */ tracker_status = 0; /* Initialise FPGA (or, our case, CPLD) stuff */ fpga_init(); /* Starts the ADC and control loop interrupt */ control_init(); /* Initialise the PV tracking mechanism */ pv_track_init(); eint(); my_timer = sc_get_timer(); while (1) { sc_time_t timeval; timeval = sc_get_timer(); handle_scandal(); /* pv_track sends data when it feels like it */ pv_track_send_data(); /* Periodically send out the values recorded by the ADC */ if(timeval >= my_timer + TELEMETRY_UPDATE_PERIOD){ my_timer = timeval; toggle_yellow_led(); #if USE_WATCHDOG kick_watchdog(); #endif mpptng_do_errors(); pv_track_send_telemetry(); /* We send the Input current and voltage from within the pvtrack module */ /* scandal_send_scaled_channel(TELEM_LOW, UNSWMPPTNG_IN_VOLTAGE, sample_adc(MEAS_VIN1)); scandal_send_scaled_channel(TELEM_LOW, UNSWMPPTNG_IN_CURRENT, sample_adc(MEAS_IIN1));*/ scandal_send_scaled_channel(TELEM_LOW, UNSWMPPTNG_OUT_VOLTAGE, sample_adc(MEAS_VOUT)); scandal_send_scaled_channel(TELEM_LOW, UNSWMPPTNG_HEATSINK_TEMP, sample_adc(MEAS_THEATSINK)); scandal_send_scaled_channel(TELEM_LOW, UNSWMPPTNG_15V, sample_adc(MEAS_15V)); scandal_send_channel(TELEM_LOW, UNSWMPPTNG_STATUS, tracker_status); /* Pre-scale for the temperature */ { int32_t degC = sample_adc(MEAS_TAMBIENT); degC = (((degC - 1615)*704*1000)/4095); scandal_send_scaled_channel(TELEM_LOW, UNSWMPPTNG_AMBIENT_TEMP, degC); } #if DEBUG >= 1 scandal_send_channel(TELEM_LOW, 134, output); scandal_send_channel(TELEM_LOW, 136, fpga_nFS()); #endif } /* If we're not tracking, check to see that our start-up criteria are satisfied, and then initialise the control loops and restart tracking */ if((tracker_status & STATUS_TRACKING) == 0){ /* Check the input voltage */ value = sample_adc(MEAS_VIN1); scandal_get_scaled_value(UNSWMPPTNG_IN_VOLTAGE, &value); if(value < config.min_vin) continue; /* Check the output voltage */ value = sample_adc(MEAS_VOUT); scandal_get_scaled_value(UNSWMPPTNG_OUT_VOLTAGE, &value); if(value > config.max_vout) continue; tracker_status |= STATUS_TRACKING; /* Initialise the tracking algorithm */ // pv_track_init(); /* Reset the FPGA */ fs_reset(); /* Initialise the control loop */ control_start(); /* Enable the FPGA */ fpga_enable(FPGA_ON); } } }