예제 #1
0
/** Configure 16 bit timer to trigger an ISR every second
 *
 * Configure "measurement in progress toggle LED-signal"
 */
void timer1_init(const uint16_t timer1_value)
{
    orig_timer1_count = timer1_value;
    timer1_count = timer1_value;

    /** Safeguard: We cannot handle 0 or 1 count measurements. */
    if (orig_timer1_count <= 1) {
        send_text_P(PSTR("Unsupported timer value <= 1"));
        wdt_soft_reset();
    }

    /* Compare match value into output compare reg. A               */
    OCR1A = TIMER1_COMPARE_MATCH_VAL;

    /* Configure and start timer */
    TCCR1A =
        BITF(TIMER1_COMA_MODE, COM1A, 0) |
        BITF(TIMER1_COMA_MODE, COM1A, 1) |
        BITF(TIMER1_WGM_MODE,  WGM1, 0) |
        BITF(TIMER1_WGM_MODE,  WGM1, 1);
    TCCR1B =
        BITF(TIMER1_PRESCALER,  CS1, 0) |
        BITF(TIMER1_PRESCALER,  CS1, 1) |
        BITF(TIMER1_PRESCALER,  CS1, 2) |
        BITF(TIMER1_WGM_MODE,  WGM1, 2) |
        BITF(TIMER1_WGM_MODE,  WGM1, 3);

    /* output compare match A interrupt enable                      */
    TIMSK1 |= _BV(OCIE1A);
}
예제 #2
0
/** Firmware FSM event handler for finished measurement */
inline static
firmware_state_t firmware_handle_measurement_finished(const firmware_state_t pstate)
{
  switch (pstate) {
  case STP_MEASURING:
    /* end measurement */
    cli();
    on_measurement_finished();
    send_table(PACKET_VALUE_TABLE_DONE);
    return STP_DONE;
    break;
  default:
    send_text_P(PSTR("invalid state transition"));
    wdt_soft_reset();
    break;
  }
}
예제 #3
0
/** Firmware FSM event handler for receiving a command packet from the host
 *
 * \param pstate current FSM state
 * \param cmd the command we are to handle
 * \return new state
 *
 * Implicit parameters via global variables:
 *   personality_param_sram[0..sizeof(personality_param_sram)-2] param+token data
 *   personality_param_sram[sizeof(personality_param_sram)-1] size of param+token data
 */
inline static
firmware_state_t firmware_handle_command(const firmware_state_t pstate,
                                         const uint8_t cmd)
{
  /* temp vars */
  const frame_cmd_t c = (frame_cmd_t)cmd;

  uprintf("EAT PACKET: %c", cmd);

  switch (pstate) {
  case STP_READY:
    switch (c) {
    case FRAME_CMD_PERSONALITY_INFO:
      send_personality_info();
      /* fall through */
    case FRAME_CMD_ABORT:
    case FRAME_CMD_INTERMEDIATE:
    case FRAME_CMD_STATE:
      send_state_P(PSTR_READY);
      return STP_READY;
      break;
    case FRAME_CMD_PARAMS_TO_EEPROM:
      /* The param length has already been checked by the frame parser */
      send_state_P(PSTR("PARAMS_TO_EEPROM"));
      eeprom_update_block(&pparam_sram, &pparam_eeprom,
                          sizeof(pparam_eeprom));
      send_state_P(PSTR_READY);
      return STP_READY;
      break;
    case FRAME_CMD_PARAMS_FROM_EEPROM:
      params_copy_from_eeprom_to_sram();
      send_eeprom_params_in_sram();
      send_state_P(PSTR_READY);
      return STP_READY;
      break;
    case FRAME_CMD_MEASURE:
      /* The param length has already been checked by the frame parser */
      general_personality_start_measurement_sram();
      send_state_P(PSTR_MEASURING);
      return STP_MEASURING;
      break;
    case FRAME_CMD_RESET:
      send_state_P(PSTR_RESET);
      wdt_soft_reset();
      break;
    }
    break;
  case STP_MEASURING:
    switch (c) {
    case FRAME_CMD_INTERMEDIATE:
      /** The value table will be updated asynchronously from ISRs
       * like ISR(ADC_vect) or ISR(TIMER1_foo), i.e. independent from
       * this main loop.  This will cause glitches in the intermediate
       * values as the values in the table often consist of more than
       * a single 8bit machine word.  However, we have decided that
       * for *intermediate* results, those glitches are acceptable.
       *
       * Keeping interrupts enabled has the additional advantage that
       * the measurement continues during send_table(), so we need not
       * concern ourselves with pausing the measurement timer, or with
       * making sure we properly reset the hardware which triggered
       * our ISR within the appropriate time range or anything
       * similar.
       *
       * If you decide to bracket the send_table() call with a
       * cli()/sei() pair, be aware that you need to solve the issue
       * of resetting the hardware properly. For example, with the
       * adc-int-mca personality, you would need to reset the peak
       * hold capacitor on resume if an event has been detected by the
       * analog circuit while we had interrupts disabled and thus
       * ISR(ADC_vect) could not reset the peak hold capacitor.
       */
      send_table(PACKET_VALUE_TABLE_INTERMEDIATE);
      send_state_P(PSTR_MEASURING);
      return STP_MEASURING;
      break;
    case FRAME_CMD_PERSONALITY_INFO:
      send_personality_info();
      /* fall through */
    case FRAME_CMD_PARAMS_TO_EEPROM:
    case FRAME_CMD_PARAMS_FROM_EEPROM:
    case FRAME_CMD_MEASURE:
    case FRAME_CMD_RESET:
    case FRAME_CMD_STATE:
      send_state_P(PSTR_MEASURING);
      return STP_MEASURING;
      break;
    case FRAME_CMD_ABORT:
      send_state_P(PSTR_DONE);
      cli();
      on_measurement_finished();
      send_table(PACKET_VALUE_TABLE_ABORTED);
      send_state_P(PSTR_DONE);
      return STP_DONE;
      break;
    }
    break;
  case STP_DONE:
    switch (c) {
    case FRAME_CMD_PERSONALITY_INFO:
      send_personality_info();
      /* fall through */
    case FRAME_CMD_STATE:
      send_state_P(PSTR_DONE);
      return STP_DONE;
      break;
    case FRAME_CMD_RESET:
      send_state_P(PSTR_RESET);
      wdt_soft_reset();
      break;
    default:
      send_table(PACKET_VALUE_TABLE_RESEND);
      send_state_P(PSTR_DONE);
      return STP_DONE;
      break;
    }
    break;
  }
  send_text_P(PSTR("STP_ERROR"));
  wdt_soft_reset();
}