Exemple #1
0
int
console_tx_queue_ni (hBSP430halSERIAL uart, uint8_t c)
{
  sConsoleTxBuffer * bufp = &tx_buffer_;

  while (1) {
    unsigned char head = bufp->head;
    unsigned char next_head = (head + 1) % (sizeof(bufp->buffer)/sizeof(*bufp->buffer));
    if (next_head == bufp->tail) {
      if (0 == bufp->wake_available) {
        bufp->wake_available = 1;
      }
      BSP430_CORE_LPM_ENTER_NI(LPM0_bits | GIE);
      BSP430_CORE_DISABLE_INTERRUPT();
      continue;
    }
    bufp->buffer[head] = c;
    bufp->head = next_head;
    if (head == bufp->tail) {
      vBSP430serialWakeupTransmit_ni(uart);
    }
    break;
  }
  return c;
}
Exemple #2
0
int
iBSP430consoleWaitForTxSpace_ni (int want_available)
{
  int rv = 0;
#if BSP430_CONSOLE_TX_BUFFER_SIZE - 0
  if (((int)sizeof(tx_buffer_.buffer) - 1) < want_available) {
    return -1;
  }
  while (1) {
    int available;
    unsigned char head = tx_buffer_.head;
    unsigned char tail = tx_buffer_.tail;

    if (0 > want_available) {
      if (head == tail) {
        break;
      }
    } else {
      available = TX_BUFFER_AVAILABLE_(&tx_buffer_, head, tail);
      if (available >= want_available) {
        break;
      }
    }
    if (0 == tx_buffer_.wake_available) {
      tx_buffer_.wake_available = want_available;
    }
    rv = 1;
    BSP430_CORE_LPM_ENTER_NI(LPM0_bits | GIE);
    BSP430_CORE_DISABLE_INTERRUPT();
  }
#endif /* BSP430_CONSOLE_TX_BUFFER_SIZE */
  return rv;
}
Exemple #3
0
long
lBSP430uptimeSleepUntil_ni (unsigned long setting_utt,
                            unsigned int lpm_bits)
{
  int rc;

  /* Exit immediately unless the alarm callback is registered. */
  if (! (DELAY_ALARM_REGISTERED & delayAlarm_.flags)) {
    return 0;
  }
  delayAlarm_.flags &= ~DELAY_ALARM_FIRED;
  rc = iBSP430timerAlarmSet_ni(H_delayAlarm, setting_utt);
  if (0 != rc) {
    return 0;
  }
  /* Sleep until the alarm goes off, or something else wakes us up.
   * Immediately disable the interrupts as that probably was not done
   * during wakeup. */
  BSP430_CORE_LPM_ENTER_NI(lpm_bits);
  BSP430_CORE_DISABLE_INTERRUPT();

  /* Cancel the alarm if it hasn't fired yet. */
  if (! (delayAlarm_.flags & DELAY_ALARM_FIRED)) {
    (void)iBSP430timerAlarmCancel_ni(H_delayAlarm);
  }
  return setting_utt - ulBSP430uptime_ni();
}
Exemple #4
0
void main ()
{
  WDTCTL = WDTPW | WDTHOLD;

#if BSP430_LED - 0
  vBSP430ledInitialize_ni();
  {
    int i;

    vBSP430ledSet(0, 1);
    for (i = 0; i < 20; ++i) {
      vBSP430ledSet(0, -1);
      vBSP430ledSet(1, -1);
      __delay_cycles(BSP430_CLOCK_PUC_MCLK_HZ / 10);
    }
    /* The subsequent vBSP430lpmConfigurePortsForLPM_ni() call should
     * turn off the LED that's still lit. */
  }
#endif

  vBSP430lpmConfigurePortsForLPM_ni();

  __delay_cycles(BSP430_CLOCK_PUC_MCLK_HZ);
  while (1) {
#if (0 <= APP_LPM) && (APP_LPM <= 4)
    BSP430_CORE_LPM_ENTER_NI(lpm_bits[APP_LPM]);
    /* For this application it doesn't matter that GIE is now set */
#endif
  }
}
Exemple #5
0
void main ()
{
  hBSP430halSERIAL console = NULL;
  hBSP430halSERIAL uart = NULL;
  unsigned long prep_utt = 0;
  unsigned long emit_utt = 0;
  unsigned long done_utt = 0;

  vBSP430platformInitialize_ni();
  iBSP430consoleInitialize();

  console = hBSP430console();
  cprintf("\ntxcb " __DATE__ " " __TIME__ "\n");

  cprintf("\nConsole %p is on %s: %s\n", console,
          xBSP430serialName(BSP430_CONSOLE_SERIAL_PERIPH_HANDLE),
          xBSP430platformPeripheralHelp(BSP430_CONSOLE_SERIAL_PERIPH_HANDLE, 0));

  uart = hBSP430serialLookup(UART_PERIPH_HANDLE);
  if (NULL == uart) {
    cprintf("Failed to resolve secondary\n");
    return;
  }
  cprintf("\nSecondary %p is on %s: %s\n", uart,
          xBSP430serialName(UART_PERIPH_HANDLE),
          xBSP430platformPeripheralHelp(UART_PERIPH_HANDLE, 0));

  tx_buffer_.head = tx_buffer_.tail = 0;
  BSP430_HAL_ISR_CALLBACK_LINK_NI(sBSP430halISRVoidChainNode, uart->tx_cbchain_ni, tx_buffer_.cb_node, next_ni);
  uart = hBSP430serialOpenUART(uart, 0, 0, 9600);
  if (NULL == uart) {
    cprintf("Secondary open failed\n");
  }

  /* Need to enable interrupts so timer overflow events are properly
   * acknowledged */
  BSP430_CORE_ENABLE_INTERRUPT();
  while (1) {
    unsigned long next_prep_utt;
    char * obp;
    char * ob_end;

    next_prep_utt = ulBSP430uptime();
    obp = tx_buffer_.buffer;
    ob_end = obp + sizeof(tx_buffer_.buffer);
    obp += snprintf(obp, ob_end - obp, "prep %lu emit %lu\r\n", emit_utt - prep_utt, done_utt - emit_utt);
    ob_end = obp;
    BSP430_CORE_DISABLE_INTERRUPT();
    emit_utt = ulBSP430uptime_ni();
    prep_utt = next_prep_utt;
    tx_buffer_.tail = 0;
    tx_buffer_.head = obp - tx_buffer_.buffer;
    vBSP430serialWakeupTransmit_ni(uart);
    BSP430_CORE_LPM_ENTER_NI(LPM0_bits);
    /* Expect tail == head otherwise should not have awoken */
    done_utt = ulBSP430uptime();
  }
}
Exemple #6
0
void main ()
{
  hBSP430halPORT b0hal = hBSP430portLookup(BSP430_PLATFORM_BUTTON0_PORT_PERIPH_HANDLE);
  volatile sBSP430hplPORTIE * b0hpl;
  int b0pin = iBSP430portBitPosition(BSP430_PLATFORM_BUTTON0_PORT_BIT);

  vBSP430platformInitialize_ni();
  (void)iBSP430consoleInitialize();

  cprintf("\nbutton " __DATE__ " " __TIME__ "\n");

  cprintf("There's supposed to be a button at %s.%u\n",
          xBSP430portName(BSP430_PLATFORM_BUTTON0_PORT_PERIPH_HANDLE),
          b0pin);
  if (! b0hal) {
    cprintf("Whoops, guess it's not really there\n");
    return;
  }
  b0hpl = BSP430_PORT_HAL_GET_HPL_PORTIE(b0hal);
  button_state.button_cb.next_ni = b0hal->pin_cbchain_ni[b0pin];
  b0hal->pin_cbchain_ni[b0pin] = &button_state.button_cb;
  b0hpl->sel &= ~BSP430_PLATFORM_BUTTON0_PORT_BIT;
  b0hpl->dir &= ~BSP430_PLATFORM_BUTTON0_PORT_BIT;
#if (BSP430_PORT_SUPPORTS_REN - 0)
  BSP430_PORT_HAL_SET_REN(b0hal, BSP430_PLATFORM_BUTTON0_PORT_BIT, BSP430_PORT_REN_PULL_UP);
#endif /* BSP430_PORT_SUPPORTS_REN */
  if (b0hpl->in & BSP430_PLATFORM_BUTTON0_PORT_BIT) {
    button_state.in_mask = BSP430_PLATFORM_BUTTON0_PORT_BIT;
    b0hpl->ies |= BSP430_PLATFORM_BUTTON0_PORT_BIT;
  } else {
    button_state.in_mask = 0;
    b0hpl->ies &= ~BSP430_PLATFORM_BUTTON0_PORT_BIT;
  }
  b0hpl->ifg &= ~BSP430_PLATFORM_BUTTON0_PORT_BIT;
  b0hpl->ie |= BSP430_PLATFORM_BUTTON0_PORT_BIT;
  cprintf("Button is configured.  Try pressing it.  No debouncing is done.\n");
#if ! (configBSP430_CORE_LPM_EXIT_CLEAR_GIE - 0)
  cprintf("WARNING: Interrupts remain enabled after wakeup\n");
#endif /* configBSP430_CORE_LPM_EXIT_CLEAR_GIE */

  vBSP430ledSet(0, 1);

  while (1) {
    static const char * state_str[] = { "released", "pressed" };

    cprintf("Count %u, in mask 0x%02x: %s\n", button_state.count, button_state.in_mask, state_str[!button_state.in_mask]);

    /* Note that we've never turned interrupts on, but
     * BSP430_CORE_LPM_ENTER_NI() does so internally so the ISR can be
     * executed.  Whether they are cleared before returning to this
     * loop depends on #configBSP430_CORE_LPM_EXIT_CLEAR_GIE. */
    BSP430_CORE_LPM_ENTER_NI(LPM0_bits);
#if ! (configBSP430_CORE_LPM_EXIT_CLEAR_GIE - 0)
    /* Infrastructure didn't clear this, so we should */
    BSP430_CORE_DISABLE_INTERRUPT();
#endif /* configBSP430_CORE_LPM_EXIT_CLEAR_GIE */
  }
}
Exemple #7
0
void main ()
{
  hBSP430timerMuxSharedAlarm map;
  tBSP430periphHandle uptime_periph;
  int arc[sizeof(mux_alarms)/sizeof(*mux_alarms)];
  unsigned long last_wake_utt;
  unsigned long last_sleep_utt;
  int rc = 0;

  vBSP430platformInitialize_ni();
  last_wake_utt = ulBSP430uptime_ni();
  (void)iBSP430consoleInitialize();
  BSP430_CORE_ENABLE_INTERRUPT();

  cprintf("\n\nevent demo " __DATE__ " " __TIME__ "\n");
  mux_tag = ucBSP430eventTagAllocate("MuxAlarm");
  stats_tag = ucBSP430eventTagAllocate("Statistics");
  mux_flag = uiBSP430eventFlagAllocate();

  uptime_periph = xBSP430periphFromHPL(hBSP430uptimeTimer()->hpl);

  map = hBSP430timerMuxAlarmStartup(&mux_alarm_base, uptime_periph, UPTIME_MUXALARM_CCIDX);
  cprintf("Mux tag %u, stats tag %u, flag %x, with alarm base %p on %s.%u\n",
          mux_tag, stats_tag, mux_flag, map,
          xBSP430timerName(uptime_periph), UPTIME_MUXALARM_CCIDX);
  if (! map) {
    cprintf("ERR initializing mux shared alarm\n");
    goto err_out;
  }

  /* Processing done entirely in mux callback.  No wakeup. */
  mux_alarms[0].alarm.callback_ni = mux_alarm_callback;
  mux_alarms[0].interval_utt = BSP430_UPTIME_MS_TO_UTT(150);

  /* Processing done by an event flag */
  mux_alarms[1].alarm.callback_ni = mux_alarm_callback;
  mux_alarms[1].interval_utt = BSP430_UPTIME_MS_TO_UTT(500);
  mux_alarms[1].flag = mux_flag;

  /* Processing done by a callback with a timestamped event */
  mux_alarms[2].alarm.callback_ni = mux_alarm_callback;
  mux_alarms[2].interval_utt = BSP430_UPTIME_MS_TO_UTT(700);
  mux_alarms[2].process_fn = process_timestamp;
  mux_alarms[2].tag = mux_tag;

  /* Processing done by a callback with a timestamped event */
  mux_alarms[3].alarm.callback_ni = mux_alarm_callback;
  mux_alarms[3].interval_utt = BSP430_UPTIME_MS_TO_UTT(10000);
  mux_alarms[3].process_fn = process_statistics;
  mux_alarms[3].tag = stats_tag;

  /* Enable the multiplexed alarms */
  BSP430_CORE_DISABLE_INTERRUPT();
  do {
    int i = 0;
    for (i = 0; (0 == rc) && (i < sizeof(mux_alarms)/sizeof(*mux_alarms)); ++i) {
      mux_alarms[i].alarm.setting_tck = ulBSP430uptime_ni();
      arc[i] = iBSP430timerMuxAlarmAdd_ni(map, &mux_alarms[i].alarm);
    }
  } while (0);
  BSP430_CORE_ENABLE_INTERRUPT();

  /* Display the results.  All values should be non-negative for success. */
  {
    int i;
    cprintf("Alarm installation got:");
    rc = 0;
    for (i = 0; i < sizeof(arc)/sizeof(*arc); ++i) {
      cprintf(" %d", arc[i]);
      if (0 > arc[i]) {
        rc = arc[i];
      }
    }
    cputchar('\n');
  }
  if (0 > rc) {
    goto err_out;
  }

  last_sleep_utt = ulBSP430uptime();
  while (1) {
    last_wake_utt = ulBSP430uptime();
    unsigned int events = process_events(uiBSP430eventFlagsGet());
    if (events) {
      cprintf("ERR: Unprocessed event flags %04x\n", events);
    }

    BSP430_CORE_DISABLE_INTERRUPT();
    /* Put back any unprocessed events */
    vBSP430eventFlagsSet_ni(events);
    if (iBSP430eventFlagsEmpty_ni()) {
      /* Nothing pending: go to sleep, then jump back to the loop head
       * when we get woken. */
      statistics_v.sleep_utt += last_wake_utt - last_sleep_utt;
      last_sleep_utt = ulBSP430uptime_ni();
      statistics_v.awake_utt += last_sleep_utt - last_wake_utt;
      statistics_v.sleep_ct += 1;
      BSP430_CORE_LPM_ENTER_NI(LPM4_bits | GIE);
      continue;
    }
    BSP430_CORE_ENABLE_INTERRUPT();
  }
err_out:
  (void)iBSP430consoleFlush();
  return;
}
Exemple #8
0
void main ()
{
  const char * command;
  int flags;

  vBSP430platformInitialize_ni();
  (void)iBSP430consoleInitialize();
  vBSP430cliSetDiagnosticFunction(iBSP430cliConsoleDiagnostic);
  cprintf("\ncli example " __DATE__ " " __TIME__ "\n");
#if configBSP430_CLI_COMMAND_COMPLETION - 0
  cprintf("Command completion is available.\n");
#endif /* configBSP430_CLI_COMMAND_COMPLETION */
  vBSP430ledSet(0, 1);
  cprintf("\nLED lit when not awaiting input\n");

  /* NOTE: The control flow in this is a bit tricky, as we're trying
   * to leave interrupts enabled during the main body of the loop,
   * while they must be disabled when processing input to recognize a
   * command.  The flags variable preserves state across multiple loop
   * iterations until all relevant activities have completed. */
  commandSet = LAST_COMMAND;
  command = NULL;
  flags = eBSP430cliConsole_REPAINT;

  BSP430_CORE_ENABLE_INTERRUPT();
  while (1) {
    if (flags & eBSP430cliConsole_ANY_ESCAPE) {
      int c;
      while (0 <= ((c = cgetchar()))) {
        cprintf("escape char 0x%02x (%u) '%c'\n", c, c, isprint(c) ? c : '.');
        /* Technically CSI is a single character 0x9b representing
         * ESC+[.  In the two-character mode accepted here, we use the
         * value for the second character. */
#define KEY_CSI '['
        if ((KEY_CSI == c) && (flags & eBSP430cliConsole_PROCESS_ESCAPE)) {
          flags &= ~eBSP430cliConsole_PROCESS_ESCAPE;
          flags |= eBSP430cliConsole_IN_ESCAPE;
        } else if ((64 <= c) && (c <= 126)) {
          flags &= ~eBSP430cliConsole_ANY_ESCAPE;
          cprintf("Leaving escape mode\n");
          break;
        }
      }
    }
    if (flags & eBSP430cliConsole_DO_COMPLETION) {
      flags &= ~eBSP430cliConsole_DO_COMPLETION;
      flags |= iBSP430cliConsoleBufferCompletion(commandSet, &command);
    }
    if (flags & eBSP430cliConsole_READY) {
      int rv;

      rv = iBSP430cliExecuteCommand(commandSet, 0, command);
      if (0 != rv) {
        cprintf("Command execution returned %d\n", rv);
      }
      /* Ensure prompt is rewritten, but not the command we just
       * ran */
      flags |= eBSP430cliConsole_REPAINT;
      command = NULL;
    }
    if (flags & eBSP430cliConsole_REPAINT) {
      /* Draw the prompt along with whatever's left in the command
       * buffer.  Note use of leading carriage return in case an edit
       * left material on the current line. */
      cprintf("\r> %s", command ? command : "");
      flags &= ~eBSP430cliConsole_REPAINT;
    }
    if (flags & eBSP430cliConsole_REPAINT_BEL) {
      cputchar('\a');
      flags &= ~eBSP430cliConsole_REPAINT_BEL;
    }
    BSP430_CORE_DISABLE_INTERRUPT();
    do {
      if (flags & eBSP430cliConsole_READY) {
        /* Clear the command we just completed */
        vBSP430cliConsoleBufferClear_ni();
        flags &= ~eBSP430cliConsole_READY;
      }
      do {
        /* Unless we're processing application-specific escape
         * characters let iBSP430cliConsoleBufferProcessInput_ni()
         * process any input characters that have already been
         * received. */
        if (! (flags & eBSP430cliConsole_ANY_ESCAPE)) {
          flags |= iBSP430cliConsoleBufferProcessInput_ni();
        }
        if (0 == flags) {
          /* Sleep until something wakes us, such as console input.
           * Then turn off interrupts and loop back to read that
           * input. */
          vBSP430ledSet(0, 0);
          BSP430_CORE_LPM_ENTER_NI(LPM0_bits);
          BSP430_CORE_DISABLE_INTERRUPT();
          vBSP430ledSet(0, 1);
        }
        /* Repeat if still nothing to do */
      } while (! flags);

      /* Got something to do; get the command contents in place so
       * we can update the screen. */
      command = xBSP430cliConsoleBuffer_ni();
    } while (0);
    BSP430_CORE_ENABLE_INTERRUPT();
  }
}
Exemple #9
0
void main ()
{
    volatile sBSP430hplTIMER * const hpl = xBSP430hplLookupTIMER(BSP430_PERIPH_TA0);
    unsigned long ta0_Hz;
    unsigned int delta_ta0;
    const struct sLPMconfig * lcp = lpm_configs;
    const struct sLPMconfig * const elcp = lpm_configs + sizeof(lpm_configs)/sizeof(*lpm_configs);

    vBSP430platformInitialize_ni();
    (void)iBSP430consoleInitialize();

    TA0CTL = TASSEL_1 | MC_2 | TACLR;
    ta0_Hz = ulBSP430timerFrequency_Hz_ni(BSP430_PERIPH_TA0);

#if 0
    /* This sequence eliminates the wakeup delay on the MSP430F5438A.
     * The ramifications of doing this are to be found in the Power
     * Management Module and Supply Voltage Supervisor chapter of the
     * 5xx/6xx Family User's Guide, in the section "SVS and SVM
     * Performance Modes and Wakeup Times".
     *
     * Also check MCU errata related to the PMM.  THere are several that
     * appear relevant when changing the module from its power-up
     * state. */
    PMMCTL0_H = PMMPW_H;
#if 1
    /* This variant works */
    SVSMLCTL &= ~(SVSLE | SVMLE);
#else
    /* This appears to have no effect, though it should work. */
    SVSMLCTL |= SVSLFP;
#endif
    PMMCTL0_H = !PMMPW_H;
#endif

    BSP430_CORE_ENABLE_INTERRUPT();

    cputs("\n\nTimer LPM wake delay test\n");
    delta_ta0 = ta0_Hz / 4;
    cprintf("TA0 is at %lu Hz; sleep time %u ticks\n", ta0_Hz, delta_ta0);
    cprintf("Standard mode SR is %04x\n", __read_status_register());
    cprintf("SR bits: SCG0 %04x ; SCG1 %04x\n", SCG0, SCG1);
    cprintf("LPM exit from ISRs clears: %04x\n", BSP430_CORE_LPM_EXIT_MASK);

    cputs("LPMx   CCR0  CAP0  Delta0   CCR1  CAP1  Delta1   SR");
    while (lcp < elcp) {
        unsigned int tar;

        cprintf("%s: ", lcp->tag);
        BSP430_CORE_DISABLE_INTERRUPT();
        ta0r = 0;
        hpl->cctl[0] = CCIE;
        tar = uiBSP430timerAsyncCounterRead_ni(hpl);
        hpl->ccr[0] = tar + delta_ta0;
        BSP430_CORE_LPM_ENTER_NI(lcp->lpm_bits);
        cprintf("%5u %5u %5u    ", hpl->ccr[0], ta0r, ta0r-hpl->ccr[0]);

        BSP430_CORE_DISABLE_INTERRUPT();
        ta0r = 0;
        hpl->cctl[1] = CCIE;
        tar = uiBSP430timerAsyncCounterRead_ni(hpl);
        hpl->ccr[1] = tar + delta_ta0;
        BSP430_CORE_LPM_ENTER_NI(lcp->lpm_bits);
        cprintf("%5u %5u %5u    ", hpl->ccr[1], ta0r, ta0r-hpl->ccr[1]);

        cprintf("%04x\n", __read_status_register());
        ++lcp;
    }
    cprintf("Done\n");

}