int main(void)
{
  init(1);

  printf("\n\nFirmware info - git: " GIT_VERSION ", built: " __DATE__ " " __TIME__ "\n");
  printf("--- SWIFT BINARY PROTOCOL RX STRESS TEST ---\n");

  static sbp_msg_callbacks_node_t callback_node;
  sbp_register_cbk(0x22, &callback, &callback_node);

  for (u8 i=0; i<30; i++) {
    guard_below[i] = 0;
    guard_above[i] = 0;
  }

  while(1) {
    /* Check the guards for buffer over/underrun. */
    for (u8 i=0; i<30; i++) {
      if (guard_below[i] != 0)
        screaming_death("Detected buffer underrun in guard area\n");
      if (guard_above[i] != 0)
        screaming_death("Detected buffer overrun in guard area\n");
    }

    sbp_process_messages();

    //for (u32 i = 0; i < 1000; i++)
    //  __asm__("nop");
  }
while (1);

	return 0;
}
int main(void)
{
  for (u32 i = 0; i < 600000; i++)
    __asm__("nop");

	led_setup();

  rcc_clock_setup_hse_3v3(&hse_16_368MHz_in_65_472MHz_out_3v3);

  debug_setup();
  timer_setup();

  // Debug pins (CC1111 TX/RX)
  RCC_AHB1ENR |= RCC_AHB1ENR_IOPCEN;
	gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO10|GPIO11);
  gpio_clear(GPIOC, GPIO10|GPIO11);


  printf("\n\nFirmware info - git: " GIT_VERSION ", built: " __DATE__ " " __TIME__ "\n");
  printf("--- DEBUG TEST ---\n");

  u32 len;

  for (u8 i=0; i<30; i++) {
    guard_below[i] = 0;
    guard_above[i] = 0;
  }

  for (u32 i=0; i<256; i++)
    buff_out[i] = (u8)i;

  while(1) {
    /* Random transmit length. */
    len = (u32)rand() % 256;
    while(debug_send_msg(0x22, len, buff_out));

    /* Check the guards for buffer over/underrun. */
    for (u8 i=0; i<30; i++) {
      if (guard_below[i] != 0)
        screaming_death();
      if (guard_above[i] != 0)
        screaming_death();
    }

    /* Introduce some timing jitter. */
    u32 jitter_delay = ((u32)rand() % 20000);
    for (u32 i = 0; i < jitter_delay; i++)
    /*for (u32 i = 0; i < 1000; i++)*/
      __asm__("nop");
  }
while (1);

	return 0;
}
int main(void)
{
  for (u32 i = 0; i < 600000; i++)
    __asm__("nop");

	led_setup();

  rcc_clock_setup_hse_3v3(&hse_16_368MHz_in_65_472MHz_out_3v3);

  usart_setup_common();
  usart_tx_dma_setup();

  /*printf("\n\nFirmware info - git: " GIT_VERSION ", built: " __DATE__ " " __TIME__ "\n");*/
  /*printf("--- USART DMA TEST ---\n");*/

  #define MAX_TX ((u32)(USART_TX_BUFFER_LEN*1.2))

  u8 guard_below[30];
  u8 buff_out[MAX_TX];
  u8 guard_above[30];
  u32 len;

  for (u8 i=0; i<30; i++) {
    guard_below[i] = 0;
    guard_above[i] = 0;
  }

  for (u32 i=0; i<MAX_TX; i++)
    buff_out[i] = (u8)i;

  while(1) {
    /* Random transmit length. */
    len = (u32)rand() % MAX_TX;
    while (len)
      len -= usart_write_dma(buff_out, len);

    /* Check the guards for buffer over/underrun. */
    for (u8 i=0; i<30; i++) {
      if (guard_below[i] != 0)
        screaming_death();
      if (guard_above[i] != 0)
        screaming_death();
    }

    /* Introduce some timing jitter. */
    for (u32 i = 0; i < ((u32)rand() % 10000); i++)
      __asm__("nop");
  }

  while (1);

	return 0;
}
Beispiel #4
0
/* Called by fault handlers in error_asm.s */
void fault_handler_screaming_death(const char *msg_str, u32 lr)
{
  char msg[128];
  extern int fallback_sprintf(char *str, const char *fmt, ...);
  fallback_sprintf(msg, "%s lr=%08X", msg_str, (unsigned int)lr);
  screaming_death(msg);
}
Beispiel #5
0
/** _exit(2) syscall handler.  Called by (at least) abort() and exit().
 * Calls screaming_death() to repeatedly print an ERROR until WDT reset.
 */
