From 456702ee87b1adbbb559778aafe98c349700178a Mon Sep 17 00:00:00 2001 From: Andrew Wygle Date: Sun, 22 May 2016 12:41:42 -0700 Subject: [PATCH 1/2] Cleaned up MSP430X port to match recent changes to ChibiOS mainline. Also fixed a couple of bugs identified as part of the refresh. --- os/common/ports/MSP430X/chcore.h | 9 ++++-- os/hal/ports/MSP430X/hal_dma_lld.c | 4 ++- os/hal/ports/MSP430X/hal_serial_lld.c | 1 + os/hal/ports/MSP430X/hal_spi_lld.c | 10 +++---- os/hal/ports/MSP430X/hal_spi_lld.h | 2 +- testhal/MSP430X/EXP430FR5969/SPI/main.c | 40 ++++++++++++++++++------- 6 files changed, 46 insertions(+), 20 deletions(-) diff --git a/os/common/ports/MSP430X/chcore.h b/os/common/ports/MSP430X/chcore.h index 09f87c4c..3683c1d4 100644 --- a/os/common/ports/MSP430X/chcore.h +++ b/os/common/ports/MSP430X/chcore.h @@ -232,14 +232,19 @@ struct port_context { * @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() { \ + _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) /** diff --git a/os/hal/ports/MSP430X/hal_dma_lld.c b/os/hal/ports/MSP430X/hal_dma_lld.c index 43e1d6cc..2e17afa3 100644 --- a/os/hal/ports/MSP430X/hal_dma_lld.c +++ b/os/hal/ports/MSP430X/hal_dma_lld.c @@ -89,7 +89,9 @@ PORT_IRQ_HANDLER(DMA_VECTOR) { if (index < MSP430X_DMA_CHANNELS) { #if CH_CFG_USE_SEMAPHORES + chSysLockFromISR(); chSemSignalI(&dma_lock); + chSysUnlockFromISR(); #endif msp430x_dma_cb_t * cb = &callbacks[index]; @@ -129,7 +131,7 @@ void dmaInit(void) { 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); + msg_t semresult = chSemWaitTimeoutS(&dma_lock, timeout); if (semresult != MSG_OK) return true; #endif diff --git a/os/hal/ports/MSP430X/hal_serial_lld.c b/os/hal/ports/MSP430X/hal_serial_lld.c index 0d9aa1cd..8f226500 100644 --- a/os/hal/ports/MSP430X/hal_serial_lld.c +++ b/os/hal/ports/MSP430X/hal_serial_lld.c @@ -374,6 +374,7 @@ PORT_IRQ_HANDLER(USCI_A0_VECTOR) { if (oqIsEmptyI(&SD0.oqueue)) chnAddFlagsI(&SD0, CHN_TRANSMISSION_END); UCA0IE &= ~UCTXCPTIE; + osalSysUnlockFromISR(); break; default: /* other interrupts */ diff --git a/os/hal/ports/MSP430X/hal_spi_lld.c b/os/hal/ports/MSP430X/hal_spi_lld.c index 70a357e3..37684878 100644 --- a/os/hal/ports/MSP430X/hal_spi_lld.c +++ b/os/hal/ports/MSP430X/hal_spi_lld.c @@ -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); } /** @@ -561,15 +562,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..0ca4c678 100644 --- a/os/hal/ports/MSP430X/hal_spi_lld.h +++ b/os/hal/ports/MSP430X/hal_spi_lld.h @@ -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/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; From d9ee72504f248b7f9edae382ff941453301bf5ad Mon Sep 17 00:00:00 2001 From: Andrew Wygle Date: Sat, 4 Jun 2016 18:26:39 -0700 Subject: [PATCH 2/2] Adds ADC12 support to MSP430X port. Adds support for the MSP430X's 12-bit ADC peripheral, as well as reasonably complete testing of same. Also includes fixes for several bugs and cleanup of the DMA peripheral, which used ch calls rather than osal calls and was unclear about what contexts its methods could be called from. --- os/common/ports/MSP430X/chcore.c | 7 + os/common/ports/MSP430X/chcore.h | 11 +- os/hal/boards/EXP430FR5969/board.c | 6 +- os/hal/boards/EXP430FR5969/board.h | 6 - os/hal/boards/EXP430FR6989/board.c | 12 +- os/hal/boards/EXP430FR6989/board.h | 14 +- os/hal/ports/MSP430X/hal_adc_lld.c | 354 ++++++++++++ os/hal/ports/MSP430X/hal_adc_lld.h | 516 ++++++++++++++++++ os/hal/ports/MSP430X/hal_dma_lld.c | 233 ++++---- os/hal/ports/MSP430X/hal_dma_lld.h | 4 +- os/hal/ports/MSP430X/hal_lld.c | 4 + os/hal/ports/MSP430X/hal_lld.h | 2 + os/hal/ports/MSP430X/hal_serial_lld.c | 15 +- os/hal/ports/MSP430X/hal_spi_lld.c | 24 +- os/hal/ports/MSP430X/hal_spi_lld.h | 2 +- os/hal/ports/MSP430X/platform.mk | 3 +- testhal/MSP430X/EXP430FR5969/ADC/Makefile | 206 +++++++ testhal/MSP430X/EXP430FR5969/ADC/chconf.h | 274 ++++++++++ testhal/MSP430X/EXP430FR5969/ADC/halconf.h | 388 +++++++++++++ testhal/MSP430X/EXP430FR5969/ADC/main.c | 270 +++++++++ testhal/MSP430X/EXP430FR5969/ADC/mcuconf.h | 68 +++ .../MSP430X/EXP430FR5969/ADC/msp_vectors.c | 286 ++++++++++ testhal/MSP430X/EXP430FR5969/DMA/main.c | 74 ++- .../MSP430X/EXP430FR5969/DMA/msp_vectors.c | 22 - .../MSP430X/EXP430FR5969/SPI/msp_vectors.c | 24 - testhal/MSP430X/EXP430FR6989/ADC/Makefile | 206 +++++++ testhal/MSP430X/EXP430FR6989/ADC/chconf.h | 274 ++++++++++ testhal/MSP430X/EXP430FR6989/ADC/halconf.h | 388 +++++++++++++ testhal/MSP430X/EXP430FR6989/ADC/main.c | 254 +++++++++ testhal/MSP430X/EXP430FR6989/ADC/mcuconf.h | 68 +++ .../MSP430X/EXP430FR6989/ADC/msp_vectors.c | 286 ++++++++++ 31 files changed, 4068 insertions(+), 233 deletions(-) create mode 100644 os/hal/ports/MSP430X/hal_adc_lld.c create mode 100644 os/hal/ports/MSP430X/hal_adc_lld.h create mode 100644 testhal/MSP430X/EXP430FR5969/ADC/Makefile create mode 100644 testhal/MSP430X/EXP430FR5969/ADC/chconf.h create mode 100644 testhal/MSP430X/EXP430FR5969/ADC/halconf.h create mode 100644 testhal/MSP430X/EXP430FR5969/ADC/main.c create mode 100644 testhal/MSP430X/EXP430FR5969/ADC/mcuconf.h create mode 100644 testhal/MSP430X/EXP430FR5969/ADC/msp_vectors.c create mode 100644 testhal/MSP430X/EXP430FR6989/ADC/Makefile create mode 100644 testhal/MSP430X/EXP430FR6989/ADC/chconf.h create mode 100644 testhal/MSP430X/EXP430FR6989/ADC/halconf.h create mode 100644 testhal/MSP430X/EXP430FR6989/ADC/main.c create mode 100644 testhal/MSP430X/EXP430FR6989/ADC/mcuconf.h create mode 100644 testhal/MSP430X/EXP430FR6989/ADC/msp_vectors.c 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 3683c1d4..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,7 +227,7 @@ struct port_context { * @details This macro must be inserted at the start of all IRQ handlers * enabled to invoke system APIs. */ -#define PORT_IRQ_PROLOGUE() +#define PORT_IRQ_PROLOGUE() __msp430x_in_isr = true; /** * @brief IRQ epilogue code. @@ -233,6 +235,7 @@ struct port_context { * enabled to invoke system APIs. */ #define PORT_IRQ_EPILOGUE() { \ + __msp430x_in_isr = false; \ _dbg_check_lock(); \ if (chSchIsPreemptionRequired()) \ chSchDoReschedule(); \ @@ -298,7 +301,7 @@ extern "C" { * @brief Port-related initialization code. */ static inline void port_init(void) { - + __msp430x_in_isr = false; } /** @@ -333,9 +336,7 @@ static inline bool port_irq_enabled(syssts_t sts) { * @retval true running in ISR mode. */ static inline bool port_is_isr_context(void) { - /* Efficiency would be enhanced by not doing this, - * because of implementation details */ - return __get_SR_register() & GIE; + return __msp430x_in_isr; } /** diff --git a/os/hal/boards/EXP430FR5969/board.c b/os/hal/boards/EXP430FR5969/board.c index 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 2e17afa3..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,11 +87,9 @@ PORT_IRQ_HANDLER(DMA_VECTOR) { index = (DMAIV >> 1) - 1; if (index < MSP430X_DMA_CHANNELS) { -#if CH_CFG_USE_SEMAPHORES - chSysLockFromISR(); - chSemSignalI(&dma_lock); - chSysUnlockFromISR(); -#endif + osalSysLockFromISR(); + osalThreadDequeueNextI(&dma_queue, MSG_OK); + osalSysUnlockFromISR(); msp430x_dma_cb_t * cb = &callbacks[index]; @@ -115,9 +112,7 @@ PORT_IRQ_HANDLER(DMA_VECTOR) { * @init */ void dmaInit(void) { -#if CH_CFG_USE_SEMAPHORES - chSemObjectInit(&dma_lock, MSP430X_DMA_CHANNELS); -#endif + osalThreadQueueObjectInit(&dma_queue); } /** @@ -127,134 +122,124 @@ void dmaInit(void) { * semaphores are enabled, the calling thread will sleep until a * channel is available or the request times out. If semaphores are * disabled, the calling thread will busy-wait instead of sleeping. + * + * @sclass */ -bool dmaRequest(msp430x_dma_req_t * request, systime_t timeout) { -/* Check if a DMA channel is available */ -#if CH_CFG_USE_SEMAPHORES - msg_t semresult = chSemWaitTimeoutS(&dma_lock, timeout); - if (semresult != MSG_OK) +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 8f226500..feb00ac3 100644 --- a/os/hal/ports/MSP430X/hal_serial_lld.c +++ b/os/hal/ports/MSP430X/hal_serial_lld.c @@ -378,8 +378,7 @@ PORT_IRQ_HANDLER(USCI_A0_VECTOR) { break; default: /* other interrupts */ - while (1) - ; + osalDbgAssert(false, "unhandled serial interrupt"); break; } @@ -433,11 +432,11 @@ PORT_IRQ_HANDLER(USCI_A1_VECTOR) { if (oqIsEmptyI(&SD1.oqueue)) chnAddFlagsI(&SD1, CHN_TRANSMISSION_END); UCA1IE &= ~UCTXCPTIE; + osalSysUnlockFromISR(); break; default: /* other interrupts */ - while (1) - ; + osalDbgAssert(false, "unhandled serial interrupt"); break; } @@ -491,11 +490,11 @@ PORT_IRQ_HANDLER(USCI_A2_VECTOR) { if (oqIsEmptyI(&SD2.oqueue)) chnAddFlagsI(&SD2, CHN_TRANSMISSION_END); UCA2IE &= ~UCTXCPTIE; + osalSysUnlockFromISR(); break; default: /* other interrupts */ - while (1) - ; + osalDbgAssert(false, "unhandled serial interrupt"); break; } @@ -549,11 +548,11 @@ PORT_IRQ_HANDLER(USCI_A3_VECTOR) { if (oqIsEmptyI(&SD3.oqueue)) chnAddFlagsI(&SD3, CHN_TRANSMISSION_END); UCA3IE &= ~UCTXCPTIE; + osalSysUnlockFromISR(); break; default: /* other interrupts */ - while (1) - ; + osalDbgAssert(false, "unhandled serial interrupt"); break; } diff --git a/os/hal/ports/MSP430X/hal_spi_lld.c b/os/hal/ports/MSP430X/hal_spi_lld.c index 37684878..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 */ @@ -407,8 +407,12 @@ void spi_lld_stop(SPIDriver * spip) { if (spip->state == SPI_READY) { /* Disables the peripheral.*/ #if MSP430X_SPI_EXCLUSIVE_DMA == TRUE - dmaRelease(&(spip->dmatx)); - dmaRelease(&(spip->dmarx)); + if (spip->config->dmatx_index < MSP430X_DMA_CHANNELS) { + dmaRelease(&(spip->dmatx)); + } + if (spip->config->dmarx_index < MSP430X_DMA_CHANNELS) { + dmaRelease(&(spip->dmarx)); + } #endif spip->regs->ctlw0 = UCSWRST; } diff --git a/os/hal/ports/MSP430X/hal_spi_lld.h b/os/hal/ports/MSP430X/hal_spi_lld.h index 0ca4c678..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 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/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) { + } +} + +