diff options
31 files changed, 4070 insertions, 235 deletions
| diff --git a/os/common/ports/MSP430X/chcore.c b/os/common/ports/MSP430X/chcore.c index 7a8d7f2..b9001b0 100644 --- a/os/common/ports/MSP430X/chcore.c +++ b/os/common/ports/MSP430X/chcore.c @@ -32,6 +32,8 @@  /* Module exported variables.                                                */
  /*===========================================================================*/
 +bool __msp430x_in_isr;
 +
  /*===========================================================================*/
  /* Module local types.                                                       */
  /*===========================================================================*/
 @@ -98,6 +100,11 @@ void _port_thread_start(void) {    asm volatile ("mov R5, R12");
    asm volatile ("call R4");
  #endif
 +#if defined(_CHIBIOS_RT_CONF_)
 +  chThdExit(MSG_OK);
 +#endif
 +#if defined(_CHIBIOS_NIL_CONF_)
    chSysHalt(0);
 +#endif
  }
  /** @} */
 diff --git a/os/common/ports/MSP430X/chcore.h b/os/common/ports/MSP430X/chcore.h index 3683c1d..9e1efa8 100644 --- a/os/common/ports/MSP430X/chcore.h +++ b/os/common/ports/MSP430X/chcore.h @@ -28,6 +28,8 @@  #include <msp430.h>
  #include <in430.h>
 +extern bool __msp430x_in_isr;
 +
  /*===========================================================================*/
  /* Module constants.                                                         */
  /*===========================================================================*/
 @@ -225,7 +227,7 @@ struct port_context {   * @details This macro must be inserted at the start of all IRQ handlers
   *          enabled to invoke system APIs.
   */
 -#define PORT_IRQ_PROLOGUE() 
 +#define PORT_IRQ_PROLOGUE() __msp430x_in_isr = true;
  /**
   * @brief   IRQ epilogue code.
 @@ -233,6 +235,7 @@ struct port_context {   *          enabled to invoke system APIs.
   */
  #define PORT_IRQ_EPILOGUE() {                                               \
 +  __msp430x_in_isr = false;                                                 \
    _dbg_check_lock();                                                        \
    if (chSchIsPreemptionRequired())                                          \
      chSchDoReschedule();                                                    \
 @@ -298,7 +301,7 @@ extern "C" {   * @brief   Port-related initialization code.
   */
  static inline void port_init(void) {
 -
 +  __msp430x_in_isr = false;
  }
  /**
 @@ -333,9 +336,7 @@ static inline bool port_irq_enabled(syssts_t sts) {   * @retval true         running in ISR mode.
   */
  static inline bool port_is_isr_context(void) {
 -  /* Efficiency would be enhanced by not doing this, 
 -   * because of implementation details */
 -  return __get_SR_register() & GIE;
 +  return __msp430x_in_isr;
  }
  /**
 diff --git a/os/hal/boards/EXP430FR5969/board.c b/os/hal/boards/EXP430FR5969/board.c index ac48ba0..0643cce 100644 --- a/os/hal/boards/EXP430FR5969/board.c +++ b/os/hal/boards/EXP430FR5969/board.c @@ -25,11 +25,11 @@  const PALConfig pal_default_config =
  {
    {VAL_IOPORT1_OUT, VAL_IOPORT1_DIR, VAL_IOPORT1_REN, VAL_IOPORT1_SEL0, 
 -    VAL_IOPORT1_SEL1, VAL_IOPORT1_IES, VAL_IOPORT1_IE},
 +    VAL_IOPORT1_SEL1},
    {VAL_IOPORT2_OUT, VAL_IOPORT2_DIR, VAL_IOPORT2_REN, VAL_IOPORT2_SEL0, 
 -    VAL_IOPORT2_SEL1, VAL_IOPORT2_IES, VAL_IOPORT2_IE},
 +    VAL_IOPORT2_SEL1},
    {VAL_IOPORT0_OUT, VAL_IOPORT0_DIR, VAL_IOPORT0_REN, VAL_IOPORT0_SEL0, 
 -    VAL_IOPORT0_SEL1, VAL_IOPORT0_IES, VAL_IOPORT0_IE}
 +    VAL_IOPORT0_SEL1}
  }; /* Set UART TX pin correctly */
  #endif /* HAL_USE_PAL */
 diff --git a/os/hal/boards/EXP430FR5969/board.h b/os/hal/boards/EXP430FR5969/board.h index 97103d3..3abe1cc 100644 --- a/os/hal/boards/EXP430FR5969/board.h +++ b/os/hal/boards/EXP430FR5969/board.h @@ -65,8 +65,6 @@  #define VAL_IOPORT1_REN   0xFCFE
  #define VAL_IOPORT1_SEL0  0x0000
  #define VAL_IOPORT1_SEL1  0x0300
 -#define VAL_IOPORT1_IES   0x0000
 -#define VAL_IOPORT1_IE    0x0000
  /*
   * Port B setup:
 @@ -93,8 +91,6 @@  #define VAL_IOPORT2_REN   0xBDFF
  #define VAL_IOPORT2_SEL0  0x0000
  #define VAL_IOPORT2_SEL1  0x0000
 -#define VAL_IOPORT2_IES   0x0000
 -#define VAL_IOPORT2_IE    0x0000
  /*
   * Port J setup:
 @@ -113,8 +109,6 @@  #define VAL_IOPORT0_REN   0x00CF
  #define VAL_IOPORT0_SEL0  0x0030
  #define VAL_IOPORT0_SEL1  0x0000
 -#define VAL_IOPORT0_IES   0x0000
 -#define VAL_IOPORT0_IE    0x0000
  #if !defined(_FROM_ASM_)
  #ifdef __cplusplus
 diff --git a/os/hal/boards/EXP430FR6989/board.c b/os/hal/boards/EXP430FR6989/board.c index a6836cf..475a2ea 100644 --- a/os/hal/boards/EXP430FR6989/board.c +++ b/os/hal/boards/EXP430FR6989/board.c @@ -25,17 +25,17 @@  const PALConfig pal_default_config =
  {
    {VAL_IOPORT1_OUT, VAL_IOPORT1_DIR, VAL_IOPORT1_REN, VAL_IOPORT1_SEL0, 
 -    VAL_IOPORT1_SEL1, VAL_IOPORT1_IES, VAL_IOPORT1_IE},
 +    VAL_IOPORT1_SEL1},
    {VAL_IOPORT2_OUT, VAL_IOPORT2_DIR, VAL_IOPORT2_REN, VAL_IOPORT2_SEL0, 
 -    VAL_IOPORT2_SEL1, VAL_IOPORT2_IES, VAL_IOPORT2_IE},
 +    VAL_IOPORT2_SEL1},
    {VAL_IOPORT3_OUT, VAL_IOPORT3_DIR, VAL_IOPORT3_REN, VAL_IOPORT3_SEL0, 
 -    VAL_IOPORT3_SEL1, VAL_IOPORT3_IES, VAL_IOPORT3_IE},
 +    VAL_IOPORT3_SEL1},
    {VAL_IOPORT4_OUT, VAL_IOPORT4_DIR, VAL_IOPORT4_REN, VAL_IOPORT4_SEL0, 
 -    VAL_IOPORT4_SEL1, VAL_IOPORT4_IES, VAL_IOPORT4_IE},
 +    VAL_IOPORT4_SEL1},
    {VAL_IOPORT5_OUT, VAL_IOPORT5_DIR, VAL_IOPORT5_REN, VAL_IOPORT5_SEL0, 
 -    VAL_IOPORT5_SEL1, VAL_IOPORT5_IES, VAL_IOPORT5_IE},
 +    VAL_IOPORT5_SEL1},
    {VAL_IOPORT0_OUT, VAL_IOPORT0_DIR, VAL_IOPORT0_REN, VAL_IOPORT0_SEL0, 
 -    VAL_IOPORT0_SEL1, VAL_IOPORT0_IES, VAL_IOPORT0_IE}
 +    VAL_IOPORT0_SEL1}
  }; /* Set UART TX pin correctly */
  #endif /* HAL_USE_PAL */
 diff --git a/os/hal/boards/EXP430FR6989/board.h b/os/hal/boards/EXP430FR6989/board.h index 83b8fbb..d5afe29 100644 --- a/os/hal/boards/EXP430FR6989/board.h +++ b/os/hal/boards/EXP430FR6989/board.h @@ -69,8 +69,6 @@  #define VAL_IOPORT1_REN   0xFFFE
  #define VAL_IOPORT1_SEL0  0x0000
  #define VAL_IOPORT1_SEL1  0x0000
 -#define VAL_IOPORT1_IES   0x0006
 -#define VAL_IOPORT1_IE    0x0006
  /*
   * Port B setup:
 @@ -97,8 +95,6 @@  #define VAL_IOPORT2_REN   0xFFCF
  #define VAL_IOPORT2_SEL0  0x0030
  #define VAL_IOPORT2_SEL1  0x0000
 -#define VAL_IOPORT2_IES   0x0000
 -#define VAL_IOPORT2_IE    0x0000
  /*
   * Port C setup:
 @@ -125,8 +121,6 @@  #define VAL_IOPORT3_REN   0xFFFF
  #define VAL_IOPORT3_SEL0  0x0000
  #define VAL_IOPORT3_SEL1  0x0000
 -#define VAL_IOPORT3_IES   0x0000
 -#define VAL_IOPORT3_IE    0x0000
  /*
   * Port D setup:
 @@ -153,11 +147,9 @@  #define VAL_IOPORT4_REN   0xFFFF
  #define VAL_IOPORT4_SEL0  0x0000
  #define VAL_IOPORT4_SEL1  0x0000
 -#define VAL_IOPORT4_IES   0x0000
 -#define VAL_IOPORT4_IE    0x0000
  /*
 - * Port D setup:
 + * Port E setup:
   * 
   * P9.0 - BoosterPack BP27        (input pullup)
   * P9.1 - BoosterPack BP28        (input pullup)
 @@ -181,8 +173,6 @@  #define VAL_IOPORT5_REN   0xFF7F
  #define VAL_IOPORT5_SEL0  0x0000
  #define VAL_IOPORT5_SEL1  0x0000
 -#define VAL_IOPORT5_IES   0x0000
 -#define VAL_IOPORT5_IE    0x0000
  /*
   * Port J setup:
 @@ -201,8 +191,6 @@  #define VAL_IOPORT0_REN   0x00CF
  #define VAL_IOPORT0_SEL0  0x0030
  #define VAL_IOPORT0_SEL1  0x0000
 -#define VAL_IOPORT0_IES   0x0000
 -#define VAL_IOPORT0_IE    0x0000
  #if !defined(_FROM_ASM_)
  #ifdef __cplusplus
 diff --git a/os/hal/ports/MSP430X/hal_adc_lld.c b/os/hal/ports/MSP430X/hal_adc_lld.c new file mode 100644 index 0000000..42d3cbe --- /dev/null +++ b/os/hal/ports/MSP430X/hal_adc_lld.c @@ -0,0 +1,354 @@ +/*
 +    ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
 +
 +    Licensed under the Apache License, Version 2.0 (the "License");
 +    you may not use this file except in compliance with the License.
 +    You may obtain a copy of the License at
 +
 +        http://www.apache.org/licenses/LICENSE-2.0
 +
 +    Unless required by applicable law or agreed to in writing, software
 +    distributed under the License is distributed on an "AS IS" BASIS,
 +    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 +    See the License for the specific language governing permissions and
 +    limitations under the License.
 +*/
 +
 +/**
 + * @file    hal_adc_lld.c
 + * @brief   MSP430X ADC subsystem low level driver source.
 + *
 + * @addtogroup ADC
 + * @{
 + */
 +
 +#include "hal.h"
 +
 +#if (HAL_USE_ADC == TRUE) || defined(__DOXYGEN__)
 +
 +/*===========================================================================*/
 +/* Driver local definitions.                                                 */
 +/*===========================================================================*/
 +
 +/*===========================================================================*/
 +/* Driver exported variables.                                                */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   ADC1 driver identifier.
 + */
 +#if (MSP430X_ADC_USE_ADC1 == TRUE) || defined(__DOXYGEN__)
 +ADCDriver ADCD1;
 +#endif
 +
 +/*===========================================================================*/
 +/* Driver local variables and types.                                         */
 +/*===========================================================================*/
 +
 +/*===========================================================================*/
 +/* Driver local functions.                                                   */
 +/*===========================================================================*/
 +
 +static void restart_dma(ADCDriver * adcp) {
 +  /* TODO timeouts? */
 +  /* Restart DMA transfer */
 +  if (adcp->dma.registers == NULL) {
 +    /* Acquire a DMA stream because dmaTransfer can be called from ISRs */
 +    osalSysLockFromISR();
 +    dmaAcquireI(&(adcp->dma), adcp->dma.index);
 +    osalSysUnlockFromISR();
 +    dmaTransfer(&(adcp->dma), &(adcp->req));
 +  }
 +  else {
 +    dmaTransfer(&(adcp->dma), &(adcp->req));
 +  }
 +}
 +
 +static void dma_callback(void * args) {
 +  ADCDriver * adcp = (ADCDriver *)args;
 +
 +  if (adcp->grpp == NULL)
 +    return;
 +
 +  adcp->count++;
 +
 +  if (adcp->count == adcp->depth / 2) {
 +    /* half-full interrupt */
 +    _adc_isr_half_code(adcp);
 +  }
 +
 +  if (adcp->count == adcp->depth) {
 +    /* full interrupt */
 +
 +    /* adc_lld_stop_conversion is called automatically here if needed */
 +    _adc_isr_full_code(adcp);
 +    /* after isr_full, adcp->grpp is only non-NULL if it's a circular group */
 +    if (adcp->grpp) {
 +      /* Reset the buffer pointer */
 +      adcp->req.dest_addr = adcp->samples;
 +
 +      restart_dma(adcp);
 +
 +      /* Reset the count */
 +      adcp->count = 0;
 +
 +      /* Start next sequence */
 +      adcp->regs->ctl[0] |= ADC12SC;
 +    }
 +  }
 +  else {
 +    /* Advance the buffer pointer */
 +    adcp->req.dest_addr = adcp->samples + (adcp->req.size * adcp->count);
 +
 +    restart_dma(adcp);
 +
 +    /* Start next sequence */
 +    adcp->regs->ctl[0] |= ADC12SC;
 +  }
 +}
 +
 +static void populate_tlv(ADCDriver * adcp) {
 +  uint8_t * tlv_addr = (uint8_t *)TLV_START;
 +
 +  while (*tlv_addr != TLV_TAGEND && tlv_addr < (uint8_t *)TLV_END) {
 +    if (*tlv_addr == TLV_ADC12CAL) {
 +      adcp->adc_cal = (msp430x_adc_cal_t *)(tlv_addr + 2);
 +    }
 +    else if (*tlv_addr == TLV_REFCAL) {
 +      adcp->ref_cal = (msp430x_ref_cal_t *)(tlv_addr + 2);
 +    }
 +    tlv_addr += (tlv_addr[1] + 2);
 +  }
 +}
 +
 +/*===========================================================================*/
 +/* Driver interrupt handlers.                                                */
 +/*===========================================================================*/
 +
 +PORT_IRQ_HANDLER(ADC12_VECTOR) {
 +
 +  OSAL_IRQ_PROLOGUE();
 +
 +  switch (__even_in_range(ADC12IV, ADC12IV_ADC12TOVIFG)) {
 +
 +  case ADC12IV_ADC12OVIFG: {
 +    if (ADCD1.grpp == NULL)
 +      break;
 +    _adc_isr_error_code(&ADCD1, ADC_ERR_OVERFLOW);
 +    break;
 +  }
 +  case ADC12IV_ADC12TOVIFG: {
 +    if (ADCD1.grpp == NULL)
 +      break;
 +    _adc_isr_error_code(&ADCD1, ADC_ERR_AWD);
 +    break;
 +  }
 +  default:
 +    osalDbgAssert(false, "unhandled ADC exception");
 +    _adc_isr_error_code(&ADCD1, ADC_ERR_UNKNOWN);
 +  }
 +
 +  OSAL_IRQ_EPILOGUE();
 +}
 +
 +/*===========================================================================*/
 +/* Driver exported functions.                                                */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Low level ADC driver initialization.
 + *
 + * @notapi
 + */
 +void adc_lld_init(void) {
 +
 +#if MSP430X_ADC_USE_ADC1 == TRUE
 +  /* Driver initialization.*/
 +  adcObjectInit(&ADCD1);
 +  ADCD1.regs = (msp430x_adc_reg_t *)(&ADC12CTL0);
 +  populate_tlv(&ADCD1);
 +#endif
 +}
 +
 +/**
 + * @brief   Configures and activates the ADC peripheral.
 + *
 + * @param[in] adcp      pointer to the @p ADCDriver object
 + *
 + * @notapi
 + */
 +void adc_lld_start(ADCDriver * adcp) {
 +
 +  if (adcp->state == ADC_STOP) {
 +    /* Enables the peripheral.*/
 +    adcp->regs->ctl[0] = ADC12ON | ADC12MSC;
 +    adcp->regs->ctl[1] =
 +        MSP430X_ADC1_PDIV | MSP430X_ADC1_DIV | MSP430X_ADC1_SSEL | ADC12SHP;
 +    adcp->regs->ctl[3] = ADC12ICH3MAP | ADC12ICH2MAP | ADC12ICH1MAP |
 +                         ADC12ICH0MAP | ADC12TCMAP | ADC12BATMAP;
 +    adcp->regs->ier[2] = ADC12TOVIE | ADC12OVIE;
 +    adcp->req.trigger  = DMA_TRIGGER_MNEM(ADC12IFG);
 +#if MSP430X_ADC_COMPACT_SAMPLES == TRUE
 +    adcp->req.data_mode = MSP430X_DMA_SRCWORD | MSP430X_DMA_DSTBYTE;
 +#else
 +    adcp->req.data_mode = MSP430X_DMA_SRCWORD | MSP430X_DMA_DSTWORD;
 +#endif
 +    adcp->req.addr_mode         = MSP430X_DMA_SRCINCR | MSP430X_DMA_DSTINCR;
 +    adcp->req.transfer_mode     = MSP430X_DMA_SINGLE;
 +    adcp->req.callback.callback = dma_callback;
 +    adcp->req.callback.args     = adcp;
 +
 +#if MSP430X_ADC_EXCLUSIVE_DMA == TRUE
 +    bool b;
 +    if (adcp->config->dma_index < MSP430X_DMA_CHANNELS) {
 +      b = dmaAcquireI(&adcp->dma, adcp->config->dma_index);
 +      osalDbgAssert(!b, "stream already allocated");
 +    }
 +    else {
 +#endif
 +      adcp->dma.registers = NULL;
 +#if MSP430X_ADC_EXCLUSIVE_DMA == TRUE
 +    }
 +#endif
 +  }
 +  /* Configures the peripheral.*/
 +}
 +
 +/**
 + * @brief   Deactivates the ADC peripheral.
 + *
 + * @param[in] adcp      pointer to the @p ADCDriver object
 + *
 + * @notapi
 + */
 +void adc_lld_stop(ADCDriver * adcp) {
 +
 +  if (adcp->state == ADC_READY) {
 +/* Resets the peripheral.*/
 +
 +/* Disables the peripheral.*/
 +#if MSP430X_ADC_EXCLUSIVE_DMA == TRUE
 +    if (adcp->config->dma_index < MSP430X_DMA_CHANNELS) {
 +      dmaRelease(&(adcp->dma));
 +    }
 +#endif
 +    adcp->regs->ctl[0] = 0;
 +  }
 +}
 +
 +/**
 + * @brief   Starts an ADC conversion.
 + *
 + * @param[in] adcp      pointer to the @p ADCDriver object
 + *
 + * @notapi
 + */
 +void adc_lld_start_conversion(ADCDriver * adcp) {
 +
 +  /* always use sequential transfer mode - this is fine */
 +  adcp->regs->ctl[1] |= ADC12CONSEQ0;
 +
 +  /* set resolution */
 +  adcp->regs->ctl[2] |= adcp->grpp->res;
 +  /* start from MEM0 */
 +  adcp->regs->ctl[3] &= ~(ADC12CSTARTADD_31);
 +
 +  /* Configure voltage reference */
 +  while (REFCTL0 & REFGENBUSY)
 +    ;
 +  REFCTL0 = adcp->grpp->vref_src;
 +
 +  for (int i = 0; i < adcp->grpp->num_channels; i++) {
 +    osalDbgAssert(adcp->grpp->channels[i] < 32, "invalid channel number");
 +    adcp->regs->mctl[i] = adcp->grpp->ref | adcp->grpp->channels[i];
 +  }
 +
 +  adcp->regs->mctl[adcp->grpp->num_channels - 1] |= ADC12EOS;
 +
 +  adcp->req.source_addr = adcp->regs->mem;
 +  adcp->req.dest_addr   = adcp->samples;
 +  adcp->req.size        = adcp->grpp->num_channels;
 +  adcp->count           = 0;
 +
 +/* TODO timeouts? */
 +#if MSP430X_ADC_EXCLUSIVE_DMA == TRUE
 +  if (adcp->config->dma_index >= MSP430X_DMA_CHANNELS) {
 +    adcp->dma.index = dmaRequestS(&(adcp->req), TIME_INFINITE);
 +  }
 +  else {
 +    dmaTransfer(&(adcp->dma), &(adcp->req));
 +  }
 +#else
 +  adcp->dma.index       = dmaRequestS(&(adcp->req), TIME_INFINITE);
 +#endif
 +
 +  adcp->regs->ctl[0] |= adcp->grpp->rate | ADC12MSC | ADC12ENC | ADC12SC;
 +}
 +
 +/**
 + * @brief   Stops an ongoing conversion.
 + *
 + * @param[in] adcp      pointer to the @p ADCDriver object
 + *
 + * @notapi
 + */
 +void adc_lld_stop_conversion(ADCDriver * adcp) {
 +
 +  /* TODO stop DMA transfers here */
 +  adcp->regs->ctl[0] &= ~(ADC12ENC | ADC12SC);
 +
 +#if MSP430X_ADC_EXCLUSIVE_DMA == TRUE
 +  if (adcp->config->dma_index >= MSP430X_DMA_CHANNELS) {
 +#endif
 +    if (adcp->dma.registers != NULL) {
 +      dmaRelease(&(adcp->dma));
 +      adcp->dma.registers = NULL;
 +    }
 +#if MSP430X_ADC_EXCLUSIVE_DMA == TRUE
 +  }
 +#endif
 +}
 +
 +adcsample_t adcMSP430XAdjustResult(ADCConversionGroup * grpp,
 +                                   adcsample_t sample) {
 +  uint32_t tmp;
 +  uint16_t fact;
 +  if (grpp->ref == MSP430X_ADC_VSS_VREF_BUF ||
 +      grpp->ref == MSP430X_ADC_VEREF_P_VREF_BUF ||
 +      grpp->ref == MSP430X_ADC_VREF_BUF_VCC ||
 +      grpp->ref == MSP430X_ADC_VREF_BUF_VEREF_P ||
 +      grpp->ref == MSP430X_ADC_VEREF_N_VREF_BUF) {
 +    /* Retrieve proper reference correction factor from TLV */
 +    fact = (&(ADCD1.ref_cal->CAL_ADC_12VREF_FACTOR))[grpp->vref_src >> 4];
 +    /* Calculate corrected value */
 +    tmp    = (uint32_t)(sample << 1) * (uint32_t)fact;
 +    sample = tmp >> 16;
 +  }
 +
 +  /* Gain correction */
 +  fact   = ADCD1.adc_cal->CAL_ADC_GAIN_FACTOR;
 +  tmp    = (uint32_t)(sample << 1) * (uint32_t)fact;
 +  sample = tmp >> 16;
 +
 +  /* Offset correction */
 +  sample += ADCD1.adc_cal->CAL_ADC_OFFSET;
 +
 +  return sample;
 +}
 +
 +adcsample_t adcMSP430XAdjustTemp(ADCConversionGroup * grpp,
 +                                 adcsample_t sample) {
 +  uint16_t t30;
 +  uint16_t t85;
 +
 +  /* Retrieve proper T = 30 correction value from TLV */
 +  t30 = (&(ADCD1.adc_cal->CAL_ADC_12T30))[grpp->vref_src >> 3];
 +  /* Retrieve proper T = 85 correction value from TLV */
 +  t85 = (&(ADCD1.adc_cal->CAL_ADC_12T30))[(grpp->vref_src >> 3) + 1];
 +
 +  return ((((int32_t)sample - (int32_t)t30) * (85 - 30)) / (t85 - t30)) + 30;
 +}
 +
 +#endif /* HAL_USE_ADC == TRUE */
 +
 +/** @} */
 diff --git a/os/hal/ports/MSP430X/hal_adc_lld.h b/os/hal/ports/MSP430X/hal_adc_lld.h new file mode 100644 index 0000000..1cca36b --- /dev/null +++ b/os/hal/ports/MSP430X/hal_adc_lld.h @@ -0,0 +1,516 @@ +/*
 +    ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
 +
 +    Licensed under the Apache License, Version 2.0 (the "License");
 +    you may not use this file except in compliance with the License.
 +    You may obtain a copy of the License at
 +
 +        http://www.apache.org/licenses/LICENSE-2.0
 +
 +    Unless required by applicable law or agreed to in writing, software
 +    distributed under the License is distributed on an "AS IS" BASIS,
 +    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 +    See the License for the specific language governing permissions and
 +    limitations under the License.
 +*/
 +
 +/**
 + * @file    hal_adc_lld.h
 + * @brief   MSP430X ADC subsystem low level driver header.
 + *
 + * @addtogroup ADC
 + * @{
 + */
 +
 +#ifndef HAL_ADC_LLD_H
 +#define HAL_ADC_LLD_H
 +
 +#if (HAL_USE_ADC == TRUE) || defined(__DOXYGEN__)
 +
 +/*===========================================================================*/
 +/* Driver constants.                                                         */
 +/*===========================================================================*/
 +
 +/**
 + * @name    Sampling rates
 + * @{
 + */
 +typedef enum {
 +  MSP430X_ADC_SHT_4   = 0x0000,
 +  MSP430X_ADC_SHT_8   = 0x1100,
 +  MSP430X_ADC_SHT_16  = 0x2200,
 +  MSP430X_ADC_SHT_32  = 0x3300,
 +  MSP430X_ADC_SHT_64  = 0x4400,
 +  MSP430X_ADC_SHT_96  = 0x5500,
 +  MSP430X_ADC_SHT_128 = 0x6600,
 +  MSP430X_ADC_SHT_192 = 0x7700,
 +  MSP430X_ADC_SHT_256 = 0x8800,
 +  MSP430X_ADC_SHT_384 = 0x9900,
 +  MSP430X_ADC_SHT_512 = 0xAA00
 +} MSP430XADCSampleRates;
 +/** @} */
 +
 +/**
 + * @name    Resolution
 + * @{
 + */
 +typedef enum {
 +  MSP430X_ADC_RES_8BIT  = 0x0000,
 +  MSP430X_ADC_RES_10BIT = 0x0010,
 +  MSP430X_ADC_RES_12BIT = 0x0020
 +} MSP430XADCResolution;
 +/** @} */
 +
 +/**
 + * @name    References
 + * @{
 + */
 +typedef enum {
 +  MSP430X_ADC_VSS_VCC             = 0x0000,
 +  MSP430X_ADC_VSS_VREF_BUF        = 0x0100,
 +  MSP430X_ADC_VSS_VEREF_N         = 0x0200,
 +  MSP430X_ADC_VSS_VEREF_P_BUF     = 0x0300,
 +  MSP430X_ADC_VSS_VEREF_P         = 0x0400,
 +  MSP430X_ADC_VEREF_P_BUF_VCC     = 0x0500,
 +  MSP430X_ADC_VEREF_P_VCC         = 0x0600,
 +  MSP430X_ADC_VEREF_P_VREF_BUF    = 0x0700,
 +  MSP430X_ADC_VREF_BUF_VCC        = 0x0900,
 +  MSP430X_ADC_VREF_BUF_VEREF_P    = 0x0B00,
 +  MSP430X_ADC_VEREF_N_VCC         = 0x0C00,
 +  MSP430X_ADC_VEREF_N_VREF_BUF    = 0x0D00,
 +  MSP430X_ADC_VEREF_N_VEREF_P     = 0x0E00,
 +  MSP430X_ADC_VEREF_N_VEREF_P_BUF = 0x0F00
 +} MSP430XADCReferences;
 +
 +typedef enum {
 +  MSP430X_REF_1V2     = 0x0000,
 +  MSP430X_REF_2V0     = 0x0010,
 +  MSP430X_REF_2V5     = 0x0020,
 +  MSP430X_REF_1V2_EXT = 0x0002,
 +  MSP430X_REF_2V0_EXT = 0x0012,
 +  MSP430X_REF_2V5_EXT = 0x0022
 +} MSP430XREFSources;
 +
 +#define MSP430X_REF_NONE MSP430X_REF_1V2
 +
 +/** @} */
 +
 +/*===========================================================================*/
 +/* Driver pre-compile time settings.                                         */
 +/*===========================================================================*/
 +
 +/**
 + * @name    MSP430X configuration options
 + * @{
 + */
 +/**
 + * @brief   Stores ADC samples in an 8 bit integer.
 + * @note    10 and 12 bit sampling modes must not be used when this option is
 + *          enabled.
 + */
 +#if !defined(MSP430X_ADC_COMPACT_SAMPLES) || defined(__DOXYGEN__)
 +#define MSP430X_ADC_COMPACT_SAMPLES FALSE
 +#endif
 +
 +/**
 + * @brief   ADC1 driver enable switch.
 + * @details If set to @p TRUE the support for ADC1 is included.
 + * @note    The default is @p TRUE.
 + */
 +#if !defined(MSP430X_ADC_USE_ADC1) || defined(__DOXYGEN__)
 +#define MSP430X_ADC_USE_ADC1 TRUE
 +#endif
 +
 +/**]
 + * @brief   Exclusive DMA enable switch.
 + * @details If set to @p TRUE the support for exclusive DMA is included.
 + * @note    This increases the size of the compiled executable somewhat.
 + * @note    The default is @p FALSE.
 + */
 +#if !defined(MSP430X_ADC_EXCLUSIVE_DMA) || defined(__DOXYGEN__)
 +#define MSP430X_ADC_EXCLUSIVE_DMA FALSE
 +#endif
 +
 +#if MSP430X_ADC_USE_ADC1
 +
 +/**
 + * @brief   ADC1 clock source configuration
 + */
 +#if !defined(MSP430X_ADC1_CLK_SRC)
 +#define MSP430X_ADC1_CLK_SRC MSP430X_MODCLK
 +#endif
 +
 +#endif
 +/** @} */
 +
 +/*===========================================================================*/
 +/* Derived constants and error checks.                                       */
 +/*===========================================================================*/
 +
 +#if MSP430X_ADC_USE_ADC1
 +
 +#if !defined(__MSP430_HAS_ADC12_B__)
 +#error "No ADC present or ADC version not supported"
 +#endif
 +
 +#if (MSP430X_ADC1_CLK_SRC == MSP430X_MODCLK)
 +#define MSP430X_ADC1_CLK_FREQ MSP430X_MODCLK_FREQ
 +#define MSP430X_ADC1_SSEL ADC12SSEL_0
 +#elif (MSP430X_ADC1_CLK_SRC == MSP430X_ACLK)
 +#define MSP430X_ADC1_CLK_FREQ MSP430X_ACLK_FREQ
 +#define MSP430X_ADC1_SSEL ADC12SSEL_1
 +#elif (MSP430X_ADC1_CLK_SRC == MSP430X_MCLK)
 +#define MSP$30X_ADC1_CLK_FREQ MSP430X_MCLK_FREQ
 +#define MSP430X_ADC1_SSEL ADC12SSEL_2
 +#elif (MSP430X_ADC1_CLK_SRC == MSP430SMCLK)
 +#define MSP430X_ADC1_CLK_FREQ MSP430X_SMCLK_FREQ
 +#define MSP430X_ADC1_SSEL ADC12SSEL_3
 +#else
 +#error "Invalid ADC1 clock source requested!"
 +#endif
 +
 +#if !defined(MSP430X_ADC1_FREQ)
 +#warning "ADC clock frequency not defined - assuming 1 for all dividers"
 +#define MSP430X_ADC1_DIV_CALC(x) (x == 1)
 +#else
 +#define MSP430X_ADC1_DIV_CALC(x)                                               \
 +  ((MSP430X_ADC1_CLK_FREQ / x) == MSP430X_ADC1_FREQ)
 +#endif
 +
 +/**
 + * @brief   ADC1 prescaler calculations
 + */
 +#if MSP430X_ADC1_DIV_CALC(1)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__1
 +#define MSP430X_ADC1_DIV ADC12DIV_0
 +#elif MSP430X_ADC1_DIV_CALC(2)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__1
 +#define MSP430X_ADC1_DIV ADC12DIV_1
 +#elif MSP430X_ADC1_DIV_CALC(3)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__1
 +#define MSP430X_ADC1_DIV ADC12DIV_2
 +#elif MSP430X_ADC1_DIV_CALC(4)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__4
 +#define MSP430X_ADC1_DIV ADC12DIV_0
 +#elif MSP430X_ADC1_DIV_CALC(5)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__1
 +#define MSP430X_ADC1_DIV ADC12DIV_4
 +#elif MSP430X_ADC1_DIV_CALC(6)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__1
 +#define MSP430X_ADC1_DIV ADC12DIV_5
 +#elif MSP430X_ADC1_DIV_CALC(7)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__1
 +#define MSP430X_ADC1_DIV ADC12DIV_6
 +#elif MSP430X_ADC1_DIV_CALC(8)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__4
 +#define MSP430X_ADC1_DIV ADC12DIV_2
 +#elif MSP430X_ADC1_DIV_CALC(12)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__4
 +#define MSP430X_ADC1_DIV ADC12DIV_2
 +#elif MSP430X_ADC1_DIV_CALC(16)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__4
 +#define MSP430X_ADC1_DIV ADC12DIV_3
 +#elif MSP430X_ADC1_DIV_CALC(20)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__4
 +#define MSP430X_ADC1_DIV ADC12DIV_4
 +#elif MSP430X_ADC1_DIV_CALC(24)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__4
 +#define MSP430X_ADC1_DIV ADC12DIV_5
 +#elif MSP430X_ADC1_DIV_CALC(28)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__4
 +#define MSP430X_ADC1_DIV ADC12DIV_6
 +#elif MSP430X_ADC1_DIV_CALC(32)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__32
 +#define MSP430X_ADC1_DIV ADC12DIV_0
 +#elif MSP430X_ADC1_DIV_CALC(64)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__64
 +#define MSP430X_ADC1_DIV ADC12DIV_0
 +#elif MSP430X_ADC1_DIV_CALC(96)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__32
 +#define MSP430X_ADC1_DIV ADC12DIV_2
 +#elif MSP430X_ADC1_DIV_CALC(128)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__64
 +#define MSP430X_ADC1_DIV ADC12DIV_1
 +#elif MSP430X_ADC1_DIV_CALC(160)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__32
 +#define MSP430X_ADC1_DIV ADC12DIV_4
 +#elif MSP430X_ADC1_DIV_CALC(192)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__64
 +#define MSP430X_ADC1_DIV ADC12DIV_2
 +#elif MSP430X_ADC1_DIV_CALC(224)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__32
 +#define MSP430X_ADC1_DIV ADC12DIV_6
 +#elif MSP430X_ADC1_DIV_CALC(256)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__64
 +#define MSP430X_ADC1_DIV ADC12DIV_3
 +#elif MSP430X_ADC1_DIV_CALC(320)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__64
 +#define MSP430X_ADC1_DIV ADC12DIV_4
 +#elif MSP430X_ADC1_DIV_CALC(384)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__64
 +#define MSP430X_ADC1_DIV ADC12DIV_5
 +#elif MSP430X_ADC1_DIV_CALC(448)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__64
 +#define MSP430X_ADC1_DIV ADC12DIV_6
 +#elif MSP430X_ADC1_DIV_CALC(512)
 +#define MSP430X_ADC1_PDIV ADC12PDIV__64
 +#define MSP430X_ADC1_DIV ADC12DIV_7
 +#else
 +#error "MSP430X_ADC1_FREQ not achievable with MSP430X_ADC1_CLK_SRC"
 +#endif
 +
 +#endif /* MSP430X_ADC_USE_ADC1 */
 +
 +/*===========================================================================*/
 +/* Driver data structures and types.                                         */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   ADC sample data type.
 + */
 +#if !MSP430X_ADC_COMPACT_SAMPLES || defined(__DOXYGEN__)
 +typedef uint16_t adcsample_t;
 +#else
 +typedef uint8_t adcsample_t;
 +#endif
 +
 +/**
 + * @brief   Channels number in a conversion group.
 + */
 +typedef uint8_t adc_channels_num_t;
 +
 +/**
 + * @brief   Possible ADC failure causes.
 + * @note    Error codes are architecture dependent and should not relied
 + *          upon.
 + */
 +typedef enum {
 +  ADC_ERR_UNKNOWN  = 0, /**< Unknown error has occurred */
 +  ADC_ERR_OVERFLOW = 1, /**< ADC overflow condition.    */
 +  ADC_ERR_AWD      = 2  /**< Analog watchdog triggered. */
 +} adcerror_t;
 +
 +/**
 + * @brief   Type of a structure representing an ADC driver.
 + */
 +typedef struct ADCDriver ADCDriver;
 +
 +/**
 + * @brief   ADC notification callback type.
 + *
 + * @param[in] adcp      pointer to the @p ADCDriver object triggering the
 + *                      callback
 + * @param[in] buffer    pointer to the most recent samples data
 + * @param[in] n         number of buffer rows available starting from @p buffer
 + */
 +typedef void (*adccallback_t)(ADCDriver * adcp, adcsample_t * buffer, size_t n);
 +
 +/**
 + * @brief   ADC error callback type.
 + *
 + * @param[in] adcp      pointer to the @p ADCDriver object triggering the
 + *                      callback
 + * @param[in] err       ADC error code
 + */
 +typedef void (*adcerrorcallback_t)(ADCDriver * adcp, adcerror_t err);
 +
 +/**
 + * @brief MSP430X ADC register structure.
 + */
 +typedef struct {
 +  uint16_t ctl[4];
 +  uint16_t lo;
 +  uint16_t hi;
 +  uint16_t ifgr[3];
 +  uint16_t ier[3];
 +  uint16_t iv;
 +  uint16_t padding[3];
 +  uint16_t mctl[32];
 +  uint16_t mem[32];
 +} msp430x_adc_reg_t;
 +
 +/**
 + * @brief MSP430X ADC calibration structure.
 + */
 +typedef struct {
 +  uint16_t CAL_ADC_GAIN_FACTOR;
 +  uint16_t CAL_ADC_OFFSET;
 +  uint16_t CAL_ADC_12T30;
 +  uint16_t CAL_ADC_12T85;
 +  uint16_t CAL_ADC_20T30;
 +  uint16_t CAL_ADC_20T85;
 +  uint16_t CAL_ADC_25T30;
 +  uint16_t CAL_ADC_25T85;
 +} msp430x_adc_cal_t;
 +
 +/**
 + * @brief MSP430X REF calibration structure.
 + */
 +typedef struct {
 +  uint16_t CAL_ADC_12VREF_FACTOR;
 +  uint16_t CAL_ADC_20VREF_FACTOR;
 +  uint16_t CAL_ADC_25VREF_FACTOR;
 +} msp430x_ref_cal_t;
 +
 +/**
 + * @brief   Conversion group configuration structure.
 + * @details This implementation-dependent structure describes a conversion
 + *          operation.
 + * @note    The use of this configuration structure requires knowledge of
 + *          MSP430X ADC cell registers interface, please refer to the MSP430X
 + *          reference manual for details.
 + */
 +typedef struct {
 +  /**
 +   * @brief   Enables the circular buffer mode for the group.
 +   */
 +  bool circular;
 +  /**
 +   * @brief   Number of the analog channels belonging to the conversion group.
 +   */
 +  adc_channels_num_t num_channels;
 +  /**
 +   * @brief   Callback function associated to the group or @p NULL.
 +   */
 +  adccallback_t end_cb;
 +  /**
 +   * @brief   Error callback or @p NULL.
 +   */
 +  adcerrorcallback_t error_cb;
 +  /* End of the mandatory fields.*/
 +  /**
 +   * @brief   Sequence of analog channels belonging to the conversion group.
 +   * @note    Only the first num_channels are valid.
 +   */
 +  uint8_t channels[32];
 +  /**
 +   * @brief   Sample resolution
 +   */
 +  MSP430XADCResolution res;
 +  /**
 +   * @brief   Sampling time in clock cycles
 +   */
 +  MSP430XADCSampleRates rate;
 +  /**
 +   * @brief   Voltage references to use
 +   */
 +  MSP430XADCReferences ref;
 +  /**
 +   * @brief   VREF source
 +   */
 +  MSP430XREFSources vref_src;
 +} ADCConversionGroup;
 +
 +/**
 + * @brief   Driver configuration structure.
 + * @note    It could be empty on some architectures.
 + */
 +typedef struct {
 +#if MSP430X_ADC_EXCLUSIVE_DMA == TRUE || defined(__DOXYGEN__)
 +  /**
 +   * @brief The index of the DMA channel.
 +   * @note  This may be >MSP430X_DMA_CHANNELS to indicate that exclusive DMA
 +   *        is not used.
 +   */
 +  uint8_t dma_index;
 +#endif
 +} ADCConfig;
 +
 +/**
 + * @brief   Structure representing an ADC driver.
 + */
 +struct ADCDriver {
 +  /**
 +   * @brief Driver state.
 +   */
 +  adcstate_t state;
 +  /**
 +   * @brief Current configuration data.
 +   */
 +  const ADCConfig * config;
 +  /**
 +   * @brief Current samples buffer pointer or @p NULL.
 +   */
 +  adcsample_t * samples;
 +  /**
 +   * @brief Current samples buffer depth or @p 0.
 +   */
 +  size_t depth;
 +  /**
 +   * @brief Current conversion group pointer or @p NULL.
 +   */
 +  const ADCConversionGroup * grpp;
 +#if (ADC_USE_WAIT == TRUE) || defined(__DOXYGEN__)
 +  /**
 +   * @brief Waiting thread.
 +   */
 +  thread_reference_t thread;
 +#endif
 +#if (ADC_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
 +  /**
 +   * @brief Mutex protecting the peripheral.
 +   */
 +  mutex_t mutex;
 +#endif
 +#if defined(ADC_DRIVER_EXT_FIELDS)
 +  ADC_DRIVER_EXT_FIELDS
 +#endif
 +  /* End of the mandatory fields.*/
 +  /**
 +   * @brief Base address of ADC12_B registers
 +   */
 +  msp430x_adc_reg_t * regs;
 +  /**
 +   * @brief DMA request structure
 +   */
 +  msp430x_dma_req_t req;
 +  /**
 +   * @brief ADC calibration structure from TLV
 +   */
 +  msp430x_adc_cal_t * adc_cal;
 +  /**
 +   * @brief REF calibration structure from TLV
 +   */
 +  msp430x_ref_cal_t * ref_cal;
 +  /**
 +   * @brief Count of times DMA callback has been called
 +   */
 +  uint8_t count;
 +  /**
 +   * @brief DMA stream
 +   */
 +  msp430x_dma_ch_t dma;
 +};
 +
 +/*===========================================================================*/
 +/* Driver macros.                                                            */
 +/*===========================================================================*/
 +
 +/*===========================================================================*/
 +/* External declarations.                                                    */
 +/*===========================================================================*/
 +
 +#if (MSP430X_ADC_USE_ADC1 == TRUE) && !defined(__DOXYGEN__)
 +extern ADCDriver ADCD1;
 +#endif
 +
 +#ifdef __cplusplus
 +extern "C" {
 +#endif
 +void adc_lld_init(void);
 +void adc_lld_start(ADCDriver * adcp);
 +void adc_lld_stop(ADCDriver * adcp);
 +void adc_lld_start_conversion(ADCDriver * adcp);
 +void adc_lld_stop_conversion(ADCDriver * adcp);
 +adcsample_t adcMSP430XAdjustResult(ADCConversionGroup * grpp,
 +                                   adcsample_t sample);
 +adcsample_t adcMSP430XAdjustTemp(ADCConversionGroup * grpp, adcsample_t sample);
 +#ifdef __cplusplus
 +}
 +#endif
 +
 +#endif /* HAL_USE_ADC == TRUE */
 +
 +#endif /* HAL_ADC_LLD_H */
 +
 +/** @} */
 diff --git a/os/hal/ports/MSP430X/hal_dma_lld.c b/os/hal/ports/MSP430X/hal_dma_lld.c index 2e17afa..82bf39f 100644 --- a/os/hal/ports/MSP430X/hal_dma_lld.c +++ b/os/hal/ports/MSP430X/hal_dma_lld.c @@ -44,9 +44,8 @@ static msp430x_dma_ch_reg_t * const dma_channels =      (msp430x_dma_ch_reg_t *)&DMA0CTL;
  static msp430x_dma_cb_t callbacks[MSP430X_DMA_CHANNELS];
 -#if CH_CFG_USE_SEMAPHORES
 -static semaphore_t dma_lock;
 -#endif
 +static threads_queue_t dma_queue;
 +static unsigned int queue_length;
  /*===========================================================================*/
  /* Driver local functions.                                                   */
 @@ -88,11 +87,9 @@ PORT_IRQ_HANDLER(DMA_VECTOR) {    index = (DMAIV >> 1) - 1;
    if (index < MSP430X_DMA_CHANNELS) {
 -#if CH_CFG_USE_SEMAPHORES
 -    chSysLockFromISR();
 -    chSemSignalI(&dma_lock);
 -    chSysUnlockFromISR();
 -#endif
 +    osalSysLockFromISR();
 +    osalThreadDequeueNextI(&dma_queue, MSG_OK);
 +    osalSysUnlockFromISR();
      msp430x_dma_cb_t * cb = &callbacks[index];
 @@ -115,9 +112,7 @@ PORT_IRQ_HANDLER(DMA_VECTOR) {   * @init
   */
  void dmaInit(void) {
 -#if CH_CFG_USE_SEMAPHORES
 -  chSemObjectInit(&dma_lock, MSP430X_DMA_CHANNELS);
 -#endif
 +  osalThreadQueueObjectInit(&dma_queue);
  }
  /**
 @@ -127,134 +122,124 @@ void dmaInit(void) {   *          semaphores are enabled, the calling thread will sleep until a
   *          channel is available or the request times out. If semaphores are
   *          disabled, the calling thread will busy-wait instead of sleeping.
 + *          
 + *  @sclass
   */
 -bool dmaRequest(msp430x_dma_req_t * request, systime_t timeout) {
 -/* Check if a DMA channel is available */
 -#if CH_CFG_USE_SEMAPHORES
 -  msg_t semresult = chSemWaitTimeoutS(&dma_lock, timeout);
 -  if (semresult != MSG_OK)
 -    return true;
 -#endif
 -
 -#if !(CH_CFG_USE_SEMAPHORES)
 -  systime_t start = chVTGetSystemTimeX();
 -
 -  do {
 -#endif
 -    /* Grab the correct DMA channel to use */
 -    int i = 0;
 -    for (i = 0; i < MSP430X_DMA_CHANNELS; i++) {
 -      if (!(dma_channels[i].ctl & DMAEN)) {
 -        break;
 -      }
 -    }
 -#if !(CH_CFG_USE_SEMAPHORES)
 -    while (chVTTimeElapsedSinceX(start) < timeout)
 -      ;
 -#endif
 -
 -#if !(CH_CFG_USE_SEMAPHORES)
 -    if (i == MSP430X_DMA_CHANNELS) {
 -      return true;
 +int dmaRequestS(msp430x_dma_req_t * request, systime_t timeout) {
 +  
 +  osalDbgCheckClassS();
 +  
 +  /* Check if a DMA channel is available */
 +  if (queue_length >= MSP430X_DMA_CHANNELS) {
 +    msg_t queueresult = osalThreadEnqueueTimeoutS(&dma_queue, timeout);
 +    if (queueresult != MSG_OK)
 +      return -1;
 +  }
 +
 +  /* Grab the correct DMA channel to use */
 +  int i = 0;
 +  for (i = 0; i < MSP430X_DMA_CHANNELS; i++) {
 +    if (!(dma_channels[i].ctl & DMAEN)) {
 +      break;
      }
 -#endif
 +  }
 +
 +  /* Make the request */
 +  init_request(request, i);
 +  
 +  return i;
 +}
 -    /* Make the request */
 -    init_request(request, i);
 +/**
 + * @brief   Acquires exclusive control of a DMA channel.
 + * @pre     The channel must not be already acquired or an error is returned.
 + * @note    If the channel is in use by the DMA engine, blocks until acquired.
 + * @post    This channel must be interacted with using only the functions
 + *          defined in this module.
 + *
 + * @param[out] channel    The channel handle. Must be pre-allocated.
 + * @param[in]  index      The index of the channel (< MSP430X_DMA_CHANNELS).
 + * @return                The operation status.
 + * @retval false          no error, channel acquired.
 + * @retval true           error, channel already acquired.
 + * 
 + * @iclass
 + */
 +bool dmaAcquireI(msp430x_dma_ch_t * channel, uint8_t index) {
 +  
 +  osalDbgCheckClassI();
 -    return false;
 +  /* Is the channel already acquired? */
 +  osalDbgAssert(index < MSP430X_DMA_CHANNELS, "invalid channel index");
 +  if (dma_channels[index].ctl & DMADT_4) {
 +    return true;
    }
 -  /**
 -   * @brief   Acquires exclusive control of a DMA channel.
 -   * @pre     The channel must not be already acquired or an error is returned.
 -   * @note    If the channel is in use by the DMA engine, blocks until acquired.
 -   * @post    This channel must be interacted with using only the functions
 -   *          defined in this module.
 -   *
 -   * @param[out] channel    The channel handle. Must be pre-allocated.
 -   * @param[in]  index      The index of the channel (< MSP430X_DMA_CHANNELS).
 -   * @return                The operation status.
 -   * @retval false          no error, channel acquired.
 -   * @retval true           error, channel already acquired.
 -   */
 -  bool dmaAcquire(msp430x_dma_ch_t * channel, uint8_t index) {
 -    /* Acquire the channel in an idle mode */
 -
 -    /* Is the channel already acquired? */
 -    osalDbgAssert(index < MSP430X_DMA_CHANNELS, "invalid channel index");
 -    if (dma_channels[index].ctl & DMADT_4) {
 -      return true;
 -    }
 +  /* Increment the DMA counter */
 +  queue_length++;
 -/* Increment the DMA counter */
 -#if CH_CFG_USE_SEMAPHORES
 -    msg_t semresult = chSemWait(&dma_lock);
 -    if (semresult != MSG_OK)
 -      return true;
 -#endif
 +  while (dma_channels[index].ctl & DMAEN)
 +    ;
 -    while (dma_channels[index].ctl & DMAEN)
 -      ;
 +  /* Acquire the channel in an idle mode */
 +  dma_trigger_set(index, DMA_TRIGGER_MNEM(DMAREQ));
 +  dma_channels[index].sz  = 0;
 +  dma_channels[index].ctl = DMAEN | DMAABORT | DMADT_4;
 -    dma_trigger_set(index, DMA_TRIGGER_MNEM(DMAREQ));
 -    dma_channels[index].sz  = 0;
 -    dma_channels[index].ctl = DMAEN | DMAABORT | DMADT_4;
 +  channel->registers = dma_channels + index;
 +  channel->index     = index;
 +  channel->cb        = callbacks + index;
 +  
 +  return false;
 +}
 -    channel->registers = dma_channels + index;
 -    channel->index     = index;
 -    channel->cb        = callbacks + index;
 +/**
 + * @brief   Initiates a DMA transfer operation using an acquired channel.
 + * @pre     The channel must have been acquired using @p dmaAcquire().
 + *
 + * @param[in] channel   pointer to a DMA channel from @p dmaAcquire().
 + * @param[in] request   pointer to a DMA request object.
 + */
 +void dmaTransfer(msp430x_dma_ch_t * channel, msp430x_dma_req_t * request) {
 -    return false;
 -  }
 +  dma_trigger_set(channel->index, request->trigger);
 +  /**(channel->ctl) = request->trigger;*/
 -  /**
 -   * @brief   Initiates a DMA transfer operation using an acquired channel.
 -   * @pre     The channel must have been acquired using @p dmaAcquire().
 -   *
 -   * @param[in] channel   pointer to a DMA channel from @p dmaAcquire().
 -   * @param[in] request   pointer to a DMA request object.
 -   */
 -  void dmaTransfer(msp430x_dma_ch_t * channel, msp430x_dma_req_t * request) {
 -
 -    dma_trigger_set(channel->index, request->trigger);
 -    /**(channel->ctl) = request->trigger;*/
 -
 -    channel->cb->callback = request->callback.callback;
 -    channel->cb->args     = request->callback.args;
 -
 -    chSysLock();
 -    channel->registers->ctl &= (~DMAEN);
 -    channel->registers->sa  = (uintptr_t)request->source_addr;
 -    channel->registers->da  = (uintptr_t)request->dest_addr;
 -    channel->registers->sz  = request->size;
 -    channel->registers->ctl = DMAIE | request->data_mode | request->addr_mode |
 -                              request->transfer_mode | DMADT_4 | DMAEN |
 -                              DMAREQ; /* repeated transfers */
 -    chSysUnlock();
 -  }
 +  channel->cb->callback = request->callback.callback;
 +  channel->cb->args     = request->callback.args;
 -  /**
 -   * @brief   Releases exclusive control of a DMA channel.
 -   * @details The channel is released from control and returned to the DMA
 -   * engine
 -   *          pool. Trying to release an unallocated channel is an illegal
 -   *          operation and is trapped if assertions are enabled.
 -   * @pre     The channel must have been acquired using @p dmaAcquire().
 -   * @post    The channel is returned to the DMA engine pool.
 -   */
 -  void dmaRelease(msp430x_dma_ch_t * channel) {
 -
 -    osalDbgCheck(channel != NULL);
 -
 -    /* Release the channel in an idle mode */
 -    channel->registers->ctl = DMAABORT;
 -
 -/* release the DMA counter */
 -#if CH_CFG_USE_SEMAPHORES
 -    chSemSignal(&dma_lock);
 -#endif
 -  }
 +  channel->registers->ctl &= (~DMAEN);
 +  channel->registers->sa  = (uintptr_t)request->source_addr;
 +  channel->registers->da  = (uintptr_t)request->dest_addr;
 +  channel->registers->sz  = request->size;
 +  channel->registers->ctl = DMAIE | request->data_mode | request->addr_mode |
 +                            request->transfer_mode | DMADT_4 | DMAEN |
 +                            DMAREQ; /* repeated transfers */
 +}
 +
 +/**
 + * @brief   Releases exclusive control of a DMA channel.
 + * @details The channel is released from control and returned to the DMA
 + * engine
 + *          pool. Trying to release an unallocated channel is an illegal
 + *          operation and is trapped if assertions are enabled.
 + * @pre     The channel must have been acquired using @p dmaAcquire().
 + * @post    The channel is returned to the DMA engine pool.
 + */
 +void dmaRelease(msp430x_dma_ch_t * channel) {
 +  syssts_t sts;
 +
 +  sts = osalSysGetStatusAndLockX();
 +  osalDbgCheck(channel != NULL);
 +
 +  /* Release the channel in an idle mode */
 +  channel->registers->ctl = DMAABORT;
 +
 +  /* release the DMA counter */
 +  osalThreadDequeueAllI(&dma_queue, MSG_RESET);
 +  queue_length = 0;
 +  osalSysRestoreStatusX(sts);
 +}
  #endif /* HAL_USE_DMA == TRUE */
 diff --git a/os/hal/ports/MSP430X/hal_dma_lld.h b/os/hal/ports/MSP430X/hal_dma_lld.h index d1495d2..f558e78 100644 --- a/os/hal/ports/MSP430X/hal_dma_lld.h +++ b/os/hal/ports/MSP430X/hal_dma_lld.h @@ -159,8 +159,8 @@ typedef struct {  extern "C" {
  #endif
  void dmaInit(void);
 -bool dmaRequest(msp430x_dma_req_t * request, systime_t timeout);
 -bool dmaAcquire(msp430x_dma_ch_t * channel, uint8_t index);
 +int dmaRequestS(msp430x_dma_req_t * request, systime_t timeout);
 +bool dmaAcquireI(msp430x_dma_ch_t * channel, uint8_t index);
  void dmaTransfer(msp430x_dma_ch_t * channel, msp430x_dma_req_t * request);
  void dmaRelease(msp430x_dma_ch_t * channel);
 diff --git a/os/hal/ports/MSP430X/hal_lld.c b/os/hal/ports/MSP430X/hal_lld.c index 872fe97..812a0cf 100644 --- a/os/hal/ports/MSP430X/hal_lld.c +++ b/os/hal/ports/MSP430X/hal_lld.c @@ -82,6 +82,10 @@ void hal_lld_init(void) {    } while (SFRIFG1 & OFIFG);
    #endif
    CSCTL0_H = 0xFF; /* Lock clock system */
 +  
 +#if (HAL_USE_DMA == TRUE)
 +  dmaInit();
 +#endif
  }
  /** @} */
 diff --git a/os/hal/ports/MSP430X/hal_lld.h b/os/hal/ports/MSP430X/hal_lld.h index 9549453..62f07e9 100644 --- a/os/hal/ports/MSP430X/hal_lld.h +++ b/os/hal/ports/MSP430X/hal_lld.h @@ -25,6 +25,8 @@  #ifndef _HAL_LLD_H_
  #define _HAL_LLD_H_
 +#include "hal_dma_lld.h"
 +
  /*===========================================================================*/
  /* Driver constants.                                                         */
  /*===========================================================================*/
 diff --git a/os/hal/ports/MSP430X/hal_serial_lld.c b/os/hal/ports/MSP430X/hal_serial_lld.c index 8f22650..feb00ac 100644 --- a/os/hal/ports/MSP430X/hal_serial_lld.c +++ b/os/hal/ports/MSP430X/hal_serial_lld.c @@ -378,8 +378,7 @@ PORT_IRQ_HANDLER(USCI_A0_VECTOR) {      break;
    default: /* other interrupts */
 -    while (1)
 -      ;
 +    osalDbgAssert(false, "unhandled serial interrupt");
      break;
    }
 @@ -433,11 +432,11 @@ PORT_IRQ_HANDLER(USCI_A1_VECTOR) {      if (oqIsEmptyI(&SD1.oqueue))
        chnAddFlagsI(&SD1, CHN_TRANSMISSION_END);
      UCA1IE &= ~UCTXCPTIE;
 +    osalSysUnlockFromISR();
      break;
    default: /* other interrupts */
 -    while (1)
 -      ;
 +    osalDbgAssert(false, "unhandled serial interrupt");
      break;
    }
 @@ -491,11 +490,11 @@ PORT_IRQ_HANDLER(USCI_A2_VECTOR) {      if (oqIsEmptyI(&SD2.oqueue))
        chnAddFlagsI(&SD2, CHN_TRANSMISSION_END);
      UCA2IE &= ~UCTXCPTIE;
 +    osalSysUnlockFromISR();
      break;
    default: /* other interrupts */
 -    while (1)
 -      ;
 +    osalDbgAssert(false, "unhandled serial interrupt");
      break;
    }
 @@ -549,11 +548,11 @@ PORT_IRQ_HANDLER(USCI_A3_VECTOR) {      if (oqIsEmptyI(&SD3.oqueue))
        chnAddFlagsI(&SD3, CHN_TRANSMISSION_END);
      UCA3IE &= ~UCTXCPTIE;
 +    osalSysUnlockFromISR();
      break;
    default: /* other interrupts */
 -    while (1)
 -      ;
 +    osalDbgAssert(false, "unhandled serial interrupt");
      break;
    }
 diff --git a/os/hal/ports/MSP430X/hal_spi_lld.c b/os/hal/ports/MSP430X/hal_spi_lld.c index 3768487..3a54b1e 100644 --- a/os/hal/ports/MSP430X/hal_spi_lld.c +++ b/os/hal/ports/MSP430X/hal_spi_lld.c @@ -104,21 +104,21 @@ static uint16_t dummyrx;  static void init_transfer(SPIDriver * spip) {
  #if MSP430X_SPI_EXCLUSIVE_DMA == TRUE || defined(__DOXYGEN__)
 -  if (spip->config->dmarx_index > MSP430X_DMA_CHANNELS) {
 -    dmaRequest(&(spip->rx_req), TIME_INFINITE);
 +  if (spip->config->dmarx_index >= MSP430X_DMA_CHANNELS) {
 +    dmaRequestS(&(spip->rx_req), TIME_INFINITE);
    }
    else {
      dmaTransfer(&(spip->dmarx), &(spip->rx_req));
    }
 -  if (spip->config->dmatx_index > MSP430X_DMA_CHANNELS) {
 -    dmaRequest(&(spip->tx_req), TIME_INFINITE);
 +  if (spip->config->dmatx_index >= MSP430X_DMA_CHANNELS) {
 +    dmaRequestS(&(spip->tx_req), TIME_INFINITE);
    }
    else {
      dmaTransfer(&(spip->dmatx), &(spip->tx_req));
    }
  #else
 -  dmaRequest(&(spip->rx_req), TIME_INFINITE);
 -  dmaRequest(&(spip->tx_req), TIME_INFINITE);
 +  dmaRequestS(&(spip->rx_req), TIME_INFINITE);
 +  dmaRequestS(&(spip->tx_req), TIME_INFINITE);
  #endif
    *(spip->ifg) |= UCTXIFG;
 @@ -325,11 +325,11 @@ void spi_lld_start(SPIDriver * spip) {      /* Claim DMA streams here */
      bool b;
      if (spip->config->dmatx_index < MSP430X_DMA_CHANNELS) {
 -      b = dmaAcquire(&(spip->dmatx), spip->config->dmatx_index);
 +      b = dmaAcquireI(&(spip->dmatx), spip->config->dmatx_index);
        osalDbgAssert(!b, "stream already allocated");
      }
      if (spip->config->dmarx_index < MSP430X_DMA_CHANNELS) {
 -      b = dmaAcquire(&(spip->dmarx), spip->config->dmarx_index);
 +      b = dmaAcquireI(&(spip->dmarx), spip->config->dmarx_index);
        osalDbgAssert(!b, "stream already allocated");
      }
  #endif /* MSP430X_SPI_EXCLUSIVE_DMA */
 @@ -407,8 +407,12 @@ void spi_lld_stop(SPIDriver * spip) {    if (spip->state == SPI_READY) {
  /* Disables the peripheral.*/
  #if MSP430X_SPI_EXCLUSIVE_DMA == TRUE
 -    dmaRelease(&(spip->dmatx));
 -    dmaRelease(&(spip->dmarx));
 +    if (spip->config->dmatx_index < MSP430X_DMA_CHANNELS) {
 +      dmaRelease(&(spip->dmatx));
 +    }
 +    if (spip->config->dmarx_index < MSP430X_DMA_CHANNELS) {
 +      dmaRelease(&(spip->dmarx));
 +    }
  #endif
      spip->regs->ctlw0 = UCSWRST;
    }
 diff --git a/os/hal/ports/MSP430X/hal_spi_lld.h b/os/hal/ports/MSP430X/hal_spi_lld.h index 0ca4c67..949a8a0 100644 --- a/os/hal/ports/MSP430X/hal_spi_lld.h +++ b/os/hal/ports/MSP430X/hal_spi_lld.h @@ -118,7 +118,7 @@   * @note    This increases the size of the compiled executable somewhat.
   * @note    The default is @p FALSE.
   */
 -#if !defined(MSP430X_SPI_EXCLUSIVE_DMA) | defined(__DOXYGEN__)
 +#if !defined(MSP430X_SPI_EXCLUSIVE_DMA) || defined(__DOXYGEN__)
  #define MSP430X_SPI_EXCLUSIVE_DMA              FALSE
  #endif
 diff --git a/os/hal/ports/MSP430X/platform.mk b/os/hal/ports/MSP430X/platform.mk index 832814b..627a2f0 100644 --- a/os/hal/ports/MSP430X/platform.mk +++ b/os/hal/ports/MSP430X/platform.mk @@ -4,7 +4,8 @@ PLATFORMSRC = ${CHIBIOS_CONTRIB}/os/hal/ports/MSP430X/hal_lld.c \                ${CHIBIOS_CONTRIB}/os/hal/ports/MSP430X/hal_serial_lld.c \
                ${CHIBIOS_CONTRIB}/os/hal/ports/MSP430X/hal_pal_lld.c \
                ${CHIBIOS_CONTRIB}/os/hal/ports/MSP430X/hal_dma_lld.c \
 -              ${CHIBIOS_CONTRIB}/os/hal/ports/MSP430X/hal_spi_lld.c 
 +              ${CHIBIOS_CONTRIB}/os/hal/ports/MSP430X/hal_spi_lld.c \
 +              ${CHIBIOS_CONTRIB}/os/hal/ports/MSP430X/hal_adc_lld.c
  # Required include directories
  PLATFORMINC = ${CHIBIOS_CONTRIB}/os/hal/ports/MSP430X
 diff --git a/testhal/MSP430X/EXP430FR5969/ADC/Makefile b/testhal/MSP430X/EXP430FR5969/ADC/Makefile new file mode 100644 index 0000000..cf81f18 --- /dev/null +++ b/testhal/MSP430X/EXP430FR5969/ADC/Makefile @@ -0,0 +1,206 @@ +##############################################################################
 +# Build global options
 +# NOTE: Can be overridden externally.
 +#
 +
 +# Optimization level, can be [0, 1, 2, 3, s].
 +#     0 = turn off optimization. s = optimize for size.
 +#     (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
 +OPTIMIZE = 0
 +
 +# Debugging format.
 +DEBUG = 
 +#DEBUG = stabs
 +
 +# Memory/data model
 +MODEL = small
 +
 +# Object files directory
 +#     To put object files in current directory, use a dot (.), do NOT make
 +#     this an empty or blank macro!
 +OBJDIR = .
 +
 +# Compiler flag to set the C Standard level.
 +#     c89   = "ANSI" C
 +#     gnu89 = c89 plus GCC extensions
 +#     c99   = ISO C99 standard (not yet fully implemented)
 +#     gnu99 = c99 plus GCC extensions
 +CSTANDARD = -std=gnu11
 +
 +# Compiler options here.
 +ifeq ($(USE_OPT),)
 +  USE_OPT = -O$(OPTIMIZE) -g$(DEBUG) 
 +  USE_OPT += -funsigned-char -fshort-enums 
 +endif
 +
 +# C specific options here (added to USE_OPT).
 +ifeq ($(USE_COPT),)
 +  USE_COPT = 
 +endif
 +
 +# C++ specific options here (added to USE_OPT).
 +ifeq ($(USE_CPPOPT),)
 +  USE_CPPOPT = -fno-rtti
 +endif
 +
 +# Enable this if you want the linker to remove unused code and data
 +ifeq ($(USE_LINK_GC),)
 +  USE_LINK_GC = yes
 +endif
 +
 +# Linker extra options here.
 +ifeq ($(USE_LDOPT),)
 +  USE_LDOPT = 
 +endif
 +
 +# Enable this if you want link time optimizations (LTO)
 +ifeq ($(USE_LTO),)
 +  USE_LTO = no
 +endif
 +
 +# Enable the selected hardware multiplier
 +ifeq ($(USE_HWMULT),)
 +  USE_HWMULT = f5series
 +endif
 +
 +# Enable this if you want to see the full log while compiling.
 +ifeq ($(USE_VERBOSE_COMPILE),)
 +  USE_VERBOSE_COMPILE = yes
 +endif
 +
 +# If enabled, this option makes the build process faster by not compiling
 +# modules not used in the current configuration.
 +ifeq ($(USE_SMART_BUILD),)
 +  USE_SMART_BUILD = yes
 +endif
 +
 +#
 +# Build global options
 +##############################################################################
 +
 +##############################################################################
 +# Architecture or project specific options
 +#
 +
 +# Stack size to be allocated to the idle thread stack. This stack is
 +# the stack used by the main() thread.
 +ifeq ($(USE_IDLE_STACKSIZE),)
 +  USE_IDLE_STACKSIZE = 0xC00
 +endif
 +
 +#
 +# Architecture or project specific options
 +##############################################################################
 +
 +##############################################################################
 +# Project, sources and paths
 +#
 +
 +# Define project name here
 +PROJECT = nil
 +
 +# Imported source files and paths
 +CHIBIOS = ../../../../../ChibiOS-RT
 +CHIBIOS_CONTRIB = ../../../..
 +# Startup files.
 +include $(CHIBIOS_CONTRIB)/os/common/startup/MSP430X/compilers/GCC/mk/startup_msp430fr5xxx.mk
 +# HAL-OSAL files (optional).
 +include $(CHIBIOS)/os/hal/hal.mk
 +include $(CHIBIOS_CONTRIB)/os/hal/boards/EXP430FR5969/board.mk
 +include $(CHIBIOS_CONTRIB)/os/hal/ports/MSP430X/platform.mk
 +include $(CHIBIOS)/os/hal/osal/nil/osal.mk
 +# RTOS files (optional).
 +include $(CHIBIOS)/os/nil/nil.mk
 +include $(CHIBIOS_CONTRIB)/os/common/ports/MSP430X/compilers/GCC/mk/port.mk
 +# Other files (optional).
 +
 +# Define linker script file here
 +LDSCRIPT = $(STARTUPLD)/msp430fr5969.ld
 +
 +# C sources 
 +CSRC = $(STARTUPSRC) \
 +       $(KERNSRC) \
 +       $(PORTSRC) \
 +       $(OSALSRC) \
 +       $(HALSRC) \
 +       $(PLATFORMSRC) \
 +       $(BOARDSRC) \
 +       $(TESTSRC) \
 +       msp_vectors.c \
 +       main.c
 +
 +# C++ sources 
 +CPPSRC =
 +
 +# List ASM source files here
 +ASMSRC = $(STARTUPASM) $(PORTASM) $(OSALASM)
 +
 +INCDIR = $(CHIBIOS)/os/license \
 +				 $(STARTUPINC) $(KERNINC) $(PORTINC) $(OSALINC) \
 +         $(HALINC) $(PLATFORMINC) $(BOARDINC) $(TESTINC) \
 +         $(CHIBIOS)/os/various
 +
 +#
 +# Project, sources and paths
 +##############################################################################
 +
 +##############################################################################
 +# Compiler settings
 +#
 +
 +MCU = msp430fr5969
 +
 +TRGT = msp430-elf-
 +CC   = $(TRGT)gcc
 +CPPC = $(TRGT)g++
 +# Enable loading with g++ only if you need C++ runtime support.
 +# NOTE: You can use C++ even without C++ support if you are careful. C++
 +#       runtime support makes code size explode.
 +LD   = $(TRGT)gcc
 +#LD   = $(TRGT)g++
 +CP   = $(TRGT)objcopy
 +AS   = $(TRGT)gcc -x assembler-with-cpp
 +AR   = $(TRGT)ar
 +OD   = $(TRGT)objdump
 +SZ   = $(TRGT)size
 +HEX  = $(CP) -O ihex
 +BIN  = $(CP) -O binary
 +
 +# MSP430-specific options here
 +MOPT = -m$(MODEL)
 +
 +# Define C warning options here
 +CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes
 +
 +# Define C++ warning options here
 +CPPWARN = -Wall -Wextra -Wundef
 +
 +#
 +# Compiler settings
 +##############################################################################
 +
 +##############################################################################
 +# Start of user section
 +#
 +
 +# List all user C define here, like -D_DEBUG=1
 +UDEFS =
 +
 +# Define ASM defines here
 +UADEFS =
 +
 +# List all user directories here
 +UINCDIR =
 +
 +# List the user directory to look for the libraries here
 +ULIBDIR =
 +
 +# List all user libraries here
 +ULIBS =
 +
 +#
 +# End of user defines
 +##############################################################################
 +
 +RULESPATH = $(CHIBIOS_CONTRIB)/os/common/startup/MSP430X/compilers/GCC
 +include $(RULESPATH)/rules.mk
 diff --git a/testhal/MSP430X/EXP430FR5969/ADC/chconf.h b/testhal/MSP430X/EXP430FR5969/ADC/chconf.h new file mode 100644 index 0000000..3b7a8e1 --- /dev/null +++ b/testhal/MSP430X/EXP430FR5969/ADC/chconf.h @@ -0,0 +1,274 @@ +/*
 +    ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
 +
 +    Licensed under the Apache License, Version 2.0 (the "License");
 +    you may not use this file except in compliance with the License.
 +    You may obtain a copy of the License at
 +
 +        http://www.apache.org/licenses/LICENSE-2.0
 +
 +    Unless required by applicable law or agreed to in writing, software
 +    distributed under the License is distributed on an "AS IS" BASIS,
 +    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 +    See the License for the specific language governing permissions and
 +    limitations under the License.
 +*/
 +
 +/**
 + * @file    nilconf.h
 + * @brief   Configuration file template.
 + * @details A copy of this file must be placed in each project directory, it
 + *          contains the application specific kernel settings.
 + *
 + * @addtogroup config
 + * @details Kernel related settings and hooks.
 + * @{
 + */
 +
 +#ifndef CHCONF_H
 +#define CHCONF_H
 +
 +#define _CHIBIOS_NIL_CONF_
 +
 +/*===========================================================================*/
 +/**
 + * @name Kernel parameters and options
 + * @{
 + */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Number of user threads in the application.
 + * @note    This number is not inclusive of the idle thread which is
 + *          Implicitly handled.
 + */
 +#define CH_CFG_NUM_THREADS                 1
 +
 +/** @} */
 +
 +/*===========================================================================*/
 +/**
 + * @name System timer settings
 + * @{
 + */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   System time counter resolution.
 + * @note    Allowed values are 16 or 32 bits.
 + */
 +#define CH_CFG_ST_RESOLUTION               16
 +
 +/**
 + * @brief   System tick frequency.
 + * @note    This value together with the @p CH_CFG_ST_RESOLUTION
 + *          option defines the maximum amount of time allowed for
 + *          timeouts.
 + */
 +#define CH_CFG_ST_FREQUENCY                1000
 +
 +/**
 + * @brief   Time delta constant for the tick-less mode.
 + * @note    If this value is zero then the system uses the classic
 + *          periodic tick. This value represents the minimum number
 + *          of ticks that is safe to specify in a timeout directive.
 + *          The value one is not valid, timeouts are rounded up to
 + *          this value.
 + */
 +#define CH_CFG_ST_TIMEDELTA                0
 +
 +/** @} */
 +
 +/*===========================================================================*/
 +/**
 + * @name Subsystem options
 + * @{
 + */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Semaphores APIs.
 + * @details If enabled then the Semaphores APIs are included in the kernel.
 + *
 + * @note    The default is @p TRUE.
 + */
 +#define CH_CFG_USE_SEMAPHORES               TRUE
 +
 +/**
 + * @brief   Mutexes APIs.
 + * @details If enabled then the mutexes APIs are included in the kernel.
 + *
 + * @note    Feature not currently implemented.
 + * @note    The default is @p FALSE.
 + */
 +#define CH_CFG_USE_MUTEXES                  FALSE
 +
 +/**
 + * @brief   Events Flags APIs.
 + * @details If enabled then the event flags APIs are included in the kernel.
 + *
 + * @note    The default is @p TRUE.
 + */
 +#define CH_CFG_USE_EVENTS                   TRUE
 +
 +/**
 + * @brief   Mailboxes APIs.
 + * @details If enabled then the asynchronous messages (mailboxes) APIs are
 + *          included in the kernel.
 + *
 + * @note    The default is @p TRUE.
 + * @note    Requires @p CH_CFG_USE_SEMAPHORES.
 + */
 +#define CH_CFG_USE_MAILBOXES                TRUE
 +
 +/**
 + * @brief   Core Memory Manager APIs.
 + * @details If enabled then the core memory manager APIs are included
 + *          in the kernel.
 + *
 + * @note    The default is @p TRUE.
 + */
 +#define CH_CFG_USE_MEMCORE                  TRUE
 +
 +/**
 + * @brief   Heap Allocator APIs.
 + * @details If enabled then the memory heap allocator APIs are included
 + *          in the kernel.
 + *
 + * @note    The default is @p TRUE.
 + */
 +#define CH_CFG_USE_HEAP                     TRUE
 +
 +/**
 + * @brief   Memory Pools Allocator APIs.
 + * @details If enabled then the memory pools allocator APIs are included
 + *          in the kernel.
 + *
 + * @note    The default is @p TRUE.
 + */
 +#define CH_CFG_USE_MEMPOOLS                 TRUE
 +
 +/**
 + * @brief   Managed RAM size.
 + * @details Size of the RAM area to be managed by the OS. If set to zero
 + *          then the whole available RAM is used. The core memory is made
 + *          available to the heap allocator and/or can be used directly through
 + *          the simplified core memory allocator.
 + *
 + * @note    In order to let the OS manage the whole RAM the linker script must
 + *          provide the @p __heap_base__ and @p __heap_end__ symbols.
 + * @note    Requires @p CH_CFG_USE_MEMCORE.
 + */
 +#define CH_CFG_MEMCORE_SIZE                 0
 +
 +/** @} */
 +
 +/*===========================================================================*/
 +/**
 + * @name Debug options
 + * @{
 + */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Debug option, kernel statistics.
 + *
 + * @note    Feature not currently implemented.
 + * @note    The default is @p FALSE.
 + */
 +#define CH_DBG_STATISTICS                   FALSE
 +
 +/**
 + * @brief   Debug option, system state check.
 + *
 + * @note    The default is @p FALSE.
 + */
 +#define CH_DBG_SYSTEM_STATE_CHECK           TRUE
 +
 +/**
 + * @brief   Debug option, parameters checks.
 + *
 + * @note    The default is @p FALSE.
 + */
 +#define CH_DBG_ENABLE_CHECKS                TRUE
 +
 +/**
 + * @brief   System assertions.
 + * 
 + * @note    The default is @p FALSE.
 + */
 +#define CH_DBG_ENABLE_ASSERTS              TRUE
 +
 +/**
 + * @brief   Stack check.
 + * 
 + *@note     The default is @p FALSE.
 + */
 +#define CH_DBG_ENABLE_STACK_CHECK          TRUE
 +
 +/** @} */
 +
 +/*===========================================================================*/
 +/**
 + * @name Kernel hooks
 + * @{
 + */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   System initialization hook.
 + */
 +#if !defined(CH_CFG_SYSTEM_INIT_HOOK) || defined(__DOXYGEN__)
 +#define CH_CFG_SYSTEM_INIT_HOOK() {                                        \
 +}
 +#endif
 +
 +/**
 + * @brief   Threads descriptor structure extension.
 + * @details User fields added to the end of the @p thread_t structure.
 + */
 +#define CH_CFG_THREAD_EXT_FIELDS                                           \
 +  /* Add threads custom fields here.*/
 +
 +/**
 + * @brief   Threads initialization hook.
 + */
 +#define CH_CFG_THREAD_EXT_INIT_HOOK(tr) {                                  \
 +  /* Add custom threads initialization code here.*/                         \
 +}
 +
 +/**
 + * @brief   Idle thread enter hook.
 + * @note    This hook is invoked within a critical zone, no OS functions
 + *          should be invoked from here.
 + * @note    This macro can be used to activate a power saving mode.
 + */
 +#define CH_CFG_IDLE_ENTER_HOOK() {                                         \
 +}
 +
 +/**
 + * @brief   Idle thread leave hook.
 + * @note    This hook is invoked within a critical zone, no OS functions
 + *          should be invoked from here.
 + * @note    This macro can be used to deactivate a power saving mode.
 + */
 +#define CH_CFG_IDLE_LEAVE_HOOK() {                                         \
 +}
 +
 +/**
 + * @brief   System halt hook.
 + */
 +#if !defined(CH_CFG_SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
 +#define CH_CFG_SYSTEM_HALT_HOOK(reason) {                                  \
 +}
 +#endif
 +
 +/** @} */
 +
 +/*===========================================================================*/
 +/* Port-specific settings (override port settings defaulted in nilcore.h).   */
 +/*===========================================================================*/
 +
 +#endif  /* _CHCONF_H_ */
 +
 +/** @} */
 diff --git a/testhal/MSP430X/EXP430FR5969/ADC/halconf.h b/testhal/MSP430X/EXP430FR5969/ADC/halconf.h new file mode 100644 index 0000000..2982a63 --- /dev/null +++ b/testhal/MSP430X/EXP430FR5969/ADC/halconf.h @@ -0,0 +1,388 @@ +/*
 +    ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
 +
 +    Licensed under the Apache License, Version 2.0 (the "License");
 +    you may not use this file except in compliance with the License.
 +    You may obtain a copy of the License at
 +
 +        http://www.apache.org/licenses/LICENSE-2.0
 +
 +    Unless required by applicable law or agreed to in writing, software
 +    distributed under the License is distributed on an "AS IS" BASIS,
 +    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 +    See the License for the specific language governing permissions and
 +    limitations under the License.
 +*/
 +
 +/**
 + * @file    templates/halconf.h
 + * @brief   HAL configuration header.
 + * @details HAL configuration file, this file allows to enable or disable the
 + *          various device drivers from your application. You may also use
 + *          this file in order to override the device drivers default settings.
 + *
 + * @addtogroup HAL_CONF
 + * @{
 + */
 +
 +#ifndef HALCONF_H
 +#define HALCONF_H
 +
 +#include "mcuconf.h"
 +
 +/**
 + * @brief   Enables the PAL subsystem.
 + */
 +#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
 +#define HAL_USE_PAL                 TRUE
 +#endif
 +
 +/**
 + * @brief   Enables the DMA subsystem.
 + */
 +#if !defined(HAL_USE_DMA) || defined(__DOXYGEN__)
 +#define HAL_USE_DMA                 TRUE
 +#endif
 +
 +/**
 + * @brief   Enables the ADC subsystem.
 + */
 +#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
 +#define HAL_USE_ADC                 TRUE
 +#endif
 +
 +/**
 + * @brief   Enables the DAC subsystem.
 + */
 +#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
 +#define HAL_USE_DAC                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the CAN subsystem.
 + */
 +#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
 +#define HAL_USE_CAN                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the EXT subsystem.
 + */
 +#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
 +#define HAL_USE_EXT                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the GPT subsystem.
 + */
 +#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
 +#define HAL_USE_GPT                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the I2C subsystem.
 + */
 +#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
 +#define HAL_USE_I2C                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the I2S subsystem.
 + */
 +#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__)
 +#define HAL_USE_I2S                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the ICU subsystem.
 + */
 +#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
 +#define HAL_USE_ICU                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the MAC subsystem.
 + */
 +#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
 +#define HAL_USE_MAC                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the MMC_SPI subsystem.
 + */
 +#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
 +#define HAL_USE_MMC_SPI             FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the PWM subsystem.
 + */
 +#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
 +#define HAL_USE_PWM                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the RTC subsystem.
 + */
 +#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
 +#define HAL_USE_RTC                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the SDC subsystem.
 + */
 +#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
 +#define HAL_USE_SDC                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the SERIAL subsystem.
 + */
 +#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
 +#define HAL_USE_SERIAL              TRUE
 +#endif
 +
 +/**
 + * @brief   Enables the SERIAL over USB subsystem.
 + */
 +#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
 +#define HAL_USE_SERIAL_USB          FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the SPI subsystem.
 + */
 +#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
 +#define HAL_USE_SPI                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the UART subsystem.
 + */
 +#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
 +#define HAL_USE_UART                FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the USB subsystem.
 + */
 +#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
 +#define HAL_USE_USB                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the WDG subsystem.
 + */
 +#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__)
 +#define HAL_USE_WDG                 FALSE
 +#endif
 +
 +/*===========================================================================*/
 +/* ADC driver related settings.                                              */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Enables synchronous APIs.
 + * @note    Disabling this option saves both code and data space.
 + */
 +#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
 +#define ADC_USE_WAIT                TRUE
 +#endif
 +
 +/**
 + * @brief   Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
 + * @note    Disabling this option saves both code and data space.
 + */
 +#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
 +#define ADC_USE_MUTUAL_EXCLUSION    TRUE
 +#endif
 +
 +/*===========================================================================*/
 +/* CAN driver related settings.                                              */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Sleep mode related APIs inclusion switch.
 + */
 +#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
 +#define CAN_USE_SLEEP_MODE          FALSE
 +#endif
 +
 +/*===========================================================================*/
 +/* I2C driver related settings.                                              */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Enables the mutual exclusion APIs on the I2C bus.
 + */
 +#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
 +#define I2C_USE_MUTUAL_EXCLUSION    FALSE
 +#endif
 +
 +/*===========================================================================*/
 +/* MAC driver related settings.                                              */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Enables an event sources for incoming packets.
 + */
 +#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
 +#define MAC_USE_ZERO_COPY           FALSE
 +#endif
 +
 +/**
 + * @brief   Enables an event sources for incoming packets.
 + */
 +#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
 +#define MAC_USE_EVENTS              FALSE
 +#endif
 +
 +/*===========================================================================*/
 +/* MMC_SPI driver related settings.                                          */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Delays insertions.
 + * @details If enabled this options inserts delays into the MMC waiting
 + *          routines releasing some extra CPU time for the threads with
 + *          lower priority, this may slow down the driver a bit however.
 + *          This option is recommended also if the SPI driver does not
 + *          use a DMA channel and heavily loads the CPU.
 + */
 +#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
 +#define MMC_NICE_WAITING            FALSE
 +#endif
 +
 +/*===========================================================================*/
 +/* SDC driver related settings.                                              */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Number of initialization attempts before rejecting the card.
 + * @note    Attempts are performed at 10mS intervals.
 + */
 +#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
 +#define SDC_INIT_RETRY              100
 +#endif
 +
 +/**
 + * @brief   Include support for MMC cards.
 + * @note    MMC support is not yet implemented so this option must be kept
 + *          at @p FALSE.
 + */
 +#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
 +#define SDC_MMC_SUPPORT             FALSE
 +#endif
 +
 +/**
 + * @brief   Delays insertions.
 + * @details If enabled this options inserts delays into the MMC waiting
 + *          routines releasing some extra CPU time for the threads with
 + *          lower priority, this may slow down the driver a bit however.
 + */
 +#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
 +#define SDC_NICE_WAITING            FALSE
 +#endif
 +
 +/*===========================================================================*/
 +/* SERIAL driver related settings.                                           */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Default bit rate.
 + * @details Configuration parameter, this is the baud rate selected for the
 + *          default configuration.
 + */
 +#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
 +#define SERIAL_DEFAULT_BITRATE      38400
 +#endif
 +
 +/**
 + * @brief   Serial buffers size.
 + * @details Configuration parameter, you can change the depth of the queue
 + *          buffers depending on the requirements of your application.
 + * @note    The default is 16 bytes for both the transmission and receive
 + *          buffers.
 + */
 +#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
 +#define SERIAL_BUFFERS_SIZE         16
 +#endif
 +
 +/*===========================================================================*/
 +/* SERIAL_USB driver related setting.                                        */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Serial over USB buffers size.
 + * @details Configuration parameter, the buffer size must be a multiple of
 + *          the USB data endpoint maximum packet size.
 + * @note    The default is 256 bytes for both the transmission and receive
 + *          buffers.
 + */
 +#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
 +#define SERIAL_USB_BUFFERS_SIZE     256
 +#endif
 +
 +/**
 + * @brief   Serial over USB number of buffers.
 + * @note    The default is 2 buffers.
 + */
 +#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__)
 +#define SERIAL_USB_BUFFERS_NUMBER   2
 +#endif
 +
 +/*===========================================================================*/
 +/* SPI driver related settings.                                              */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Enables synchronous APIs.
 + * @note    Disabling this option saves both code and data space.
 + */
 +#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
 +#define SPI_USE_WAIT                TRUE
 +#endif
 +
 +/**
 + * @brief   Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
 + * @note    Disabling this option saves both code and data space.
 + */
 +#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
 +#define SPI_USE_MUTUAL_EXCLUSION    FALSE
 +#endif
 +
 +/*===========================================================================*/
 +/* UART driver related settings.                                             */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Enables synchronous APIs.
 + * @note    Disabling this option saves both code and data space.
 + */
 +#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
 +#define UART_USE_WAIT               FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
 + * @note    Disabling this option saves both code and data space.
 + */
 +#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
 +#define UART_USE_MUTUAL_EXCLUSION   FALSE
 +#endif
 +
 +/*===========================================================================*/
 +/* USB driver related settings.                                              */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Enables synchronous APIs.
 + * @note    Disabling this option saves both code and data space.
 + */
 +#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__)
 +#define USB_USE_WAIT                FALSE
 +#endif
 +
 +#endif /* _HALCONF_H_ */
 +
 +/** @} */
 diff --git a/testhal/MSP430X/EXP430FR5969/ADC/main.c b/testhal/MSP430X/EXP430FR5969/ADC/main.c new file mode 100644 index 0000000..8a530ec --- /dev/null +++ b/testhal/MSP430X/EXP430FR5969/ADC/main.c @@ -0,0 +1,270 @@ +/*
 +    ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
 +
 +    Licensed under the Apache License, Version 2.0 (the "License");
 +    you may not use this file except in compliance with the License.
 +    You may obtain a copy of the License at
 +
 +        http://www.apache.org/licenses/LICENSE-2.0
 +
 +    Unless required by applicable law or agreed to in writing, software
 +    distributed under the License is distributed on an "AS IS" BASIS,
 +    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 +    See the License for the specific language governing permissions and
 +    limitations under the License.
 +*/
 +
 +#include "ch.h"
 +#include "hal.h"
 +#include "string.h"
 +#include "stdio.h" /* eesh */
 +
 +/* Disable watchdog because of lousy startup code in newlib */
 +static void __attribute__((naked, section(".crt_0042disable_watchdog"), used))
 +disable_watchdog(void) {
 +  WDTCTL = WDTPW | WDTHOLD;
 +}
 +
 +const char * start_msg  = "\r\n\r\nExecuting ADC test suite...\r\n";
 +const char * test_1_msg = "\r\nTEST 1: 1 channel, depth 1, no circular\r\n";
 +const char * test_2_msg = "\r\nTEST 2: 1 channel, depth 8, no circular\r\n";
 +const char * test_3_msg = "\r\nTEST 3: 4 channels, depth 1, no circular\r\n";
 +const char * test_4_msg = "\r\nTEST 4: 4 channels, depth 8, no circular\r\n";
 +const char * test_5_msg = "\r\nTEST 5: 1 channel, depth 1, circular\r\n";
 +const char * test_6_msg = "\r\nTEST 6: 1 channel, depth 8, circular\r\n";
 +const char * test_7_msg = "\r\nTEST 7: 4 channel, depth 1, circular\r\n";
 +const char * test_8_msg = "\r\nTEST 8: 4 channel, depth 8, circular\r\n";
 +const char * test_9_msg = "\r\nTEST 9: 1 channel, depth 1, synchronous\r\n";
 +const char * test_10_msg = "\r\nTEST 9: 1 channel, depth 1, exclusive\r\n";
 +
 +const char * success_string = "\r\nSUCCESS\r\n";
 +const char * fail_string = "\r\nFAILURE\r\n";
 +
 +char out_string[128];
 +const char * raw_fmt_string = "Raw Value: %d\r\n";
 +const char * cooked_fmt_string = "Cooked Value: %d\r\n";
 +const char * chn_fmt_string = "\r\nCHANNEL %d\r\n";
 +
 +uint16_t buffer_margin[72];
 +uint16_t * buffer = buffer_margin + 4;
 +uint8_t depth;
 +uint8_t cb_arg = 0;
 +uint16_t cb_expect;
 +
 +static const int test = 0;
 +
 +ADCConfig config = {
 +  255 /* dma_index */
 +};
 +
 +ADCConversionGroup group = {
 +  false, /* circular */
 +  1, /* num_channels */
 +  NULL, /* end_cb */
 +  NULL, /* error_cb */
 +  { 
 +    30, 31, 30, 31, 0, 0, 0, 0,
 +    0, 0, 0, 0, 0, 0, 0, 0,
 +    0, 0, 0, 0, 0, 0, 0, 0,
 +    0, 0, 0, 0, 0, 0, 0, 0
 +  }, /* channels */
 +  MSP430X_ADC_RES_12BIT, /* res */
 +  MSP430X_ADC_SHT_32, /* rate */
 +  MSP430X_ADC_VSS_VREF_BUF, /* ref */
 +  MSP430X_REF_2V5 /* vref_src */
 +};
 +
 +void print(const char * msg) {
 +    
 +  if (!test) {
 +    chnWrite(&SD0, (const uint8_t *)msg, strlen(msg));
 +  }
 +}
 +
 +void adc_callback(ADCDriver * adcp, adcsample_t *buffer, size_t n) {
 +  (void)adcp;
 +  (void)buffer;
 +  (void)n;
 +  
 +  cb_arg++;
 +  
 +  if (adcp->grpp->circular && cb_arg == cb_expect) {
 +    osalSysLockFromISR();
 +    adcStopConversionI(adcp);
 +    osalSysUnlockFromISR();
 +  }
 +}
 +
 +void run_test(const char * test_msg, uint8_t num_channels, uint8_t depth,
 +    bool circular) {
 +  print(test_msg);
 +  
 +  cb_arg = 0;
 +  
 +  group.num_channels = num_channels;
 +  group.circular = circular;
 +  group.end_cb = adc_callback;
 +  
 +  if (depth > 1) cb_expect = 2;
 +  else cb_expect = 1;
 +  if (circular) cb_expect *= 3;
 +  
 +  adcStartConversion(&ADCD1, &group, buffer, depth);
 +  
 +  while (ADCD1.state == ADC_ACTIVE) ;
 +  
 +  
 +  int index = 0;
 +  for (int j = 0; j < depth; j++) {
 +    for (int i = 0; i < group.num_channels; i++) {
 +      index = i + (j * group.num_channels);
 +      sniprintf(out_string, 128, chn_fmt_string, group.channels[i]);
 +      print(out_string);
 +      
 +      sniprintf(out_string, 128, raw_fmt_string, buffer[index]); 
 +      print(out_string);
 +      
 +      if (group.channels[i] == 30) { /* internal temp sensor */
 +        buffer[index] = adcMSP430XAdjustTemp(&group, buffer[index]);
 +      }
 +      else {
 +        buffer[index] = adcMSP430XAdjustResult(&group, buffer[index]);
 +      }
 +      
 +      sniprintf(out_string, 128, cooked_fmt_string, buffer[index]); 
 +      print(out_string);
 +    }
 +  }
 +  
 +  if (cb_arg == cb_expect) {
 +    print(success_string);
 +  }
 +  else {
 +    print(fail_string);
 +  }
 +}
 +
 +/*
 + * Thread 2.
 + */
 +THD_WORKING_AREA(waThread1, 4096);
 +THD_FUNCTION(Thread1, arg) {
 +
 +  (void)arg;
 +
 +  /*
 +   * Activate the serial driver 0 using the driver default configuration.
 +   */
 +  sdStart(&SD0, NULL);
 +
 +
 +  while (chnGetTimeout(&SD0, TIME_INFINITE)) {
 +    print(start_msg);
 +    chThdSleepMilliseconds(2000);
 +
 +    /* Activate the ADC driver 1 using its config */
 +    adcStart(&ADCD1, &config);
 +    
 +    /* Test 1 - 1ch1d, no circular */
 +    run_test(test_1_msg, 1, 1, false);
 +    
 +    /* Test 2 - 1ch8d, no circular */
 +    run_test(test_2_msg, 1, 8, false);
 +    
 +    /* Test 3 - 4chd1, no circular */
 +    run_test(test_3_msg, 4, 1, false);
 +    
 +    /* Test 4 - 4ch8d, no circular */
 +    run_test(test_4_msg, 4, 8, false);
 +    
 +    /* Test 5 - 1ch1d, circular */
 +    run_test(test_5_msg, 1, 1, true);
 +    
 +    /* Test 6 - 1ch8d, circular */
 +    run_test(test_6_msg, 1, 8, true);
 +    
 +    /* Test 7 - 4ch1d, circular */
 +    run_test(test_7_msg, 4, 1, true);
 +    
 +    /* Test 8 - 4ch8d, circular */
 +    run_test(test_8_msg, 4, 8, true);
 +    
 +    /* Test 9 - 1ch1d, synchronous */
 +    print(test_9_msg);
 +    cb_arg = 0;
 +    
 +    group.num_channels = 1;
 +    group.circular = false;
 +    group.end_cb = adc_callback;
 +    
 +    cb_expect = 1;
 +    
 +    adcConvert(&ADCD1, &group, buffer, 1);
 +    
 +    while (ADCD1.state == ADC_ACTIVE) ;
 +    
 +    sniprintf(out_string, 128, chn_fmt_string, group.channels[0]);
 +    print(out_string);
 +    
 +    sniprintf(out_string, 128, raw_fmt_string, buffer[0]); 
 +    print(out_string);
 +    
 +    buffer[0] = adcMSP430XAdjustTemp(&group, buffer[0]);
 +    
 +    sniprintf(out_string, 128, cooked_fmt_string, buffer[0]); 
 +    print(out_string);
 +    
 +    if (cb_arg == cb_expect) {
 +      print(success_string);
 +    }
 +    else {
 +      print(fail_string);
 +    }
 +    
 +    /* Test 10 - 1ch1d, exclusive */
 +    adcStop(&ADCD1);
 +    
 +    config.dma_index = 0;
 +    
 +    adcStart(&ADCD1, &config);
 +    
 +    run_test(test_10_msg, 1, 1, false);
 +    
 +    adcStop(&ADCD1);
 +    
 +    config.dma_index = 255;
 +  }
 +}
 +
 +/*
 + * Threads static table, one entry per thread. The number of entries must
 + * match NIL_CFG_NUM_THREADS.
 + */
 +THD_TABLE_BEGIN
 +  THD_TABLE_ENTRY(waThread1, "adc_test", Thread1, NULL)
 +THD_TABLE_END
 +
 +/*
 + * Application entry point.
 + */
 +int main(void) {
 +
 +  /*
 +   * System initializations.
 +   * - HAL initialization, this also initializes the configured device drivers
 +   *   and performs the board-specific initializations.
 +   * - Kernel initialization, the main() function becomes a thread and the
 +   *   RTOS is active.
 +   */
 +  WDTCTL = WDTPW | WDTHOLD;
 +
 +  halInit();
 +  chSysInit();
 +
 +  /* This is now the idle thread loop, you may perform here a low priority
 +     task but you must never try to sleep or wait in this loop. Note that
 +     this tasks runs at the lowest priority level so any instruction added
 +     here will be executed after all other tasks have been started.*/
 +  while (true) {
 +  }
 +}
 diff --git a/testhal/MSP430X/EXP430FR5969/ADC/mcuconf.h b/testhal/MSP430X/EXP430FR5969/ADC/mcuconf.h new file mode 100644 index 0000000..70e29ff --- /dev/null +++ b/testhal/MSP430X/EXP430FR5969/ADC/mcuconf.h @@ -0,0 +1,68 @@ +/*
 +    ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
 +
 +    Licensed under the Apache License, Version 2.0 (the "License");
 +    you may not use this file except in compliance with the License.
 +    You may obtain a copy of the License at
 +
 +        http://www.apache.org/licenses/LICENSE-2.0
 +
 +    Unless required by applicable law or agreed to in writing, software
 +    distributed under the License is distributed on an "AS IS" BASIS,
 +    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 +    See the License for the specific language governing permissions and
 +    limitations under the License.
 +*/
 +
 +#ifndef MCUCONF_H
 +#define MCUCONF_H
 +
 +/*
 + * MSP430X drivers configuration.
 + * The following settings override the default settings present in
 + * the various device driver implementation headers.
 + * Note that the settings for each driver only have effect if the driver
 + * is enabled in halconf.h.
 + * 
 + */
 +
 +#define MSP430X_MCUCONF
 +
 +/* HAL driver system settings */
 +#define MSP430X_ACLK_SRC MSP430X_VLOCLK
 +#define MSP430X_LFXTCLK_FREQ 0
 +#define MSP430X_HFXTCLK_FREQ 0
 +#define MSP430X_DCOCLK_FREQ 8000000
 +#define MSP430X_MCLK_DIV 1
 +#define MSP430X_SMCLK_DIV 32
 +
 +/*
 + * SERIAL driver system settings.
 + */
 +#define MSP430X_SERIAL_USE_USART0         TRUE
 +#define MSP430X_USART0_CLK_SRC            MSP430X_SMCLK_SRC
 +#define MSP430X_SERIAL_USE_USART1         FALSE
 +#define MSP430X_SERIAL_USE_USART2         FALSE
 +#define MSP430X_SERIAL_USE_USART3         FALSE
 +
 +/*
 + * ST driver system settings.
 + */
 +#define MSP430X_ST_CLK_SRC MSP430X_SMCLK_SRC
 +#define MSP430X_ST_TIMER_TYPE B
 +#define MSP430X_ST_TIMER_INDEX 0
 +
 +/*
 + * SPI driver system settings.
 + */
 +#define MSP430X_SPI_USE_SPIA1 FALSE
 +#define MSP430X_SPI_USE_SPIB0 FALSE
 +#define MSP430X_SPI_EXCLUSIVE_DMA TRUE
 +
 +/*
 + * ADC driver system settings
 + */
 +#define MSP430X_ADC_EXCLUSIVE_DMA TRUE
 +#define MSP430X_ADC1_FREQ 5000000 / 256
 +
 +#endif /* _MCUCONF_H_ */
 diff --git a/testhal/MSP430X/EXP430FR5969/ADC/msp_vectors.c b/testhal/MSP430X/EXP430FR5969/ADC/msp_vectors.c new file mode 100644 index 0000000..d12ed53 --- /dev/null +++ b/testhal/MSP430X/EXP430FR5969/ADC/msp_vectors.c @@ -0,0 +1,286 @@ +#include <msp430.h>
 +
 +__attribute__((interrupt(1)))
 +void Vector1(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(2)))
 +void Vector2(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(3)))
 +void Vector3(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(4)))
 +void Vector4(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(5)))
 +void Vector5(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(6)))
 +void Vector6(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(7)))
 +void Vector7(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(8)))
 +void Vector8(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(9)))
 +void Vector9(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(10)))
 +void Vector10(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(11)))
 +void Vector11(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(12)))
 +void Vector12(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(13)))
 +void Vector13(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(14)))
 +void Vector14(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(15)))
 +void Vector15(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(16)))
 +void Vector16(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(17)))
 +void Vector17(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(18)))
 +void Vector18(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(19)))
 +void Vector19(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(20)))
 +void Vector20(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(21)))
 +void Vector21(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(22)))
 +void Vector22(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(23)))
 +void Vector23(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(24)))
 +void Vector24(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(25)))
 +void Vector25(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(26)))
 +void Vector26(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(27)))
 +void Vector27(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(28)))
 +void Vector28(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(29)))
 +void Vector29(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(30)))
 +void Vector30(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(31)))
 +void Vector31(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(32)))
 +void Vector32(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(35)))
 +void Vector35(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(36)))
 +void Vector36(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(38)))
 +void Vector38(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(39)))
 +void Vector39(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(41)))
 +void Vector41(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(42)))
 +void Vector42(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(44)))
 +void Vector44(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(45)))
 +void Vector45(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(46)))
 +void Vector46(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(48)))
 +void Vector48(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(50)))
 +void Vector50(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(51)))
 +void Vector51(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(53)))
 +void Vector53(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(54)))
 +void Vector54(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(55)))
 +void Vector55(void) {
 +
 +  while (1) {
 +  }
 +}
 +
 +
 diff --git a/testhal/MSP430X/EXP430FR5969/DMA/main.c b/testhal/MSP430X/EXP430FR5969/DMA/main.c index 1929af1..757eedc 100644 --- a/testhal/MSP430X/EXP430FR5969/DMA/main.c +++ b/testhal/MSP430X/EXP430FR5969/DMA/main.c @@ -35,6 +35,8 @@ const char * test_6_msg = "TEST 6: Attempt to claim already claimed DMA "                            "and succeed.\r\n";
  const char * test_7_msg = "TEST 7: Claim DMA channel 1, perform a Word-to-word "
                            "memcpy, and release it\r\n";
 +const char * test_8_msg = "TEST 8: Claim all three DMA channels, try to issue dmaRequest, "
 +                          "fail\r\n";
  const char * succeed_string = "SUCCESS\r\n\r\n";
  const char * fail_string    = "FAILURE\r\n\r\n";
 @@ -43,6 +45,8 @@ char instring[256];  char outstring[256];
  msp430x_dma_req_t * request;
  uint8_t cb_arg = 1;
 +bool result;
 +int result_i;
  void dma_callback_test(void * args) {
 @@ -120,6 +124,8 @@ msp430x_dma_req_t test_5_req = {  };
  msp430x_dma_ch_t ch = { NULL, 0, NULL };
 +msp430x_dma_ch_t ch1 = { NULL, 0, NULL };
 +msp430x_dma_ch_t ch2 = { NULL, 0, NULL };
  /*
   * Thread 2.
 @@ -146,7 +152,9 @@ THD_FUNCTION(Thread1, arg) {        chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string));
      }
      request = &test_1_req;
 -    dmaRequest(request, TIME_INFINITE);
 +    chSysLock();
 +    dmaRequestS(request, TIME_INFINITE);
 +    chSysUnlock();
      if (strcmp("After DMA test  \r\n", outstring)) {
        chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string));
      }
 @@ -162,7 +170,9 @@ THD_FUNCTION(Thread1, arg) {        chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string));
      }
      request = &test_2_req;
 -    dmaRequest(request, TIME_INFINITE);
 +    chSysLock();
 +    dmaRequestS(request, TIME_INFINITE);
 +    chSysUnlock();
      if (strcmp("After DMA test  \r\n", outstring)) {
        chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string));
      }
 @@ -178,7 +188,9 @@ THD_FUNCTION(Thread1, arg) {        chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string));
      }
      request = &test_3_req;
 -    dmaRequest(request, TIME_INFINITE);
 +    chSysLock();
 +    dmaRequestS(request, TIME_INFINITE);
 +    chSysUnlock();
      if (strcmp("AAAAAAAAAAAAAAAA\r\n", outstring)) {
        chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string));
      }
 @@ -196,7 +208,9 @@ THD_FUNCTION(Thread1, arg) {        chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string));
      }
      request = &test_4_req;
 -    dmaRequest(request, TIME_INFINITE);
 +    chSysLock();
 +    dmaRequestS(request, TIME_INFINITE);
 +    chSysUnlock();
      if (strcmp("After DMA test  \r\n", outstring) || cb_arg) {
        chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string));
      }
 @@ -213,7 +227,9 @@ THD_FUNCTION(Thread1, arg) {        chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string));
      }
      request = &test_5_req;
 -    dmaAcquire(&ch, 0);
 +    chSysLock();
 +    dmaAcquireI(&ch, 0);
 +    chSysUnlock();
      dmaTransfer(&ch, request);
      if (strcmp("After DMA test  \r\n", outstring)) {
        chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string));
 @@ -225,11 +241,17 @@ THD_FUNCTION(Thread1, arg) {      /* Test 6 - Attempt to claim DMA channel 0, fail, release it, attempt to
       * claim it again */
      chnWrite(&SD0, (const uint8_t *)test_6_msg, strlen(test_6_msg));
 -    if (!dmaAcquire(&ch, 0)) {
 +    chSysLock();
 +    result = dmaAcquireI(&ch, 0);
 +    chSysUnlock();
 +    if (!result) {
        chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string));
      }
      dmaRelease(&ch);
 -    if (dmaAcquire(&ch, 0)) {
 +    chSysLock();
 +    result = dmaAcquireI(&ch, 0);
 +    chSysUnlock();
 +    if (result) {
        chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string));
      }
      else {
 @@ -246,7 +268,9 @@ THD_FUNCTION(Thread1, arg) {        chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string));
      }
      request = &test_5_req;
 -    dmaAcquire(&ch, 1);
 +    chSysLock();
 +    dmaAcquireI(&ch, 1);
 +    chSysUnlock();
      dmaTransfer(&ch, request);
      if (strcmp("After DMA test  \r\n", outstring)) {
        chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string));
 @@ -255,6 +279,40 @@ THD_FUNCTION(Thread1, arg) {        chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string));
      }
      dmaRelease(&ch);
 +    
 +    /* Test 8 - Claim all 3 DMA channels, attempt dmaRequest, fail */
 +    chnWrite(&SD0, (const uint8_t *)test_8_msg, strlen(test_8_msg));
 +    chSysLock();
 +    result = dmaAcquireI(&ch, 0);
 +    chSysUnlock();
 +    if (result) {
 +      chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string));
 +    }
 +    chSysLock();
 +    result = dmaAcquireI(&ch1, 1);
 +    chSysUnlock();
 +    if (result) {
 +      chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string));
 +    }
 +    chSysLock();
 +    result = dmaAcquireI(&ch2, 2);
 +    chSysUnlock();
 +    if (result) {
 +      chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string));
 +    }
 +    chSysLock();
 +    result_i = dmaRequestS(request, TIME_IMMEDIATE);
 +    chSysUnlock();
 +    if (result_i > 0) {
 +      chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string));
 +    }
 +    else {
 +      chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string));
 +    }
 +    dmaRelease(&ch);
 +    dmaRelease(&ch1);
 +    dmaRelease(&ch2);
 +
    }
  }
 diff --git a/testhal/MSP430X/EXP430FR5969/DMA/msp_vectors.c b/testhal/MSP430X/EXP430FR5969/DMA/msp_vectors.c index 8968fb9..f5ad4b6 100644 --- a/testhal/MSP430X/EXP430FR5969/DMA/msp_vectors.c +++ b/testhal/MSP430X/EXP430FR5969/DMA/msp_vectors.c @@ -192,18 +192,6 @@ void Vector32(void) {    while (1) {
    }
  }
 -__attribute__((interrupt(33)))
 -void Vector33(void) {
 -
 -  while (1) {
 -  }
 -}
 -__attribute__((interrupt(34)))
 -void Vector34(void) {
 -
 -  while (1) {
 -  }
 -}
  __attribute__((interrupt(35)))
  void Vector35(void) {
 @@ -216,12 +204,7 @@ void Vector36(void) {    while (1) {
    }
  }
 -__attribute__((interrupt(37)))
 -void Vector37(void) {
 -  while (1) {
 -  }
 -}
  __attribute__((interrupt(38)))
  void Vector38(void) {
 @@ -234,12 +217,7 @@ void Vector39(void) {    while (1) {
    }
  }
 -__attribute__((interrupt(40)))
 -void Vector40(void) {
 -  while (1) {
 -  }
 -}
  __attribute__((interrupt(41)))
  void Vector41(void) {
 diff --git a/testhal/MSP430X/EXP430FR5969/SPI/msp_vectors.c b/testhal/MSP430X/EXP430FR5969/SPI/msp_vectors.c index 8968fb9..c23cbc8 100644 --- a/testhal/MSP430X/EXP430FR5969/SPI/msp_vectors.c +++ b/testhal/MSP430X/EXP430FR5969/SPI/msp_vectors.c @@ -192,18 +192,6 @@ void Vector32(void) {    while (1) {
    }
  }
 -__attribute__((interrupt(33)))
 -void Vector33(void) {
 -
 -  while (1) {
 -  }
 -}
 -__attribute__((interrupt(34)))
 -void Vector34(void) {
 -
 -  while (1) {
 -  }
 -}
  __attribute__((interrupt(35)))
  void Vector35(void) {
 @@ -216,12 +204,6 @@ void Vector36(void) {    while (1) {
    }
  }
 -__attribute__((interrupt(37)))
 -void Vector37(void) {
 -
 -  while (1) {
 -  }
 -}
  __attribute__((interrupt(38)))
  void Vector38(void) {
 @@ -234,12 +216,6 @@ void Vector39(void) {    while (1) {
    }
  }
 -__attribute__((interrupt(40)))
 -void Vector40(void) {
 -
 -  while (1) {
 -  }
 -}
  __attribute__((interrupt(41)))
  void Vector41(void) {
 diff --git a/testhal/MSP430X/EXP430FR6989/ADC/Makefile b/testhal/MSP430X/EXP430FR6989/ADC/Makefile new file mode 100644 index 0000000..b86021e --- /dev/null +++ b/testhal/MSP430X/EXP430FR6989/ADC/Makefile @@ -0,0 +1,206 @@ +##############################################################################
 +# Build global options
 +# NOTE: Can be overridden externally.
 +#
 +
 +# Optimization level, can be [0, 1, 2, 3, s].
 +#     0 = turn off optimization. s = optimize for size.
 +#     (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
 +OPTIMIZE = 0
 +
 +# Debugging format.
 +DEBUG = 
 +#DEBUG = stabs
 +
 +# Memory/data model
 +MODEL = small
 +
 +# Object files directory
 +#     To put object files in current directory, use a dot (.), do NOT make
 +#     this an empty or blank macro!
 +OBJDIR = .
 +
 +# Compiler flag to set the C Standard level.
 +#     c89   = "ANSI" C
 +#     gnu89 = c89 plus GCC extensions
 +#     c99   = ISO C99 standard (not yet fully implemented)
 +#     gnu99 = c99 plus GCC extensions
 +CSTANDARD = -std=gnu11
 +
 +# Compiler options here.
 +ifeq ($(USE_OPT),)
 +  USE_OPT = -O$(OPTIMIZE) -g$(DEBUG) 
 +  USE_OPT += -funsigned-char -fshort-enums 
 +endif
 +
 +# C specific options here (added to USE_OPT).
 +ifeq ($(USE_COPT),)
 +  USE_COPT = 
 +endif
 +
 +# C++ specific options here (added to USE_OPT).
 +ifeq ($(USE_CPPOPT),)
 +  USE_CPPOPT = -fno-rtti
 +endif
 +
 +# Enable this if you want the linker to remove unused code and data
 +ifeq ($(USE_LINK_GC),)
 +  USE_LINK_GC = yes
 +endif
 +
 +# Linker extra options here.
 +ifeq ($(USE_LDOPT),)
 +  USE_LDOPT = 
 +endif
 +
 +# Enable this if you want link time optimizations (LTO)
 +ifeq ($(USE_LTO),)
 +  USE_LTO = no
 +endif
 +
 +# Enable the selected hardware multiplier
 +ifeq ($(USE_HWMULT),)
 +  USE_HWMULT = f5series
 +endif
 +
 +# Enable this if you want to see the full log while compiling.
 +ifeq ($(USE_VERBOSE_COMPILE),)
 +  USE_VERBOSE_COMPILE = yes
 +endif
 +
 +# If enabled, this option makes the build process faster by not compiling
 +# modules not used in the current configuration.
 +ifeq ($(USE_SMART_BUILD),)
 +  USE_SMART_BUILD = yes
 +endif
 +
 +#
 +# Build global options
 +##############################################################################
 +
 +##############################################################################
 +# Architecture or project specific options
 +#
 +
 +# Stack size to be allocated to the idle thread stack. This stack is
 +# the stack used by the main() thread.
 +ifeq ($(USE_IDLE_STACKSIZE),)
 +  USE_IDLE_STACKSIZE = 0xC00
 +endif
 +
 +#
 +# Architecture or project specific options
 +##############################################################################
 +
 +##############################################################################
 +# Project, sources and paths
 +#
 +
 +# Define project name here
 +PROJECT = nil
 +
 +# Imported source files and paths
 +CHIBIOS = ../../../../../ChibiOS-RT
 +CHIBIOS_CONTRIB = ../../../..
 +# Startup files.
 +include $(CHIBIOS_CONTRIB)/os/common/startup/MSP430X/compilers/GCC/mk/startup_msp430fr5xxx.mk
 +# HAL-OSAL files (optional).
 +include $(CHIBIOS)/os/hal/hal.mk
 +include $(CHIBIOS_CONTRIB)/os/hal/boards/EXP430FR6989/board.mk
 +include $(CHIBIOS_CONTRIB)/os/hal/ports/MSP430X/platform.mk
 +include $(CHIBIOS)/os/hal/osal/nil/osal.mk
 +# RTOS files (optional).
 +include $(CHIBIOS)/os/nil/nil.mk
 +include $(CHIBIOS_CONTRIB)/os/common/ports/MSP430X/compilers/GCC/mk/port.mk
 +# Other files (optional).
 +
 +# Define linker script file here
 +LDSCRIPT = $(STARTUPLD)/msp430fr6989.ld
 +
 +# C sources 
 +CSRC = $(STARTUPSRC) \
 +       $(KERNSRC) \
 +       $(PORTSRC) \
 +       $(OSALSRC) \
 +       $(HALSRC) \
 +       $(PLATFORMSRC) \
 +       $(BOARDSRC) \
 +       $(TESTSRC) \
 +       msp_vectors.c \
 +       main.c
 +
 +# C++ sources 
 +CPPSRC =
 +
 +# List ASM source files here
 +ASMSRC = $(STARTUPASM) $(PORTASM) $(OSALASM)
 +
 +INCDIR = $(CHIBIOS)/os/license \
 +				 $(STARTUPINC) $(KERNINC) $(PORTINC) $(OSALINC) \
 +         $(HALINC) $(PLATFORMINC) $(BOARDINC) $(TESTINC) \
 +         $(CHIBIOS)/os/various
 +
 +#
 +# Project, sources and paths
 +##############################################################################
 +
 +##############################################################################
 +# Compiler settings
 +#
 +
 +MCU = msp430fr6989
 +
 +TRGT = msp430-elf-
 +CC   = $(TRGT)gcc
 +CPPC = $(TRGT)g++
 +# Enable loading with g++ only if you need C++ runtime support.
 +# NOTE: You can use C++ even without C++ support if you are careful. C++
 +#       runtime support makes code size explode.
 +LD   = $(TRGT)gcc
 +#LD   = $(TRGT)g++
 +CP   = $(TRGT)objcopy
 +AS   = $(TRGT)gcc -x assembler-with-cpp
 +AR   = $(TRGT)ar
 +OD   = $(TRGT)objdump
 +SZ   = $(TRGT)size
 +HEX  = $(CP) -O ihex
 +BIN  = $(CP) -O binary
 +
 +# MSP430-specific options here
 +MOPT = -m$(MODEL)
 +
 +# Define C warning options here
 +CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes
 +
 +# Define C++ warning options here
 +CPPWARN = -Wall -Wextra -Wundef
 +
 +#
 +# Compiler settings
 +##############################################################################
 +
 +##############################################################################
 +# Start of user section
 +#
 +
 +# List all user C define here, like -D_DEBUG=1
 +UDEFS =
 +
 +# Define ASM defines here
 +UADEFS =
 +
 +# List all user directories here
 +UINCDIR =
 +
 +# List the user directory to look for the libraries here
 +ULIBDIR =
 +
 +# List all user libraries here
 +ULIBS =
 +
 +#
 +# End of user defines
 +##############################################################################
 +
 +RULESPATH = $(CHIBIOS_CONTRIB)/os/common/startup/MSP430X/compilers/GCC
 +include $(RULESPATH)/rules.mk
 diff --git a/testhal/MSP430X/EXP430FR6989/ADC/chconf.h b/testhal/MSP430X/EXP430FR6989/ADC/chconf.h new file mode 100644 index 0000000..3b7a8e1 --- /dev/null +++ b/testhal/MSP430X/EXP430FR6989/ADC/chconf.h @@ -0,0 +1,274 @@ +/*
 +    ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
 +
 +    Licensed under the Apache License, Version 2.0 (the "License");
 +    you may not use this file except in compliance with the License.
 +    You may obtain a copy of the License at
 +
 +        http://www.apache.org/licenses/LICENSE-2.0
 +
 +    Unless required by applicable law or agreed to in writing, software
 +    distributed under the License is distributed on an "AS IS" BASIS,
 +    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 +    See the License for the specific language governing permissions and
 +    limitations under the License.
 +*/
 +
 +/**
 + * @file    nilconf.h
 + * @brief   Configuration file template.
 + * @details A copy of this file must be placed in each project directory, it
 + *          contains the application specific kernel settings.
 + *
 + * @addtogroup config
 + * @details Kernel related settings and hooks.
 + * @{
 + */
 +
 +#ifndef CHCONF_H
 +#define CHCONF_H
 +
 +#define _CHIBIOS_NIL_CONF_
 +
 +/*===========================================================================*/
 +/**
 + * @name Kernel parameters and options
 + * @{
 + */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Number of user threads in the application.
 + * @note    This number is not inclusive of the idle thread which is
 + *          Implicitly handled.
 + */
 +#define CH_CFG_NUM_THREADS                 1
 +
 +/** @} */
 +
 +/*===========================================================================*/
 +/**
 + * @name System timer settings
 + * @{
 + */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   System time counter resolution.
 + * @note    Allowed values are 16 or 32 bits.
 + */
 +#define CH_CFG_ST_RESOLUTION               16
 +
 +/**
 + * @brief   System tick frequency.
 + * @note    This value together with the @p CH_CFG_ST_RESOLUTION
 + *          option defines the maximum amount of time allowed for
 + *          timeouts.
 + */
 +#define CH_CFG_ST_FREQUENCY                1000
 +
 +/**
 + * @brief   Time delta constant for the tick-less mode.
 + * @note    If this value is zero then the system uses the classic
 + *          periodic tick. This value represents the minimum number
 + *          of ticks that is safe to specify in a timeout directive.
 + *          The value one is not valid, timeouts are rounded up to
 + *          this value.
 + */
 +#define CH_CFG_ST_TIMEDELTA                0
 +
 +/** @} */
 +
 +/*===========================================================================*/
 +/**
 + * @name Subsystem options
 + * @{
 + */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Semaphores APIs.
 + * @details If enabled then the Semaphores APIs are included in the kernel.
 + *
 + * @note    The default is @p TRUE.
 + */
 +#define CH_CFG_USE_SEMAPHORES               TRUE
 +
 +/**
 + * @brief   Mutexes APIs.
 + * @details If enabled then the mutexes APIs are included in the kernel.
 + *
 + * @note    Feature not currently implemented.
 + * @note    The default is @p FALSE.
 + */
 +#define CH_CFG_USE_MUTEXES                  FALSE
 +
 +/**
 + * @brief   Events Flags APIs.
 + * @details If enabled then the event flags APIs are included in the kernel.
 + *
 + * @note    The default is @p TRUE.
 + */
 +#define CH_CFG_USE_EVENTS                   TRUE
 +
 +/**
 + * @brief   Mailboxes APIs.
 + * @details If enabled then the asynchronous messages (mailboxes) APIs are
 + *          included in the kernel.
 + *
 + * @note    The default is @p TRUE.
 + * @note    Requires @p CH_CFG_USE_SEMAPHORES.
 + */
 +#define CH_CFG_USE_MAILBOXES                TRUE
 +
 +/**
 + * @brief   Core Memory Manager APIs.
 + * @details If enabled then the core memory manager APIs are included
 + *          in the kernel.
 + *
 + * @note    The default is @p TRUE.
 + */
 +#define CH_CFG_USE_MEMCORE                  TRUE
 +
 +/**
 + * @brief   Heap Allocator APIs.
 + * @details If enabled then the memory heap allocator APIs are included
 + *          in the kernel.
 + *
 + * @note    The default is @p TRUE.
 + */
 +#define CH_CFG_USE_HEAP                     TRUE
 +
 +/**
 + * @brief   Memory Pools Allocator APIs.
 + * @details If enabled then the memory pools allocator APIs are included
 + *          in the kernel.
 + *
 + * @note    The default is @p TRUE.
 + */
 +#define CH_CFG_USE_MEMPOOLS                 TRUE
 +
 +/**
 + * @brief   Managed RAM size.
 + * @details Size of the RAM area to be managed by the OS. If set to zero
 + *          then the whole available RAM is used. The core memory is made
 + *          available to the heap allocator and/or can be used directly through
 + *          the simplified core memory allocator.
 + *
 + * @note    In order to let the OS manage the whole RAM the linker script must
 + *          provide the @p __heap_base__ and @p __heap_end__ symbols.
 + * @note    Requires @p CH_CFG_USE_MEMCORE.
 + */
 +#define CH_CFG_MEMCORE_SIZE                 0
 +
 +/** @} */
 +
 +/*===========================================================================*/
 +/**
 + * @name Debug options
 + * @{
 + */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Debug option, kernel statistics.
 + *
 + * @note    Feature not currently implemented.
 + * @note    The default is @p FALSE.
 + */
 +#define CH_DBG_STATISTICS                   FALSE
 +
 +/**
 + * @brief   Debug option, system state check.
 + *
 + * @note    The default is @p FALSE.
 + */
 +#define CH_DBG_SYSTEM_STATE_CHECK           TRUE
 +
 +/**
 + * @brief   Debug option, parameters checks.
 + *
 + * @note    The default is @p FALSE.
 + */
 +#define CH_DBG_ENABLE_CHECKS                TRUE
 +
 +/**
 + * @brief   System assertions.
 + * 
 + * @note    The default is @p FALSE.
 + */
 +#define CH_DBG_ENABLE_ASSERTS              TRUE
 +
 +/**
 + * @brief   Stack check.
 + * 
 + *@note     The default is @p FALSE.
 + */
 +#define CH_DBG_ENABLE_STACK_CHECK          TRUE
 +
 +/** @} */
 +
 +/*===========================================================================*/
 +/**
 + * @name Kernel hooks
 + * @{
 + */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   System initialization hook.
 + */
 +#if !defined(CH_CFG_SYSTEM_INIT_HOOK) || defined(__DOXYGEN__)
 +#define CH_CFG_SYSTEM_INIT_HOOK() {                                        \
 +}
 +#endif
 +
 +/**
 + * @brief   Threads descriptor structure extension.
 + * @details User fields added to the end of the @p thread_t structure.
 + */
 +#define CH_CFG_THREAD_EXT_FIELDS                                           \
 +  /* Add threads custom fields here.*/
 +
 +/**
 + * @brief   Threads initialization hook.
 + */
 +#define CH_CFG_THREAD_EXT_INIT_HOOK(tr) {                                  \
 +  /* Add custom threads initialization code here.*/                         \
 +}
 +
 +/**
 + * @brief   Idle thread enter hook.
 + * @note    This hook is invoked within a critical zone, no OS functions
 + *          should be invoked from here.
 + * @note    This macro can be used to activate a power saving mode.
 + */
 +#define CH_CFG_IDLE_ENTER_HOOK() {                                         \
 +}
 +
 +/**
 + * @brief   Idle thread leave hook.
 + * @note    This hook is invoked within a critical zone, no OS functions
 + *          should be invoked from here.
 + * @note    This macro can be used to deactivate a power saving mode.
 + */
 +#define CH_CFG_IDLE_LEAVE_HOOK() {                                         \
 +}
 +
 +/**
 + * @brief   System halt hook.
 + */
 +#if !defined(CH_CFG_SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
 +#define CH_CFG_SYSTEM_HALT_HOOK(reason) {                                  \
 +}
 +#endif
 +
 +/** @} */
 +
 +/*===========================================================================*/
 +/* Port-specific settings (override port settings defaulted in nilcore.h).   */
 +/*===========================================================================*/
 +
 +#endif  /* _CHCONF_H_ */
 +
 +/** @} */
 diff --git a/testhal/MSP430X/EXP430FR6989/ADC/halconf.h b/testhal/MSP430X/EXP430FR6989/ADC/halconf.h new file mode 100644 index 0000000..2982a63 --- /dev/null +++ b/testhal/MSP430X/EXP430FR6989/ADC/halconf.h @@ -0,0 +1,388 @@ +/*
 +    ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
 +
 +    Licensed under the Apache License, Version 2.0 (the "License");
 +    you may not use this file except in compliance with the License.
 +    You may obtain a copy of the License at
 +
 +        http://www.apache.org/licenses/LICENSE-2.0
 +
 +    Unless required by applicable law or agreed to in writing, software
 +    distributed under the License is distributed on an "AS IS" BASIS,
 +    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 +    See the License for the specific language governing permissions and
 +    limitations under the License.
 +*/
 +
 +/**
 + * @file    templates/halconf.h
 + * @brief   HAL configuration header.
 + * @details HAL configuration file, this file allows to enable or disable the
 + *          various device drivers from your application. You may also use
 + *          this file in order to override the device drivers default settings.
 + *
 + * @addtogroup HAL_CONF
 + * @{
 + */
 +
 +#ifndef HALCONF_H
 +#define HALCONF_H
 +
 +#include "mcuconf.h"
 +
 +/**
 + * @brief   Enables the PAL subsystem.
 + */
 +#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
 +#define HAL_USE_PAL                 TRUE
 +#endif
 +
 +/**
 + * @brief   Enables the DMA subsystem.
 + */
 +#if !defined(HAL_USE_DMA) || defined(__DOXYGEN__)
 +#define HAL_USE_DMA                 TRUE
 +#endif
 +
 +/**
 + * @brief   Enables the ADC subsystem.
 + */
 +#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
 +#define HAL_USE_ADC                 TRUE
 +#endif
 +
 +/**
 + * @brief   Enables the DAC subsystem.
 + */
 +#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
 +#define HAL_USE_DAC                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the CAN subsystem.
 + */
 +#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
 +#define HAL_USE_CAN                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the EXT subsystem.
 + */
 +#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
 +#define HAL_USE_EXT                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the GPT subsystem.
 + */
 +#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
 +#define HAL_USE_GPT                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the I2C subsystem.
 + */
 +#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
 +#define HAL_USE_I2C                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the I2S subsystem.
 + */
 +#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__)
 +#define HAL_USE_I2S                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the ICU subsystem.
 + */
 +#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
 +#define HAL_USE_ICU                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the MAC subsystem.
 + */
 +#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
 +#define HAL_USE_MAC                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the MMC_SPI subsystem.
 + */
 +#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
 +#define HAL_USE_MMC_SPI             FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the PWM subsystem.
 + */
 +#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
 +#define HAL_USE_PWM                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the RTC subsystem.
 + */
 +#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
 +#define HAL_USE_RTC                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the SDC subsystem.
 + */
 +#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
 +#define HAL_USE_SDC                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the SERIAL subsystem.
 + */
 +#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
 +#define HAL_USE_SERIAL              TRUE
 +#endif
 +
 +/**
 + * @brief   Enables the SERIAL over USB subsystem.
 + */
 +#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
 +#define HAL_USE_SERIAL_USB          FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the SPI subsystem.
 + */
 +#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
 +#define HAL_USE_SPI                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the UART subsystem.
 + */
 +#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
 +#define HAL_USE_UART                FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the USB subsystem.
 + */
 +#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
 +#define HAL_USE_USB                 FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the WDG subsystem.
 + */
 +#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__)
 +#define HAL_USE_WDG                 FALSE
 +#endif
 +
 +/*===========================================================================*/
 +/* ADC driver related settings.                                              */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Enables synchronous APIs.
 + * @note    Disabling this option saves both code and data space.
 + */
 +#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
 +#define ADC_USE_WAIT                TRUE
 +#endif
 +
 +/**
 + * @brief   Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
 + * @note    Disabling this option saves both code and data space.
 + */
 +#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
 +#define ADC_USE_MUTUAL_EXCLUSION    TRUE
 +#endif
 +
 +/*===========================================================================*/
 +/* CAN driver related settings.                                              */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Sleep mode related APIs inclusion switch.
 + */
 +#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
 +#define CAN_USE_SLEEP_MODE          FALSE
 +#endif
 +
 +/*===========================================================================*/
 +/* I2C driver related settings.                                              */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Enables the mutual exclusion APIs on the I2C bus.
 + */
 +#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
 +#define I2C_USE_MUTUAL_EXCLUSION    FALSE
 +#endif
 +
 +/*===========================================================================*/
 +/* MAC driver related settings.                                              */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Enables an event sources for incoming packets.
 + */
 +#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
 +#define MAC_USE_ZERO_COPY           FALSE
 +#endif
 +
 +/**
 + * @brief   Enables an event sources for incoming packets.
 + */
 +#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
 +#define MAC_USE_EVENTS              FALSE
 +#endif
 +
 +/*===========================================================================*/
 +/* MMC_SPI driver related settings.                                          */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Delays insertions.
 + * @details If enabled this options inserts delays into the MMC waiting
 + *          routines releasing some extra CPU time for the threads with
 + *          lower priority, this may slow down the driver a bit however.
 + *          This option is recommended also if the SPI driver does not
 + *          use a DMA channel and heavily loads the CPU.
 + */
 +#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
 +#define MMC_NICE_WAITING            FALSE
 +#endif
 +
 +/*===========================================================================*/
 +/* SDC driver related settings.                                              */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Number of initialization attempts before rejecting the card.
 + * @note    Attempts are performed at 10mS intervals.
 + */
 +#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
 +#define SDC_INIT_RETRY              100
 +#endif
 +
 +/**
 + * @brief   Include support for MMC cards.
 + * @note    MMC support is not yet implemented so this option must be kept
 + *          at @p FALSE.
 + */
 +#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
 +#define SDC_MMC_SUPPORT             FALSE
 +#endif
 +
 +/**
 + * @brief   Delays insertions.
 + * @details If enabled this options inserts delays into the MMC waiting
 + *          routines releasing some extra CPU time for the threads with
 + *          lower priority, this may slow down the driver a bit however.
 + */
 +#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
 +#define SDC_NICE_WAITING            FALSE
 +#endif
 +
 +/*===========================================================================*/
 +/* SERIAL driver related settings.                                           */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Default bit rate.
 + * @details Configuration parameter, this is the baud rate selected for the
 + *          default configuration.
 + */
 +#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
 +#define SERIAL_DEFAULT_BITRATE      38400
 +#endif
 +
 +/**
 + * @brief   Serial buffers size.
 + * @details Configuration parameter, you can change the depth of the queue
 + *          buffers depending on the requirements of your application.
 + * @note    The default is 16 bytes for both the transmission and receive
 + *          buffers.
 + */
 +#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
 +#define SERIAL_BUFFERS_SIZE         16
 +#endif
 +
 +/*===========================================================================*/
 +/* SERIAL_USB driver related setting.                                        */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Serial over USB buffers size.
 + * @details Configuration parameter, the buffer size must be a multiple of
 + *          the USB data endpoint maximum packet size.
 + * @note    The default is 256 bytes for both the transmission and receive
 + *          buffers.
 + */
 +#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
 +#define SERIAL_USB_BUFFERS_SIZE     256
 +#endif
 +
 +/**
 + * @brief   Serial over USB number of buffers.
 + * @note    The default is 2 buffers.
 + */
 +#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__)
 +#define SERIAL_USB_BUFFERS_NUMBER   2
 +#endif
 +
 +/*===========================================================================*/
 +/* SPI driver related settings.                                              */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Enables synchronous APIs.
 + * @note    Disabling this option saves both code and data space.
 + */
 +#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
 +#define SPI_USE_WAIT                TRUE
 +#endif
 +
 +/**
 + * @brief   Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
 + * @note    Disabling this option saves both code and data space.
 + */
 +#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
 +#define SPI_USE_MUTUAL_EXCLUSION    FALSE
 +#endif
 +
 +/*===========================================================================*/
 +/* UART driver related settings.                                             */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Enables synchronous APIs.
 + * @note    Disabling this option saves both code and data space.
 + */
 +#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
 +#define UART_USE_WAIT               FALSE
 +#endif
 +
 +/**
 + * @brief   Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
 + * @note    Disabling this option saves both code and data space.
 + */
 +#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
 +#define UART_USE_MUTUAL_EXCLUSION   FALSE
 +#endif
 +
 +/*===========================================================================*/
 +/* USB driver related settings.                                              */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Enables synchronous APIs.
 + * @note    Disabling this option saves both code and data space.
 + */
 +#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__)
 +#define USB_USE_WAIT                FALSE
 +#endif
 +
 +#endif /* _HALCONF_H_ */
 +
 +/** @} */
 diff --git a/testhal/MSP430X/EXP430FR6989/ADC/main.c b/testhal/MSP430X/EXP430FR6989/ADC/main.c new file mode 100644 index 0000000..06f9a9c --- /dev/null +++ b/testhal/MSP430X/EXP430FR6989/ADC/main.c @@ -0,0 +1,254 @@ +/*
 +    ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
 +
 +    Licensed under the Apache License, Version 2.0 (the "License");
 +    you may not use this file except in compliance with the License.
 +    You may obtain a copy of the License at
 +
 +        http://www.apache.org/licenses/LICENSE-2.0
 +
 +    Unless required by applicable law or agreed to in writing, software
 +    distributed under the License is distributed on an "AS IS" BASIS,
 +    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 +    See the License for the specific language governing permissions and
 +    limitations under the License.
 +*/
 +
 +#include "ch.h"
 +#include "hal.h"
 +#include "string.h"
 +#include "stdio.h" /* eesh */
 +
 +/* Disable watchdog because of lousy startup code in newlib */
 +static void __attribute__((naked, section(".crt_0042disable_watchdog"), used))
 +disable_watchdog(void) {
 +  WDTCTL = WDTPW | WDTHOLD;
 +}
 +
 +const char * start_msg  = "\r\n\r\nExecuting ADC test suite...\r\n";
 +const char * test_1_msg = "\r\nTEST 1: 1 channel, depth 1, no circular\r\n";
 +const char * test_2_msg = "\r\nTEST 2: 1 channel, depth 8, no circular\r\n";
 +const char * test_3_msg = "\r\nTEST 3: 4 channels, depth 1, no circular\r\n";
 +const char * test_4_msg = "\r\nTEST 4: 4 channels, depth 8, no circular\r\n";
 +const char * test_5_msg = "\r\nTEST 5: 1 channel, depth 1, circular\r\n";
 +const char * test_6_msg = "\r\nTEST 6: 1 channel, depth 8, circular\r\n";
 +const char * test_7_msg = "\r\nTEST 7: 4 channel, depth 1, circular\r\n";
 +const char * test_8_msg = "\r\nTEST 8: 4 channel, depth 8, circular\r\n";
 +const char * test_9_msg = "\r\nTEST 9: 1 channel, depth 1, synchronous\r\n";
 +
 +const char * success_string = "\r\nSUCCESS\r\n";
 +const char * fail_string = "\r\nFAILURE\r\n";
 +
 +char out_string[128];
 +const char * raw_fmt_string = "Raw Value: %d\r\n";
 +const char * cooked_fmt_string = "Cooked Value: %d\r\n";
 +const char * chn_fmt_string = "\r\nCHANNEL %d\r\n";
 +
 +uint16_t buffer_margin[72];
 +uint16_t * buffer = buffer_margin + 4;
 +uint8_t depth;
 +uint8_t cb_arg = 0;
 +uint16_t cb_expect;
 +
 +static const int test = 0;
 +
 +ADCConfig config = {
 +};
 +
 +ADCConversionGroup group = {
 +  false, /* circular */
 +  1, /* num_channels */
 +  NULL, /* end_cb */
 +  NULL, /* error_cb */
 +  { 
 +    30, 31, 30, 31, 0, 0, 0, 0,
 +    0, 0, 0, 0, 0, 0, 0, 0,
 +    0, 0, 0, 0, 0, 0, 0, 0,
 +    0, 0, 0, 0, 0, 0, 0, 0
 +  }, /* channels */
 +  MSP430X_ADC_RES_12BIT, /* res */
 +  MSP430X_ADC_SHT_32, /* rate */
 +  MSP430X_ADC_VSS_VREF_BUF, /* ref */
 +  MSP430X_REF_2V5 /* vref_src */
 +};
 +
 +void print(const char * msg) {
 +    
 +  if (!test) {
 +    chnWrite(&SD1, (const uint8_t *)msg, strlen(msg));
 +  }
 +}
 +
 +void adc_callback(ADCDriver * adcp, adcsample_t *buffer, size_t n) {
 +  (void)adcp;
 +  (void)buffer;
 +  (void)n;
 +  
 +  cb_arg++;
 +  
 +  if (adcp->grpp->circular && cb_arg == cb_expect) {
 +    osalSysLockFromISR();
 +    adcStopConversionI(adcp);
 +    osalSysUnlockFromISR();
 +  }
 +}
 +
 +void run_test(const char * test_msg, uint8_t num_channels, uint8_t depth,
 +    bool circular) {
 +  print(test_msg);
 +  
 +  cb_arg = 0;
 +  
 +  group.num_channels = num_channels;
 +  group.circular = circular;
 +  group.end_cb = adc_callback;
 +  
 +  if (depth > 1) cb_expect = 2;
 +  else cb_expect = 1;
 +  if (circular) cb_expect *= 3;
 +  
 +  adcStartConversion(&ADCD1, &group, buffer, depth);
 +  
 +  while (ADCD1.state == ADC_ACTIVE) ;
 +  
 +  
 +  int index = 0;
 +  for (int j = 0; j < depth; j++) {
 +    for (int i = 0; i < group.num_channels; i++) {
 +      index = i + (j * group.num_channels);
 +      sniprintf(out_string, 128, chn_fmt_string, group.channels[i]);
 +      print(out_string);
 +      
 +      sniprintf(out_string, 128, raw_fmt_string, buffer[index]); 
 +      print(out_string);
 +      
 +      if (group.channels[i] == 30) { /* internal temp sensor */
 +        buffer[index] = adcMSP430XAdjustTemp(&group, buffer[index]);
 +      }
 +      else {
 +        buffer[index] = adcMSP430XAdjustResult(&group, buffer[index]);
 +      }
 +      
 +      sniprintf(out_string, 128, cooked_fmt_string, buffer[index]); 
 +      print(out_string);
 +    }
 +  }
 +  
 +  if (cb_arg == cb_expect) {
 +    print(success_string);
 +  }
 +  else {
 +    print(fail_string);
 +  }
 +}
 +
 +/*
 + * Thread 2.
 + */
 +THD_WORKING_AREA(waThread1, 4096);
 +THD_FUNCTION(Thread1, arg) {
 +
 +  (void)arg;
 +
 +  /*
 +   * Activate the serial driver 0 using the driver default configuration.
 +   */
 +  sdStart(&SD1, NULL);
 +
 +  /* Activate the ADC driver 1 using its config */
 +  adcStart(&ADCD1, &config);
 +
 +  while (chnGetTimeout(&SD1, TIME_INFINITE)) {
 +    print(start_msg);
 +    chThdSleepMilliseconds(2000);
 +
 +    /* Test 1 - 1ch1d, no circular */
 +    run_test(test_1_msg, 1, 1, false);
 +    
 +    /* Test 2 - 1ch8d, no circular */
 +    run_test(test_2_msg, 1, 8, false);
 +    
 +    /* Test 3 - 4chd1, no circular */
 +    run_test(test_3_msg, 4, 1, false);
 +    
 +    /* Test 4 - 4ch8d, no circular */
 +    run_test(test_4_msg, 4, 8, false);
 +    
 +    /* Test 5 - 1ch1d, circular */
 +    run_test(test_5_msg, 1, 1, true);
 +    
 +    /* Test 6 - 1ch8d, circular */
 +    run_test(test_6_msg, 1, 8, true);
 +    
 +    /* Test 7 - 4ch1d, circular */
 +    run_test(test_7_msg, 4, 1, true);
 +    
 +    /* Test 8 - 4ch8d, circular */
 +    run_test(test_8_msg, 4, 8, true);
 +    
 +    /* Test 9 - 1ch1d, synchronous */
 +    print(test_9_msg);
 +    cb_arg = 0;
 +    
 +    group.num_channels = 1;
 +    group.circular = false;
 +    group.end_cb = adc_callback;
 +    
 +    cb_expect = 1;
 +    
 +    adcConvert(&ADCD1, &group, buffer, 1);
 +    
 +    while (ADCD1.state == ADC_ACTIVE) ;
 +    
 +    sniprintf(out_string, 128, chn_fmt_string, group.channels[0]);
 +    print(out_string);
 +    
 +    sniprintf(out_string, 128, raw_fmt_string, buffer[0]); 
 +    print(out_string);
 +    
 +    buffer[0] = adcMSP430XAdjustTemp(&group, buffer[0]);
 +    
 +    sniprintf(out_string, 128, cooked_fmt_string, buffer[0]); 
 +    print(out_string);
 +    
 +    if (cb_arg == cb_expect) {
 +      print(success_string);
 +    }
 +    else {
 +      print(fail_string);
 +    }
 +  }
 +}
 +
 +/*
 + * Threads static table, one entry per thread. The number of entries must
 + * match NIL_CFG_NUM_THREADS.
 + */
 +THD_TABLE_BEGIN
 +  THD_TABLE_ENTRY(waThread1, "adc_test", Thread1, NULL)
 +THD_TABLE_END
 +
 +/*
 + * Application entry point.
 + */
 +int main(void) {
 +
 +  /*
 +   * System initializations.
 +   * - HAL initialization, this also initializes the configured device drivers
 +   *   and performs the board-specific initializations.
 +   * - Kernel initialization, the main() function becomes a thread and the
 +   *   RTOS is active.
 +   */
 +  WDTCTL = WDTPW | WDTHOLD;
 +
 +  halInit();
 +  chSysInit();
 +
 +  /* This is now the idle thread loop, you may perform here a low priority
 +     task but you must never try to sleep or wait in this loop. Note that
 +     this tasks runs at the lowest priority level so any instruction added
 +     here will be executed after all other tasks have been started.*/
 +  while (true) {
 +  }
 +}
 diff --git a/testhal/MSP430X/EXP430FR6989/ADC/mcuconf.h b/testhal/MSP430X/EXP430FR6989/ADC/mcuconf.h new file mode 100644 index 0000000..bcb0c69 --- /dev/null +++ b/testhal/MSP430X/EXP430FR6989/ADC/mcuconf.h @@ -0,0 +1,68 @@ +/*
 +    ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
 +
 +    Licensed under the Apache License, Version 2.0 (the "License");
 +    you may not use this file except in compliance with the License.
 +    You may obtain a copy of the License at
 +
 +        http://www.apache.org/licenses/LICENSE-2.0
 +
 +    Unless required by applicable law or agreed to in writing, software
 +    distributed under the License is distributed on an "AS IS" BASIS,
 +    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 +    See the License for the specific language governing permissions and
 +    limitations under the License.
 +*/
 +
 +#ifndef MCUCONF_H
 +#define MCUCONF_H
 +
 +/*
 + * MSP430X drivers configuration.
 + * The following settings override the default settings present in
 + * the various device driver implementation headers.
 + * Note that the settings for each driver only have effect if the driver
 + * is enabled in halconf.h.
 + * 
 + */
 +
 +#define MSP430X_MCUCONF
 +
 +/* HAL driver system settings */
 +#define MSP430X_ACLK_SRC MSP430X_VLOCLK
 +#define MSP430X_LFXTCLK_FREQ 0
 +#define MSP430X_HFXTCLK_FREQ 0
 +#define MSP430X_DCOCLK_FREQ 8000000
 +#define MSP430X_MCLK_DIV 1
 +#define MSP430X_SMCLK_DIV 32
 +
 +/*
 + * SERIAL driver system settings.
 + */
 +#define MSP430X_SERIAL_USE_USART1         TRUE
 +#define MSP430X_USART1_CLK_SRC            MSP430X_SMCLK_SRC
 +#define MSP430X_SERIAL_USE_USART0         FALSE
 +#define MSP430X_SERIAL_USE_USART2         FALSE
 +#define MSP430X_SERIAL_USE_USART3         FALSE
 +
 +/*
 + * ST driver system settings.
 + */
 +#define MSP430X_ST_CLK_SRC MSP430X_SMCLK_SRC
 +#define MSP430X_ST_TIMER_TYPE B
 +#define MSP430X_ST_TIMER_INDEX 0
 +
 +/*
 + * SPI driver system settings.
 + */
 +#define MSP430X_SPI_USE_SPIA1 FALSE
 +#define MSP430X_SPI_USE_SPIB0 FALSE
 +#define MSP430X_SPI_EXCLUSIVE_DMA FALSE
 +
 +/*
 + * ADC driver system settings
 + */
 +#define MSP430X_ADC_EXCLUSIVE_DMA FALSE
 +#define MSP430X_ADC1_FREQ 5000000 / 256
 +
 +#endif /* _MCUCONF_H_ */
 diff --git a/testhal/MSP430X/EXP430FR6989/ADC/msp_vectors.c b/testhal/MSP430X/EXP430FR6989/ADC/msp_vectors.c new file mode 100644 index 0000000..24e2a11 --- /dev/null +++ b/testhal/MSP430X/EXP430FR6989/ADC/msp_vectors.c @@ -0,0 +1,286 @@ +#include <msp430.h>
 +
 +__attribute__((interrupt(1)))
 +void Vector1(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(2)))
 +void Vector2(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(3)))
 +void Vector3(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(4)))
 +void Vector4(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(5)))
 +void Vector5(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(6)))
 +void Vector6(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(7)))
 +void Vector7(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(8)))
 +void Vector8(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(9)))
 +void Vector9(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(10)))
 +void Vector10(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(11)))
 +void Vector11(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(12)))
 +void Vector12(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(13)))
 +void Vector13(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(14)))
 +void Vector14(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(15)))
 +void Vector15(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(16)))
 +void Vector16(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(17)))
 +void Vector17(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(18)))
 +void Vector18(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(19)))
 +void Vector19(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(20)))
 +void Vector20(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(21)))
 +void Vector21(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(22)))
 +void Vector22(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(23)))
 +void Vector23(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(24)))
 +void Vector24(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(25)))
 +void Vector25(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(26)))
 +void Vector26(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(27)))
 +void Vector27(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(28)))
 +void Vector28(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(29)))
 +void Vector29(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(30)))
 +void Vector30(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(33)))
 +void Vector33(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(34)))
 +void Vector34(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(36)))
 +void Vector36(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(37)))
 +void Vector37(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(39)))
 +void Vector39(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(40)))
 +void Vector40(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(42)))
 +void Vector42(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(44)))
 +void Vector44(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(45)))
 +void Vector45(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(47)))
 +void Vector47(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(48)))
 +void Vector48(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(49)))
 +void Vector49(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(50)))
 +void Vector50(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(51)))
 +void Vector51(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(53)))
 +void Vector53(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(54)))
 +void Vector54(void) {
 +
 +  while (1) {
 +  }
 +}
 +__attribute__((interrupt(55)))
 +void Vector55(void) {
 +
 +  while (1) {
 +  }
 +}
 +
 +
 | 