void _exit(int status)
{
  (void)status;
  /* TODO: Perhaps print a backtrace; let's see if this ever actually
     occurs before implementing that. */
  screaming_death("abort() or exit() was called");
}
Beispiel #6
0
/** USART TX DMA interrupt service routine.
 * Should be called from the relevant DMA stream ISR.
 * \param s The USART DMA state structure.
 */
void usart_tx_dma_isr(usart_tx_dma_state* s)
{
    if (dma_get_interrupt_flag(s->dma, s->stream,
                               DMA_TEIF | DMA_DMEIF))
        /* TODO: Handle error interrupts! */
        screaming_death("DMA TX error interrupt");

    if (dma_get_interrupt_flag(s->dma, s->stream, DMA_TCIF)) {
        /* Interrupt is Transmit Complete. */

        /* Clear the DMA transmit complete and half complete interrupt flags. */
        dma_clear_interrupt_flags(s->dma, s->stream, DMA_HTIF | DMA_TCIF);

        /* Now that the transfer has finished we can increment the read index. */
        s->rd = (s->rd + s->xfer_len) % USART_TX_BUFFER_LEN;

        if (s->wr != s->rd)
            /* Buffer not empty. */
            dma_schedule(s);
    }

    if (dma_get_interrupt_flag(s->dma, s->stream, DMA_FEIF))
        /* Clear FIFO error flag */
        dma_clear_interrupt_flags(s->dma, s->stream, DMA_HTIF | DMA_FEIF);
}
Beispiel #7
0
/** Helper function that schedules a new transfer with the DMA controller if
 * needed.
 * \param s The USART DMA state structure.
 * */
static void dma_schedule(usart_tx_dma_state* s)
{
    /* TODO: We shouldn't have to check for this now that we are called
     * atomically but leaving it in for now just in case. */
    if (DMA_SCR(s->dma, s->stream) & DMA_SxCR_EN)
        screaming_death("DMA TX scheduled while DMA channel running");

    DMA_SM0AR(s->dma, s->stream) = &(s->buff[s->rd]);

    /* Save the transfer length so we can increment the read index after the
     * transfer is finished. */
    if (s->rd < s->wr)
        /* DMA up until write pointer. */
        s->xfer_len = s->wr - s->rd;
    else
        /* DMA up until the end of the buffer. */
        s->xfer_len = USART_TX_BUFFER_LEN - s->rd;

    /* Set the number of datas in the DMA controller. */
    DMA_SNDTR(s->dma, s->stream) = s->xfer_len;

    /* Clear USART_TC flag */
    USART_SR(s->usart) &= ~USART_SR_TC;

    /* Enable DMA stream to start transfer. */
    DMA_SCR(s->dma, s->stream) |= DMA_SxCR_EN;
}
int main(void)
{
  for (u32 i = 0; i < 600000; i++)
    __asm__("nop");

	led_setup();

  rcc_clock_setup_hse_3v3(&hse_16_368MHz_in_65_472MHz_out_3v3);

  debug_setup();
  timer_setup();

  // Debug pins (CC1111 TX/RX)
  RCC_AHB1ENR |= RCC_AHB1ENR_IOPCEN;
	gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO10|GPIO11);
  gpio_clear(GPIOC, GPIO10|GPIO11);


  printf("\n\nFirmware info - git: " GIT_VERSION ", built: " __DATE__ " " __TIME__ "\n");
  printf("--- DEBUG RX STRESS TEST ---\n");

  static msg_callbacks_node_t callback_node;
  debug_register_callback(0x22, &callback, &callback_node);

  for (u8 i=0; i<30; i++) {
    guard_below[i] = 0;
    guard_above[i] = 0;
  }

  while(1) {
    /* Check the guards for buffer over/underrun. */
    for (u8 i=0; i<30; i++) {
      if (guard_below[i] != 0)
        screaming_death();
      if (guard_above[i] != 0)
        screaming_death();
    }

    debug_process_messages();

    //for (u32 i = 0; i < 1000; i++)
    //  __asm__("nop");
  }
