diff --git a/os/common/ports/MSP430X/chcore.c b/os/common/ports/MSP430X/chcore.c index 7a8d7f27..b9001b09 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 09f87c4c..9e1efa81 100644 --- a/os/common/ports/MSP430X/chcore.h +++ b/os/common/ports/MSP430X/chcore.h @@ -28,6 +28,8 @@ #include #include +extern bool __msp430x_in_isr; + /*===========================================================================*/ /* Module constants. */ /*===========================================================================*/ @@ -225,21 +227,27 @@ 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. * @details This macro must be inserted at the end of all IRQ handlers * enabled to invoke system APIs. */ -#define PORT_IRQ_EPILOGUE() chSchRescheduleS() +#define PORT_IRQ_EPILOGUE() { \ + __msp430x_in_isr = false; \ + _dbg_check_lock(); \ + if (chSchIsPreemptionRequired()) \ + chSchDoReschedule(); \ + _dbg_check_unlock(); \ +} /** * @brief IRQ handler function declaration. * @note @p id can be a function name or a vector number depending on the * port implementation. */ -#define PORT_IRQ_HANDLER(id) __attribute__ ((interrupt(id))) \ +#define PORT_IRQ_HANDLER(id) __attribute__ ((interrupt(id))) \ void ISR_ ## id (void) /** @@ -293,7 +301,7 @@ extern "C" { * @brief Port-related initialization code. */ static inline void port_init(void) { - + __msp430x_in_isr = false; } /** @@ -328,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 ac48ba06..0643cce6 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 97103d3c..3abe1cce 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 a6836cf0..475a2ea9 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 83b8fbb6..d5afe297 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 00000000..42d3cbec --- /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 00000000..1cca36b1 --- /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 43e1d6cc..82bf39f3 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,9 +87,9 @@ PORT_IRQ_HANDLER(DMA_VECTOR) { index = (DMAIV >> 1) - 1; if (index < MSP430X_DMA_CHANNELS) { -#if CH_CFG_USE_SEMAPHORES - chSemSignalI(&dma_lock); -#endif + osalSysLockFromISR(); + osalThreadDequeueNextI(&dma_queue, MSG_OK); + osalSysUnlockFromISR(); msp430x_dma_cb_t * cb = &callbacks[index]; @@ -113,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); } /** @@ -125,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 = chSemWaitTimeout(&dma_lock, timeout); - if (semresult != MSG_OK) +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; + } + } + + /* Make the request */ + init_request(request, i); + + return 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(); + + /* Is the channel already acquired? */ + osalDbgAssert(index < MSP430X_DMA_CHANNELS, "invalid channel index"); + if (dma_channels[index].ctl & DMADT_4) { 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; - } -#endif - - /* Make the request */ - init_request(request, i); - - return false; } - /** - * @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 */ + /* Increment the DMA counter */ + queue_length++; - /* Is the channel already acquired? */ - osalDbgAssert(index < MSP430X_DMA_CHANNELS, "invalid channel index"); - if (dma_channels[index].ctl & DMADT_4) { - return true; - } + while (dma_channels[index].ctl & DMAEN) + ; -/* Increment the DMA counter */ -#if CH_CFG_USE_SEMAPHORES - msg_t semresult = chSemWait(&dma_lock); - if (semresult != MSG_OK) - return true; -#endif + /* 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; - while (dma_channels[index].ctl & DMAEN) - ; + channel->registers = dma_channels + index; + channel->index = index; + channel->cb = callbacks + index; + + return false; +} - dma_trigger_set(index, DMA_TRIGGER_MNEM(DMAREQ)); - dma_channels[index].sz = 0; - dma_channels[index].ctl = DMAEN | DMAABORT | DMADT_4; +/** + * @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) { - channel->registers = dma_channels + index; - channel->index = index; - channel->cb = callbacks + index; + dma_trigger_set(channel->index, request->trigger); + /**(channel->ctl) = request->trigger;*/ - return false; - } + channel->cb->callback = request->callback.callback; + channel->cb->args = request->callback.args; - /** - * @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) { + 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 */ +} - dma_trigger_set(channel->index, request->trigger); - /**(channel->ctl) = request->trigger;*/ +/** + * @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; - channel->cb->callback = request->callback.callback; - channel->cb->args = request->callback.args; + sts = osalSysGetStatusAndLockX(); + osalDbgCheck(channel != NULL); - 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(); - } + /* Release the channel in an idle mode */ + channel->registers->ctl = DMAABORT; - /** - * @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 - } + /* 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 d1495d26..f558e789 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 872fe97c..812a0cf7 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 9549453e..62f07e90 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 0d9aa1cd..feb00ac3 100644 --- a/os/hal/ports/MSP430X/hal_serial_lld.c +++ b/os/hal/ports/MSP430X/hal_serial_lld.c @@ -374,11 +374,11 @@ PORT_IRQ_HANDLER(USCI_A0_VECTOR) { if (oqIsEmptyI(&SD0.oqueue)) chnAddFlagsI(&SD0, CHN_TRANSMISSION_END); UCA0IE &= ~UCTXCPTIE; + osalSysUnlockFromISR(); break; default: /* other interrupts */ - while (1) - ; + osalDbgAssert(false, "unhandled serial interrupt"); break; } @@ -432,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; } @@ -490,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; } @@ -548,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 70a357e3..3a54b1e1 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 */ @@ -388,10 +388,11 @@ void spi_lld_start(SPIDriver * spip) { spip->regs->ctlw0 = UCSWRST; spip->regs->brw = brw; spip->regs->ctlw0 = - (spip->config->spi_mode << 14) | (spip->config->bit_order << 13) | + ((spip->config->spi_mode ^ 0x02) << 14) | (spip->config->bit_order << 13) | (spip->config->data_size << 12) | (UCMST) | ((spip->config->ss_line ? 0 : 2) << 9) | (UCSYNC) | (ssel) | (UCSTEM); *(spip->ifg) = 0; + spi_lld_unselect(spip); } /** @@ -406,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; } @@ -561,15 +566,12 @@ void spi_lld_receive(SPIDriver * spip, size_t n, void * rxbuf) { * @param[in] frame the data frame to send over the SPI bus * @return The received data frame from the SPI bus. */ -uint16_t spi_lld_polled_exchange(SPIDriver * spip, uint16_t frame) { +uint8_t spi_lld_polled_exchange(SPIDriver * spip, uint8_t frame) { - osalDbgAssert(!(frame & 0xFF00U), "16-bit transfers not supported"); - - while (!(*(spip->ifg) & UCTXIFG)) - ; spip->regs->txbuf = frame; while (!(*(spip->ifg) & UCRXIFG)) ; + *(spip->ifg) &= ~(UCRXIFG | UCTXIFG); return spip->regs->rxbuf; } diff --git a/os/hal/ports/MSP430X/hal_spi_lld.h b/os/hal/ports/MSP430X/hal_spi_lld.h index ebf14c81..949a8a09 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 @@ -630,7 +630,7 @@ extern "C" { const void *txbuf, void *rxbuf); void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf); void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf); - uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame); + uint8_t spi_lld_polled_exchange(SPIDriver *spip, uint8_t frame); #ifdef __cplusplus } #endif diff --git a/os/hal/ports/MSP430X/platform.mk b/os/hal/ports/MSP430X/platform.mk index 832814bb..627a2f05 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 00000000..cf81f18b --- /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 00000000..3b7a8e1d --- /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 00000000..2982a631 --- /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 00000000..8a530ecf --- /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 00000000..70e29ffb --- /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 00000000..d12ed531 --- /dev/null +++ b/testhal/MSP430X/EXP430FR5969/ADC/msp_vectors.c @@ -0,0 +1,286 @@ +#include + +__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 1929af17..757eedcf 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 8968fb99..f5ad4b6a 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/main.c b/testhal/MSP430X/EXP430FR5969/SPI/main.c index 17f5c86d..8d281986 100644 --- a/testhal/MSP430X/EXP430FR5969/SPI/main.c +++ b/testhal/MSP430X/EXP430FR5969/SPI/main.c @@ -34,11 +34,12 @@ const char * test_5_msg = "TEST 5: spiIgnore\r\n"; const char * test_6_msg = "TEST 6: spiExchange\r\n"; const char * test_7_msg = "TEST 7: spiSend\r\n"; const char * test_8_msg = "TEST 8: spiReceive\r\n"; -const char * test_9_msg = "TEST 9: spiStartExchange with exclusive DMA\r\n"; -const char * test_10_msg = - "TEST 10: spiStartExchange with exclusive DMA for TX\r\n"; +const char * test_9_msg = "TEST 9: spiPolledExchange\r\n"; +const char * test_10_msg = "TEST 10: spiStartExchange with exclusive DMA\r\n"; const char * test_11_msg = - "TEST 11: spiStartExchange with exclusive DMA for RX\r\n"; + "TEST 11: spiStartExchange with exclusive DMA for TX\r\n"; +const char * test_12_msg = + "TEST 12: spiStartExchange with exclusive DMA for RX\r\n"; const char * succeed_string = "SUCCESS\r\n\r\n"; const char * fail_string = "FAILURE\r\n\r\n"; @@ -270,6 +271,25 @@ THD_FUNCTION(Thread1, arg) { else { chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string)); } + + /* Test 9 - spiPolledExchange */ + chnWrite(&SD0, (const uint8_t *)test_9_msg, strlen(test_9_msg)); + strcpy(outstring, "After SPI test \r\n"); + strcpy(instring, "Before SPI test \r\n"); + if (strcmp("Before SPI test \r\n", instring) || + strcmp("After SPI test \r\n", outstring)) { + chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); + } + spiSelect(&SPIDB0); + outstring[0] = spiPolledExchange(&SPIDB0, instring[0]); + spiUnselect(&SPIDB0); + if (strcmp("Bfter SPI test \r\n", outstring) || + strcmp("Before SPI test \r\n", instring)) { + chnWrite(&SD0, (const uint8_t *)fail_string, strlen(fail_string)); + } + else { + chnWrite(&SD0, (const uint8_t *)succeed_string, strlen(succeed_string)); + } /* Reconfigure SPIDA1 to use exclusive DMA for both */ spiStop(&SPIDA1); @@ -278,8 +298,8 @@ THD_FUNCTION(Thread1, arg) { SPIDA1_config.spi_mode = 1; /* because why not get coverage */ spiStart(&SPIDA1, &SPIDA1_config); - /* Test 9 - spiStartExchange with exclusive DMA */ - chnWrite(&SD0, (const uint8_t *)test_9_msg, strlen(test_9_msg)); + /* Test 10 - spiStartExchange with exclusive DMA */ + chnWrite(&SD0, (const uint8_t *)test_10_msg, strlen(test_10_msg)); strcpy(outstring, "After SPI test \r\n"); strcpy(instring, "Before SPI test \r\n"); cb_arg = 1; @@ -307,8 +327,8 @@ THD_FUNCTION(Thread1, arg) { SPIDA1_config.spi_mode = 2; /* because why not get coverage */ spiStart(&SPIDA1, &SPIDA1_config); - /* Test 10 - spiStartExchange with exclusive DMA for TX */ - chnWrite(&SD0, (const uint8_t *)test_10_msg, strlen(test_10_msg)); + /* Test 11 - spiStartExchange with exclusive DMA for TX */ + chnWrite(&SD0, (const uint8_t *)test_11_msg, strlen(test_11_msg)); strcpy(outstring, "After SPI test \r\n"); strcpy(instring, "Before SPI test \r\n"); cb_arg = 1; @@ -336,8 +356,8 @@ THD_FUNCTION(Thread1, arg) { SPIDA1_config.spi_mode = 3; /* because why not get coverage */ spiStart(&SPIDA1, &SPIDA1_config); - /* Test 11 - spiStartExchange with exclusive DMA for RX */ - chnWrite(&SD0, (const uint8_t *)test_11_msg, strlen(test_11_msg)); + /* Test 12 - spiStartExchange with exclusive DMA for RX */ + chnWrite(&SD0, (const uint8_t *)test_12_msg, strlen(test_12_msg)); strcpy(outstring, "After SPI test \r\n"); strcpy(instring, "Before SPI test \r\n"); cb_arg = 1; diff --git a/testhal/MSP430X/EXP430FR5969/SPI/msp_vectors.c b/testhal/MSP430X/EXP430FR5969/SPI/msp_vectors.c index 8968fb99..c23cbc89 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 00000000..b86021e7 --- /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 00000000..3b7a8e1d --- /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 00000000..2982a631 --- /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 00000000..06f9a9c6 --- /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 00000000..bcb0c69f --- /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 00000000..24e2a118 --- /dev/null +++ b/testhal/MSP430X/EXP430FR6989/ADC/msp_vectors.c @@ -0,0 +1,286 @@ +#include + +__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) { + } +} + +