while (1);

	return 0;
}
Beispiel #9
0
static void usart_rx_dma_isr(struct usart_rx_dma_state* s, u32 flags)
{
  if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0)
    screaming_death("USART RX DMA error interrupt");

  chSysLockFromISR();
  /* Increment our write wrap counter. */
  s->wr_wraps++;
  chBSemSignalI(&s->ready);
  chSysUnlockFromISR();
}
void callback(u16 sender_id, u8 len, u8 msg[], void* context)
{
  (void)sender_id; (void)len; (void) context;

  // Check this shit out
  ok_packets++;
  ok_bytes += 25;
  for (u8 i=0; i<22; i++)
    if (msg[i] != i)
      screaming_death("Test packet not received correctly");
}
Beispiel #11
0
/** DMA 2 Stream 3 Interrupt Service Routine. (SPI1_TX) */
void dma2_stream3_isr(void)
{
  CH_IRQ_PROLOGUE();
  chSysLockFromIsr();

  if (dma_get_interrupt_flag(DMA2, 3, DMA_TEIF | DMA_DMEIF))
    screaming_death("DMA SPI1_TX error interrupt");

  chSysUnlockFromIsr();
  CH_IRQ_EPILOGUE();
}
Beispiel #12
0
static void usart_tx_dma_isr(struct usart_tx_dma_state* s, u32 flags)
{
  if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0)
    screaming_death("USART TX DMA error interrupt");

  osalSysLockFromISR();
  /* Now that the transfer has finished we can increment the read index. */
  s->rd = (s->rd + s->xfer_len) % USART_TX_BUFFER_LEN;

  if (s->wr != s->rd)
    /* Buffer not empty. */
    dma_schedule(s);
  else
    s->busy = false;
  osalSysUnlockFromISR();
}
Beispiel #13
0
/** DMA 2 Stream 0 Interrupt Service Routine. (SPI1_RX) */
void dma2_stream0_isr(void)
{
  CH_IRQ_PROLOGUE();
  chSysLockFromIsr();

  if (dma_get_interrupt_flag(DMA2, 0, DMA_TEIF | DMA_DMEIF))
    screaming_death("DMA SPI1_RX error interrupt");

  /* Disable both receive and transmit streams */
  dma_clear_interrupt_flags(DMA2, 3, DMA_TCIF | DMA_HTIF);
  dma_clear_interrupt_flags(DMA2, 0, DMA_TCIF | DMA_HTIF);

  /* Signal the semaphore to wake up blocking spi1_xfer_dma */
  chBSemSignalI(&spi_dma_sem);

  chSysUnlockFromIsr();
  CH_IRQ_EPILOGUE();
}
Beispiel #14
0
/** Returns a lower bound on the number of bytes in the DMA receive buffer.
 * Also checks for buffer overrun conditions.
 * \param s The USART DMA state structure.
 */
u32 usart_n_read_dma(usart_rx_dma_state* s)
{
  s32 n_read = s->rd_wraps * USART_RX_BUFFER_LEN + s->rd;
  s32 n_written = (s->wr_wraps + 1) * USART_RX_BUFFER_LEN - \
                  DMA_SNDTR(s->dma, s->stream);
  s32 n_available = n_written - n_read;

  if (n_available < 0)
    /* This strange and rare case occurs when NDTR has rolled over but the flag
     * hasn't been raised yet and thus n_wraps hasn't been incremented in the
     * ISR. Simply return 0 this time and the next time this function is called
     * (or at some point) the interrupt will have been triggered and the number
     * of bytes available in the buffer will be a sane amount. */
    n_available = 0;
  else if (n_available > USART_RX_BUFFER_LEN)
    /* If greater than a whole buffer then we have had an overflow. */
    screaming_death("DMA RX buffer overrun");

  return n_available;
}
Beispiel #15
0
/** USART RX DMA interrupt service routine.
 * Should be called from the relevant DMA stream ISR.
 * \param s The USART DMA state structure.
 */
void usart_rx_dma_isr(usart_rx_dma_state* s)
{
  if (dma_get_interrupt_flag(s->dma, s->stream,
                             DMA_TEIF | DMA_DMEIF | DMA_FEIF))
    /* TODO: Handle error interrupts! */
    screaming_death("USART RX DMA error interrupt");

  if (dma_get_interrupt_flag(s->dma, s->stream, DMA_HTIF | DMA_TCIF)) {
    /* Interrupt is Transmit Complete. We are in circular buffer mode so this
     * probably means we just wrapped the buffer. */

    /* Clear the DMA transmit complete and half complete interrupt flags. */
    dma_clear_interrupt_flags(s->dma, s->stream, DMA_HTIF | DMA_TCIF);

    /* Increment our write wrap counter. */
    s->wr_wraps++;
  }

  /* Note: When DMA is re-enabled after bootloader it appears ISR can get
   * called without any of the bits of DMA_LISR being high */
}