Merge pull request #236 from alexclewontin/pwm-fix
[NUC123SD4AN0] Barebones PWM module for downstream compatibility
This commit is contained in:
commit
7d6e9b8f23
|
@ -16,7 +16,9 @@
|
|||
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_PAL
|
||||
const PALConfig pal_default_config;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Board-specific initialization code.
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#define NUC123SD4AN0
|
||||
#define BOARD_NAME "NUTINY SDK NUC123 V2.0"
|
||||
|
||||
|
||||
#define NUC123_LSE_BYPASS TRUE
|
||||
/*
|
||||
* Board specific settings.
|
||||
|
|
|
@ -4,9 +4,5 @@ BOARDSRC = $(CHIBIOS_CONTRIB)/os/hal/boards/NUTINY-SDK-NUC123-V2.0/board.c
|
|||
# Required include directories
|
||||
BOARDINC = $(CHIBIOS_CONTRIB)/os/hal/boards/NUTINY-SDK-NUC123-V2.0
|
||||
|
||||
# Define linker script file here, as the linker script is per chip variant, which should
|
||||
# remain constant per board
|
||||
LDSCRIPT = $(STARTUPLD_CONTRIB)/NUC123SD4AN0.ld
|
||||
|
||||
ALLCSRC += $(BOARDSRC)
|
||||
ALLINC += $(BOARDINC)
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
ifeq ($(USE_SMART_BUILD),yes)
|
||||
ifneq ($(findstring HAL_USE_PAL TRUE,$(HALCONF)),)
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/GPIOv1/hal_pal_lld.c
|
||||
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/GPIOv1
|
||||
endif
|
||||
else
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/GPIOv1/hal_pal_lld.c
|
||||
endif
|
||||
|
||||
# ifeq ($(USE_SMART_BUILD),yes)
|
||||
# ifneq ($(findstring HAL_USE_PAL TRUE,$(HALCONF)),)
|
||||
# PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/GPIOv1/hal_pal_lld.c
|
||||
# endif
|
||||
# else
|
||||
# PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/GPIOv1/hal_pal_lld.c
|
||||
# endif
|
||||
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/GPIOv1
|
|
@ -1,4 +1,10 @@
|
|||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/TIMv1/hal_st_lld.c
|
||||
ifeq ($(USE_SMART_BUILD),yes)
|
||||
ifneq ($(findstring HAL_USE_PWM TRUE,$(HALCONF)),)
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/TIMv1/hal_pwm_lld.c
|
||||
#PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/TIMv1/timer.c
|
||||
endif
|
||||
else
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/TIMv1/hal_pwm_lld.c
|
||||
endif
|
||||
|
||||
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/TIMv1/hal_st_lld.c
|
||||
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/TIMv1
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2019 /u/KeepItUnder
|
||||
Copyright (C) 2020 Alex Lewontin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -30,22 +30,124 @@
|
|||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define NUC123_PWM_CLKSRC_HSE 0x0UL
|
||||
#define NUC123_PWM_CLKSRC_HCLK 0x2UL
|
||||
#define NUC123_PWM_CLKSRC_HSI 0x3UL
|
||||
#define NUC123_PWM_CLKSRC_LSI 0x7UL
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief PWMD1 driver identifier.
|
||||
*/
|
||||
#if (NUC123_PWM_USE_PWM1 == TRUE) || defined(__DOXYGEN__)
|
||||
PWMDriver PWMD1;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
typedef struct {
|
||||
__IO uint32_t CNR; /* Offset: 0x0C PWM Counter Register 0 */
|
||||
__IO uint32_t CMR; /* Offset: 0x10 PWM Comparator Register 0 */
|
||||
__I uint32_t PDR; /* Offset: 0x14 PWM Data Register 0 */
|
||||
} PWM_CHANNEL_T;
|
||||
|
||||
#define PWMA_CHANNELS_BASE (PWMA_BASE + 0xC)
|
||||
#define PWMA_CHANNELS ((PWM_CHANNEL_T *) PWMA_CHANNELS_BASE)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Shared IRQ handler.
|
||||
* @note It is assumed that the various sources are only activated if the
|
||||
* associated callback pointer is not equal to @p NULL in order to not
|
||||
* perform an extra check in a potentially critical interrupt handler.
|
||||
*
|
||||
* @param[in] pwmd pointer to a @p PWMDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void pwm_lld_serve_interrupt(PWMDriver *pwmp) {
|
||||
|
||||
uint32_t piir;
|
||||
uint32_t pier_clr_msk;
|
||||
uint32_t poe_clr_msk;
|
||||
|
||||
pier_clr_msk = 0;
|
||||
poe_clr_msk = 0;
|
||||
piir = PWMA->PIIR;
|
||||
PWMA->PIIR = piir;
|
||||
|
||||
if (piir & PWM_PIIR_PWMDIF0_Msk) {
|
||||
pwmp->config->channels[0].callback(pwmp);
|
||||
}
|
||||
|
||||
if (piir & PWM_PIIR_PWMDIF1_Msk) {
|
||||
pwmp->config->channels[1].callback(pwmp);
|
||||
}
|
||||
|
||||
if (piir & PWM_PIIR_PWMDIF2_Msk) {
|
||||
pwmp->config->channels[2].callback(pwmp);
|
||||
}
|
||||
|
||||
if (piir & PWM_PIIR_PWMDIF3_Msk) {
|
||||
pwmp->config->channels[3].callback(pwmp);
|
||||
}
|
||||
|
||||
if (piir & PWM_PIIR_PWMIF0_Msk) {
|
||||
if (pwmp->periodic_callback_enabled) {
|
||||
pwmp->config->callback(pwmp);
|
||||
}
|
||||
if (!pwmIsChannelEnabledI(pwmp, 0)) {
|
||||
poe_clr_msk |= PWM_POE_PWM1_Msk;
|
||||
pier_clr_msk |= PWM_PIER_PWMDIE0_Msk;
|
||||
}
|
||||
}
|
||||
|
||||
if (piir & PWM_PIIR_PWMIF1_Msk) {
|
||||
poe_clr_msk |= PWM_POE_PWM1_Msk;
|
||||
pier_clr_msk |= PWM_PIER_PWMDIE1_Msk;
|
||||
pier_clr_msk |= PWM_PIER_PWMIE1_Msk;
|
||||
}
|
||||
|
||||
if (piir & PWM_PIIR_PWMIF2_Msk) {
|
||||
poe_clr_msk |= PWM_POE_PWM2_Msk;
|
||||
pier_clr_msk |= PWM_PIER_PWMDIE2_Msk;
|
||||
pier_clr_msk |= PWM_PIER_PWMIE2_Msk;
|
||||
}
|
||||
|
||||
if (piir & PWM_PIIR_PWMIF3_Msk) {
|
||||
poe_clr_msk |= PWM_POE_PWM3_Msk;
|
||||
pier_clr_msk |= PWM_PIER_PWMDIE3_Msk;
|
||||
pier_clr_msk |= PWM_PIER_PWMIE3_Msk;
|
||||
}
|
||||
|
||||
PWMA->POE &= ~poe_clr_msk;
|
||||
PWMA->PIER &= ~pier_clr_msk;
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief PWM interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
OSAL_IRQ_HANDLER(NUC123_PWMA_HANDLER)
|
||||
{
|
||||
OSAL_IRQ_PROLOGUE();
|
||||
pwm_lld_serve_interrupt(&PWMD1);
|
||||
OSAL_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
@ -55,175 +157,277 @@
|
|||
*
|
||||
* @notapi
|
||||
*/
|
||||
// void pwm_lld_init(void) {
|
||||
|
||||
// }
|
||||
|
||||
void pwm_lld_start(PWM_T *pwm, uint32_t mask) {
|
||||
uint32_t pwmStart = 0;
|
||||
|
||||
for(uint32_t i = 0; i < PWM_CHANNELS; i++) {
|
||||
if (mask & (1 << i)) {
|
||||
pwmStart |= (PWM_PCR_CH0EN_Msk << (i * 8));
|
||||
}
|
||||
}
|
||||
|
||||
(pwm)->PCR |= pwmStart;
|
||||
}
|
||||
|
||||
|
||||
void pwm_lld_enable_period_int(PWM_T *pwm, uint32_t pwmChannel, uint32_t periodType) {
|
||||
(pwm)->PIER = ((pwm)->PIER & ~(0x01ul << (pwmChannel >> 1))) | (0x01ul << pwmChannel) | (periodType << (pwmChannel >> 1));
|
||||
}
|
||||
|
||||
|
||||
void pwm_lld_disable_period_int(PWM_T *pwm, uint32_t pwmChannel) {
|
||||
(pwm)->PIER &= ~(PWM_PIER_PWMIE0_Msk << pwmChannel);
|
||||
}
|
||||
|
||||
|
||||
uint32_t pwm_lld_get_period_int(PWM_T *pwm, uint32_t pwmChannel) {
|
||||
if ((pwm)->PIIR & (0x01ul << (pwmChannel))) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pwm_lld_clear_period_int(PWM_T *pwm, uint32_t pwmChannel) {
|
||||
(pwm)->PIIR = (0x01ul << pwmChannel);
|
||||
}
|
||||
|
||||
|
||||
uint32_t pwm_lld_config_output_channel(PWM_T *pwm, uint32_t channel, uint32_t freq, uint32_t duty)
|
||||
void pwm_lld_init(void)
|
||||
{
|
||||
uint32_t regSource;
|
||||
uint32_t clkSource;
|
||||
uint32_t pwmClk;
|
||||
uint8_t divider = 1;
|
||||
uint8_t prescale = 0xFF;
|
||||
uint16_t CNR = 0xFFFF;
|
||||
|
||||
if (channel < 2) {
|
||||
regSource = ((CLK->CLKSEL2 & (CLK_CLKSEL2_PWM01_S_Msk)) >> (CLK_CLKSEL2_PWM01_S_Pos - 2)) | (CLK->CLKSEL1 & (CLK_CLKSEL1_PWM01_S_Msk)) >> (CLK_CLKSEL1_PWM01_S_Pos);
|
||||
} else {
|
||||
regSource = ((CLK->CLKSEL2 & (CLK_CLKSEL2_PWM23_S_Msk)) >> (CLK_CLKSEL2_PWM23_S_Pos - 2)) | (CLK->CLKSEL1 & (CLK_CLKSEL1_PWM23_S_Msk)) >> (CLK_CLKSEL1_PWM23_S_Pos);
|
||||
}
|
||||
#if (NUC123_PWM_USE_PWM1 == TRUE)
|
||||
/* Driver initialization.*/
|
||||
pwmObjectInit(&PWMD1);
|
||||
PWMD1.channels = PWM_CHANNELS;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (regSource == 2) {
|
||||
SystemCoreClockUpdate();
|
||||
clkSource = SystemCoreClock;
|
||||
} else {
|
||||
switch (regSource) {
|
||||
case 0:
|
||||
clkSource = __HXT;
|
||||
break;
|
||||
case 1:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
clkSource = 0;
|
||||
break;
|
||||
case 2:
|
||||
SystemCoreClockUpdate();
|
||||
clkSource = SystemCoreClock;
|
||||
break;
|
||||
case 3:
|
||||
clkSource = __HIRC;
|
||||
break;
|
||||
case 7:
|
||||
clkSource = __LIRC;
|
||||
break;
|
||||
/**
|
||||
* @brief Configures and activates the PWM peripheral.
|
||||
* @note Starting a driver that is already in the @p PWM_READY state
|
||||
* disables all the active channels.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_start(PWMDriver *pwmp)
|
||||
{
|
||||
uint32_t clksel1;
|
||||
uint32_t clksel2;
|
||||
uint32_t prescale;
|
||||
uint32_t pcr;
|
||||
if (pwmp->state == PWM_STOP) {
|
||||
clksel1 = CLK->CLKSEL1;
|
||||
clksel2 = CLK->CLKSEL2;
|
||||
clksel1 = (clksel1 & ~(CLK_CLKSEL1_PWM01_S_Msk)) |
|
||||
((NUC123_PWM_CLKSRC_HCLK << CLK_CLKSEL1_PWM01_S_Pos) &
|
||||
CLK_CLKSEL1_PWM01_S_Msk);
|
||||
clksel1 = (clksel1 & ~(CLK_CLKSEL1_PWM23_S_Msk)) |
|
||||
((NUC123_PWM_CLKSRC_HCLK << CLK_CLKSEL1_PWM23_S_Pos) &
|
||||
CLK_CLKSEL1_PWM23_S_Msk);
|
||||
clksel2 = (clksel2 & ~(CLK_CLKSEL2_PWM01_S_E_Msk)) |
|
||||
((NUC123_PWM_CLKSRC_HCLK >> 2) << CLK_CLKSEL2_PWM01_S_E_Pos);
|
||||
clksel2 = (clksel2 & ~(CLK_CLKSEL2_PWM23_S_E_Msk)) |
|
||||
((NUC123_PWM_CLKSRC_HCLK >> 2) << CLK_CLKSEL2_PWM23_S_E_Pos);
|
||||
CLK->CLKSEL1 = clksel1;
|
||||
CLK->CLKSEL2 = clksel2;
|
||||
|
||||
CLK->APBCLK |= (CLK_APBCLK_PWM01_EN_Msk | CLK_APBCLK_PWM23_EN_Msk);
|
||||
nvicEnableVector(NUC123_PWMA_NUMBER, NUC123_PWM_IRQ_PRIORITY);
|
||||
SYS->IPRSTC2 |= SYS_IPRSTC2_PWM03_RST_Msk;
|
||||
SYS->IPRSTC2 &= ~(SYS_IPRSTC2_PWM03_RST_Msk);
|
||||
|
||||
/* Set clock scaling to 1 */
|
||||
PWMA->CSR = (4 << PWM_CSR_CSR0_Pos) | (4 << PWM_CSR_CSR1_Pos) |
|
||||
(4 << PWM_CSR_CSR2_Pos) | (4 << PWM_CSR_CSR3_Pos);
|
||||
|
||||
/* Set prescale to set frequency */
|
||||
prescale = NUC123_HCLK / pwmp->config->frequency;
|
||||
PWMA->PPR = (PWMA->PPR & ~(PWM_PPR_CP01_Msk | PWM_PPR_CP23_Msk)) |
|
||||
((prescale << PWM_PPR_CP01_Pos) & PWM_PPR_CP01_Msk) |
|
||||
((prescale << PWM_PPR_CP23_Pos) & PWM_PPR_CP23_Msk);
|
||||
|
||||
/*
|
||||
* PINV == 0 -> active high, PINV == 1 -> active low.
|
||||
* CHnINV vs CHnPINV:
|
||||
* - CHnINV inverts before deadzone generation
|
||||
* - CHnPINV inverts after deadzone generation
|
||||
* If no deadzone generation, INV(signal) == PINV(signal) and signal == INV(PINV(signal))
|
||||
* If there is deadzone generation, things get more complicated.
|
||||
*/
|
||||
|
||||
pcr = PWMA->PCR;
|
||||
|
||||
pcr &= ~(PWM_PCR_CH0PINV_Msk | PWM_PCR_CH0INV_Msk);
|
||||
pcr &= ~(PWM_PCR_CH1PINV_Msk | PWM_PCR_CH1INV_Msk);
|
||||
pcr &= ~(PWM_PCR_CH2PINV_Msk | PWM_PCR_CH2INV_Msk);
|
||||
pcr &= ~(PWM_PCR_CH3PINV_Msk | PWM_PCR_CH3INV_Msk);
|
||||
|
||||
/* Conditionally (and branchlessly) set the bits for the inverted channels */
|
||||
pcr |= ((pwmp->config->channels[0].mode == PWM_OUTPUT_ACTIVE_LOW) * PWM_PCR_CH0PINV_Msk);
|
||||
pcr |= ((pwmp->config->channels[1].mode == PWM_OUTPUT_ACTIVE_LOW) * PWM_PCR_CH1PINV_Msk);
|
||||
pcr |= ((pwmp->config->channels[2].mode == PWM_OUTPUT_ACTIVE_LOW) * PWM_PCR_CH2PINV_Msk);
|
||||
pcr |= ((pwmp->config->channels[3].mode == PWM_OUTPUT_ACTIVE_LOW) * PWM_PCR_CH3PINV_Msk);
|
||||
|
||||
/* Set to auto-reload (this will also reset CMR & CNR) */
|
||||
pcr |= (PWM_PCR_CH0MOD_Msk | PWM_PCR_CH1MOD_Msk);
|
||||
pcr |= (PWM_PCR_CH2MOD_Msk | PWM_PCR_CH3MOD_Msk);
|
||||
|
||||
PWMA->PCR = pcr;
|
||||
|
||||
/* TODO: Deadzone generation */
|
||||
|
||||
/* Mux the pins per the channel configs */
|
||||
|
||||
if (pwmp->config->channels[0].mode != PWM_OUTPUT_DISABLED) {
|
||||
if (pwmp->config->channels[0].pinmask & NUC123_PWM_CH0_PIN_PA12) {
|
||||
SYS->GPA_MFP |= (1 << 12);
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate best divider */
|
||||
while (divider < 17) {
|
||||
pwmClk = (clkSource / (freq)) / divider;
|
||||
// If pwmClk is larger than (CNR * prescale) then divider can still be bigger
|
||||
if (pwmClk > (0x10000 * 0x100)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Set prescaler to CNR value lower than 0xFFFF
|
||||
prescale = (pwmClk + 0xFFFF) / 0x10000;
|
||||
|
||||
// Keep prescale bigger than 2 this loop
|
||||
if (prescale < 3) {
|
||||
prescale = 2;
|
||||
}
|
||||
|
||||
pwmClk /= prescale;
|
||||
|
||||
if (pwmClk <= 0x10000) {
|
||||
if (pwmClk == 1) {
|
||||
CNR = 1; // Too fast, and PWM cannot generate expected frequency...
|
||||
} else {
|
||||
CNR = pwmClk;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
divider = divider << 1;
|
||||
if (pwmp->config->channels[1].mode != PWM_OUTPUT_DISABLED) {
|
||||
if (pwmp->config->channels[1].pinmask & NUC123_PWM_CH1_PIN_PA13) {
|
||||
SYS->GPA_MFP |= (1 << 13);
|
||||
}
|
||||
}
|
||||
|
||||
pwmClk = clkSource / (prescale * divider * CNR);
|
||||
if (pwmp->config->channels[2].mode != PWM_OUTPUT_DISABLED) {
|
||||
if (pwmp->config->channels[2].pinmask & NUC123_PWM_CH2_PIN_PA14) {
|
||||
SYS->GPA_MFP |= (1 << 14);
|
||||
}
|
||||
|
||||
/* Calculate PWM Registers */
|
||||
prescale -= 1;
|
||||
CNR -= 1;
|
||||
|
||||
/* Set final divider for output calculation */
|
||||
switch (divider) {
|
||||
case 1:
|
||||
divider = 4;
|
||||
break;
|
||||
case 4:
|
||||
divider = 1;
|
||||
break;
|
||||
case 8:
|
||||
divider = 2;
|
||||
break;
|
||||
case 16:
|
||||
divider = 3;
|
||||
break;
|
||||
case 0:
|
||||
case 2:
|
||||
case 3:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
default:
|
||||
divider = 0;
|
||||
break;
|
||||
if (pwmp->config->channels[2].pinmask & NUC123_PWM_CH2_PIN_PC12) {
|
||||
SYS->GPC_MFP |= (1 << 12);
|
||||
SYS->ALT_MFP |= SYS_ALT_MFP_PC12_MFP1_Msk;
|
||||
}
|
||||
}
|
||||
|
||||
// Prescaler is shared every two channels (01/23/etc.)
|
||||
(pwm)->PPR = ((pwm)->PPR & ~(PWM_PPR_CP01_Msk << ((channel >> 1) * 8))) | (prescale << ((channel >> 1) * 8));
|
||||
(pwm)->CSR = ((pwm)->CSR & ~(PWM_CSR_CSR0_Msk << (4 * channel))) | (divider << (4 * channel));
|
||||
if (pwmp->config->channels[3].mode != PWM_OUTPUT_DISABLED) {
|
||||
if (pwmp->config->channels[3].pinmask & NUC123_PWM_CH3_PIN_PA15) {
|
||||
SYS->GPA_MFP |= (1 << 15);
|
||||
SYS->ALT_MFP &= ~SYS_ALT_MFP_PA15_MFP1_Msk;
|
||||
}
|
||||
|
||||
// Set edge-aligned PWM
|
||||
(pwm)->PCR &= ~(PWM_PCR_PWM01TYPE_Msk << (channel >> 1));
|
||||
(pwm)->PCR |= PWM_PCR_CH0MOD_Msk << (8 * channel);
|
||||
|
||||
// Set PWM register values
|
||||
if (duty) {
|
||||
*((__IO uint32_t *)((((uint32_t) & ((pwm)->CMR0)) + channel * 12))) = duty * (CNR + 1) / 100 - 1;
|
||||
} else {
|
||||
*((__IO uint32_t *)((((uint32_t) & ((pwm)->CMR0)) + channel * 12))) = 0;
|
||||
if (pwmp->config->channels[3].pinmask & NUC123_PWM_CH3_PIN_PC13) {
|
||||
SYS->GPC_MFP |= (1 << 13);
|
||||
SYS->ALT_MFP |= SYS_ALT_MFP_PC13_MFP1_Msk;
|
||||
}
|
||||
}
|
||||
|
||||
*((__IO uint32_t *)((((uint32_t) & ((pwm)->CNR0)) + channel * 12))) = CNR;
|
||||
#if defined(NUC123xxxAEx)
|
||||
/* TODO: Implement PWM0 PC8 & PWM1 PB9 */
|
||||
#endif
|
||||
|
||||
return(pwmClk);
|
||||
PWMA->PIER &= ~(PWM_PIER_INT01TYPE_Msk | PWM_PIER_INT23TYPE_Msk);
|
||||
|
||||
pwm_lld_change_period(pwmp, pwmp->config->period);
|
||||
|
||||
PWMA->PCR |= (PWM_PCR_CH0EN_Msk | PWM_PCR_CH1EN_Msk |
|
||||
PWM_PCR_CH2EN_Msk | PWM_PCR_CH3EN_Msk);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the PWM peripheral.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_stop(PWMDriver *pwmp)
|
||||
{
|
||||
/* If in ready state then disables the PWM clock.*/
|
||||
if (pwmp->state == PWM_READY) {
|
||||
#if NUC123_PWM_USE_PWM1 == TRUE
|
||||
if (&PWMD1 == pwmp) {
|
||||
CLK->APBCLK &= ~(CLK_APBCLK_PWM01_EN_Msk | CLK_APBCLK_PWM23_EN_Msk);
|
||||
nvicDisableVector(NUC123_PWMA_NUMBER);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables a PWM channel.
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @post The channel is active using the specified configuration.
|
||||
* @note The function has effect at the next cycle start.
|
||||
* @note Channel notification is not enabled.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] channel PWM channel identifier (0...channels-1)
|
||||
* @param[in] width PWM pulse width as clock pulses number
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_enable_channel(PWMDriver *pwmp, pwmchannel_t channel,
|
||||
pwmcnt_t width)
|
||||
{
|
||||
(void)pwmp;
|
||||
PWMA_CHANNELS[channel].CMR = width;
|
||||
PWMA->POE |= PWM_POE_PWM0_Msk << channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables a PWM channel and its notification.
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @post The channel is disabled and its output line returned to the
|
||||
* idle state.
|
||||
* @note The function has effect at the next cycle start.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] channel PWM channel identifier (0...channels-1)
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel)
|
||||
{
|
||||
(void)pwmp;
|
||||
/* We do not disable immediately, but enable the periodic interrupt
|
||||
We will actually disable in the next ISR. */
|
||||
PWMA->PIER |= (PWM_PIER_PWMIE0_Msk << channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables the periodic activation edge notification.
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @note If the notification is already enabled then the call has no effect.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_enable_periodic_notification(PWMDriver *pwmp) {
|
||||
(void)pwmp;
|
||||
PWMA->PIER |= PWM_PIER_PWMIE0_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the periodic activation edge notification.
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @note If the notification is already disabled then the call has no effect.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_disable_periodic_notification(PWMDriver *pwmp) {
|
||||
(void)pwmp;
|
||||
/* TODO: Make sure this isn't in use for disabling the periodic channel */
|
||||
PWMA->PIER &= ~PWM_PIER_PWMIE0_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables a channel de-activation edge notification.
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @pre The channel must have been activated using @p pwmEnableChannel().
|
||||
* @note If the notification is already enabled then the call has no effect.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] channel PWM channel identifier (0...channels-1)
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_enable_channel_notification(PWMDriver *pwmp,
|
||||
pwmchannel_t channel)
|
||||
{
|
||||
(void)pwmp;
|
||||
PWMA->PIER |= (PWM_PIER_PWMDIE0_Msk << channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables a channel de-activation edge notification.
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @pre The channel must have been activated using @p pwmEnableChannel().
|
||||
* @note If the notification is already disabled then the call has no effect.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] channel PWM channel identifier (0...channels-1)
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_disable_channel_notification(PWMDriver * pwmp,
|
||||
pwmchannel_t channel)
|
||||
{
|
||||
(void)pwmp;
|
||||
PWMA->PIER &= ~(PWM_PIER_PWMDIE0_Msk << channel);
|
||||
}
|
||||
|
||||
void _pwm_lld_change_period(PWMDriver *pwmp, pwmcnt_t period) {
|
||||
(void)pwmp;
|
||||
osalSysLock();
|
||||
PWMA_CHANNELS[0].CNR = period - 1;
|
||||
PWMA_CHANNELS[1].CNR = period - 1;
|
||||
PWMA_CHANNELS[2].CNR = period - 1;
|
||||
PWMA_CHANNELS[3].CNR = period - 1;
|
||||
osalSysUnlock();
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_PWM */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2019 /u/KeepItUnder
|
||||
Copyright (C) 2020 Alex Lewontin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -25,9 +25,7 @@
|
|||
#ifndef HAL_PWM_LLD_H
|
||||
#define HAL_PWM_LLD_H
|
||||
|
||||
// #if HAL_USE_PWM || defined(__DOXYGEN__)
|
||||
|
||||
// #include "stm32_tim.h"
|
||||
#if (HAL_USE_PWM == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
|
@ -36,84 +34,237 @@
|
|||
/**
|
||||
* @brief Number of PWM channels per PWM driver.
|
||||
*/
|
||||
#define PWM_CHANNELS (4)
|
||||
#define PWM_CHANNELS 4
|
||||
|
||||
#define PWM_CH0 0x0ul
|
||||
#define PWM_CH1 0x1ul
|
||||
#define PWM_CH2 0x2ul
|
||||
#define PWM_CH3 0x3ul
|
||||
/**
|
||||
* @brief Possible per-channel output pin mask values.
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Channel 0 output pin mask values.
|
||||
* @note Pin PA.12 has not yet been implemented
|
||||
*/
|
||||
#define NUC123_PWM_CH0_PIN_NONE 0x0
|
||||
#define NUC123_PWM_CH0_PIN_PA12 0x1
|
||||
#if defined(NUC123xxxAEx)
|
||||
#define NUC123_PWM_CH0_PIN_PC8 0x2
|
||||
#endif
|
||||
|
||||
#define PWM_EDGE_ALIGNED (0x0ul) /*!< Edge aligned */
|
||||
#define PWM_CENTER_ALIGNED (0x01ul) /*!< Center aligned */
|
||||
/**
|
||||
* @brief Channel 1 output pin mask values.
|
||||
* @note Pin PB.9 has not yet been implemented
|
||||
*/
|
||||
#define NUC123_PWM_CH1_PIN_NONE 0x0
|
||||
#define NUC123_PWM_CH1_PIN_PA13 0x1
|
||||
#if defined(NUC123xxxAEx)
|
||||
#define NUC123_PWM_CH1_PIN_PB9 0x2
|
||||
#endif
|
||||
|
||||
#define PWM_CLK_DIV_1 (0x04ul) /*!< Divide by 1 */
|
||||
#define PWM_CLK_DIV_2 (0x0ul) /*!< Divide by 2 */
|
||||
#define PWM_CLK_DIV_4 (0x01ul) /*!< Divide by 4 */
|
||||
#define PWM_CLK_DIV_8 (0x02ul) /*!< Divide by 8 */
|
||||
#define PWM_CLK_DIV_16 (0x03ul) /*!< Divide by 16 */
|
||||
|
||||
#define PWM_PERIOD_INT_UNDERFLOW (0) /*!< Period interrupt - counter underflow */
|
||||
#define PWM_PERIOD_INT_MATCH_CNR (PWM_PIER_INT01TYPE_Msk) /*!< Period interrupt - counter matches CNR */
|
||||
#define PWM_CAPTURE_INT_RISING_LATCH (PWM_CCR0_CRL_IE0_Msk) /*!< Capture interrupt - rising latch */
|
||||
#define PWM_CAPTURE_INT_FALLING_LATCH (PWM_CCR0_CFL_IE0_Msk) /*!< Capture interrupt - falling latch */
|
||||
/**
|
||||
* @brief Channel 2 output pin mask values.
|
||||
*/
|
||||
#define NUC123_PWM_CH2_PIN_NONE 0x0
|
||||
#define NUC123_PWM_CH2_PIN_PA14 0x1
|
||||
#define NUC123_PWM_CH2_PIN_PC12 0x2
|
||||
|
||||
/**
|
||||
* @brief Channel 3 output pin mask values.
|
||||
*/
|
||||
#define NUC123_PWM_CH3_PIN_NONE 0x0
|
||||
#define NUC123_PWM_CH3_PIN_PA15 0x1
|
||||
#define NUC123_PWM_CH3_PIN_PC13 0x2
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name NUC123 configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief PWMD1 driver enable switch.
|
||||
* @details If set to @p TRUE the support for PWM1 is included.
|
||||
* @note The default is @p TRUE
|
||||
*/
|
||||
#if !defined(NUC123_PWM_USE_PWM1) || defined(__DOXYGEN__)
|
||||
#define NUC123_PWM_USE_PWM1 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD1 driver IRQ priority.
|
||||
*/
|
||||
#if !defined(NUC123_PWM_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define NUC123_PWM_IRQ_PRIORITY 3
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Configuration checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Type of a PWM mode.
|
||||
*/
|
||||
typedef uint32_t pwmmode_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a PWM channel.
|
||||
*/
|
||||
typedef uint8_t pwmchannel_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a channels mask.
|
||||
*/
|
||||
typedef uint8_t pwmchnmsk_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a PWM counter.
|
||||
*/
|
||||
typedef uint32_t pwmcnt_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a PWM driver channel configuration structure.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Channel active logic level.
|
||||
*/
|
||||
pwmmode_t mode;
|
||||
/**
|
||||
* @brief Channel callback pointer.
|
||||
* @note This callback is invoked on the channel compare event. If set to
|
||||
* @p NULL then the callback is disabled.
|
||||
*/
|
||||
pwmcallback_t callback;
|
||||
/* End of the mandatory fields.*/
|
||||
|
||||
/**
|
||||
* @brief A mask of pins the PWM signal will be output on.
|
||||
* @note See driver constants for possible values.
|
||||
*/
|
||||
uint8_t pinmask;
|
||||
|
||||
} PWMChannelConfig;
|
||||
|
||||
/**
|
||||
* @brief Type of a PWM driver configuration structure.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Timer clock in Hz.
|
||||
* @note The low level can use assertions in order to catch invalid
|
||||
* frequency specifications.
|
||||
*/
|
||||
uint32_t frequency;
|
||||
/**
|
||||
* @brief PWM period in ticks.
|
||||
* @note The low level can use assertions in order to catch invalid
|
||||
* period specifications.
|
||||
*/
|
||||
pwmcnt_t period;
|
||||
/**
|
||||
* @brief Periodic callback pointer.
|
||||
* @note This callback is invoked on PWM counter reset. If set to
|
||||
* @p NULL then the callback is disabled.
|
||||
*/
|
||||
pwmcallback_t callback;
|
||||
/**
|
||||
* @brief Channels configurations.
|
||||
*/
|
||||
PWMChannelConfig channels[PWM_CHANNELS];
|
||||
/* End of the mandatory fields.*/
|
||||
} PWMConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure representing a PWM driver.
|
||||
*/
|
||||
struct PWMDriver {
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
pwmstate_t state;
|
||||
/**
|
||||
* @brief Current driver configuration data.
|
||||
*/
|
||||
const PWMConfig *config;
|
||||
/**
|
||||
* @brief Current PWM period in ticks.
|
||||
*/
|
||||
pwmcnt_t period;
|
||||
/**
|
||||
* @brief Mask of the enabled channels.
|
||||
*/
|
||||
pwmchnmsk_t enabled;
|
||||
/**
|
||||
* @brief Number of channels in this instance.
|
||||
*/
|
||||
pwmchannel_t channels;
|
||||
#if defined(PWM_DRIVER_EXT_FIELDS)
|
||||
PWM_DRIVER_EXT_FIELDS
|
||||
#endif
|
||||
/* End of the mandatory fields.*/
|
||||
_Bool periodic_callback_enabled;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Changes the period the PWM peripheral.
|
||||
* @details This function changes the period of a PWM unit that has already
|
||||
* been activated using @p pwmStart().
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @post The PWM unit period is changed to the new value.
|
||||
* @note The function has effect at the next cycle start.
|
||||
* @note If a period is specified that is shorter than the pulse width
|
||||
* programmed in one of the channels then the behavior is not
|
||||
* guaranteed.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] period new cycle time in ticks
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pwm_lld_change_period(pwmp, period) _pwm_lld_change_period(pwmp, period)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (NUC123_PWM_USE_PWM1 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern PWMDriver PWMD1;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// void pwm_lld_init(void);
|
||||
// void pwm_lld_start(PWMDriver *pwmp);
|
||||
// void pwm_lld_stop(PWMDriver *pwmp);
|
||||
// void pwm_lld_enable_channel(PWMDriver *pwmp,
|
||||
// pwmchannel_t channel,
|
||||
// pwmcnt_t width);
|
||||
// void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel);
|
||||
// void pwm_lld_enable_periodic_notification(PWMDriver *pwmp);
|
||||
// void pwm_lld_disable_periodic_notification(PWMDriver *pwmp);
|
||||
// void pwm_lld_enable_channel_notification(PWMDriver *pwmp,
|
||||
// pwmchannel_t channel);
|
||||
// void pwm_lld_disable_channel_notification(PWMDriver *pwmp,
|
||||
// pwmchannel_t channel);
|
||||
// void pwm_lld_serve_interrupt(PWMDriver *pwmp);
|
||||
|
||||
void pwm_lld_enable_period_int(PWM_T *pwm, uint32_t pwmChannel, uint32_t periodType);
|
||||
void pwm_lld_disable_period_int(PWM_T *pwm, uint32_t pwmChannel);
|
||||
void pwm_lld_start(PWM_T *pwm, uint32_t mask);
|
||||
void pwm_lld_clear_period_int(PWM_T *pwm, uint32_t pwmChannel);
|
||||
uint32_t pwm_lld_get_period_int(PWM_T *pwm, uint32_t pwmChannel);
|
||||
uint32_t pwm_lld_config_output_channel(PWM_T *pwm, uint32_t channel, uint32_t freq, uint32_t duty);
|
||||
void pwm_lld_init(void);
|
||||
void pwm_lld_start(PWMDriver *pwmp);
|
||||
void pwm_lld_stop(PWMDriver *pwmp);
|
||||
void pwm_lld_enable_channel(PWMDriver *pwmp,
|
||||
pwmchannel_t channel,
|
||||
pwmcnt_t width);
|
||||
void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel);
|
||||
void pwm_lld_enable_periodic_notification(PWMDriver *pwmp);
|
||||
void pwm_lld_disable_periodic_notification(PWMDriver *pwmp);
|
||||
void pwm_lld_enable_channel_notification(PWMDriver *pwmp,
|
||||
pwmchannel_t channel);
|
||||
void pwm_lld_disable_channel_notification(PWMDriver *pwmp,
|
||||
pwmchannel_t channel);
|
||||
void _pwm_lld_change_period(PWMDriver *pwmp, pwmcnt_t period);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// #endif /* HAL_USE_PWM */
|
||||
#endif /* HAL_USE_PWM */
|
||||
|
||||
#endif /* HAL_PWM_LLD_H */
|
||||
|
||||
|
|
|
@ -8,8 +8,7 @@ PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
|
|||
|
||||
# Optional platform files.
|
||||
ifeq ($(USE_SMART_BUILD),yes)
|
||||
HALCONF := $(strip $(shell cat halconf.h | egrep -e "\#define"))
|
||||
|
||||
HALCONF := $(strip $(shell cat $(CONFDIR)/halconf.h $(CONFDIR)/halconf_community.h | egrep -e "\#define"))
|
||||
endif
|
||||
|
||||
# Drivers compatible with the platform.
|
||||
|
|
|
@ -115,6 +115,9 @@ include $(CHIBIOS)/tools/mk/autobuild.mk
|
|||
#include $(CHIBIOS)/test/rt/rt_test.mk
|
||||
#include $(CHIBIOS)/test/oslib/oslib_test.mk
|
||||
|
||||
# Define linker script file here
|
||||
LDSCRIPT= $(STARTUPLD_CONTRIB)/NUC123SD4AN0.ld
|
||||
|
||||
# C sources that can be compiled in ARM or THUMB mode depending on the global
|
||||
# setting.
|
||||
CSRC = $(ALLCSRC) \
|
||||
|
@ -183,7 +186,6 @@ include $(RULESPATH)/rules.mk
|
|||
# Custom rules
|
||||
#
|
||||
|
||||
|
||||
OPENOCD:=$(shell readlink -f `which openocd`)
|
||||
OPENOCDPATH:=$(shell dirname $(OPENOCD))/../share/openocd
|
||||
|
||||
|
@ -195,11 +197,3 @@ connect:
|
|||
|
||||
flash: $(BUILDDIR)/$(PROJECT).elf
|
||||
openocd -f ../scripts/interface/nulink.cfg -f ../scripts/target/numicroM0.cfg -c "program $< verify reset exit"
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Custom rules
|
||||
##############################################################################
|
||||
|
||||
|
|
|
@ -0,0 +1,203 @@
|
|||
##############################################################################
|
||||
# Build global options
|
||||
# NOTE: Can be overridden externally.
|
||||
#
|
||||
|
||||
# Compiler options here.
|
||||
ifeq ($(USE_OPT),)
|
||||
USE_OPT = -ggdb -g3 -gdwarf-3 -gstrict-dwarf -fomit-frame-pointer -falign-functions=16
|
||||
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 = yes
|
||||
endif
|
||||
|
||||
# Enable this if you want to see the full log while compiling.
|
||||
ifeq ($(USE_VERBOSE_COMPILE),)
|
||||
USE_VERBOSE_COMPILE = no
|
||||
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 Cortex-M process stack. This stack is
|
||||
# the stack used by the main() thread.
|
||||
ifeq ($(USE_PROCESS_STACKSIZE),)
|
||||
USE_PROCESS_STACKSIZE = 0x400
|
||||
endif
|
||||
|
||||
# Stack size to the allocated to the Cortex-M main/exceptions stack. This
|
||||
# stack is used for processing interrupts and exceptions.
|
||||
ifeq ($(USE_EXCEPTIONS_STACKSIZE),)
|
||||
USE_EXCEPTIONS_STACKSIZE = 0x400
|
||||
endif
|
||||
|
||||
# Enables the use of FPU (no, softfp, hard).
|
||||
ifeq ($(USE_FPU),)
|
||||
USE_FPU = no
|
||||
endif
|
||||
|
||||
# FPU-related options.
|
||||
ifeq ($(USE_FPU_OPT),)
|
||||
USE_FPU_OPT = -mfloat-abi=$(USE_FPU) -mfpu=fpv4-sp-d16
|
||||
endif
|
||||
|
||||
#
|
||||
# Architecture or project specific options
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Project, target, sources and paths
|
||||
#
|
||||
|
||||
# Define project name here
|
||||
PROJECT = ch
|
||||
|
||||
# Target settings.
|
||||
MCU = cortex-m0
|
||||
|
||||
# Imported source files and paths.
|
||||
BASE_PATH := ../../../../../../..
|
||||
CHIBIOS := $(BASE_PATH)/ChibiOS/ChibiOS
|
||||
CHIBIOS_CONTRIB := $(BASE_PATH)/ChibiOS/ChibiOS-Contrib
|
||||
CONFDIR := ./cfg
|
||||
BUILDDIR := ./build
|
||||
DEPDIR := ./.dep
|
||||
|
||||
# Licensing files.
|
||||
include $(CHIBIOS)/os/license/license.mk
|
||||
# Startup files.
|
||||
include $(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_NUC123SD4AN0.mk
|
||||
# HAL-OSAL files (optional).
|
||||
include $(CHIBIOS)/os/hal/hal.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/NUC123SD4AN0/platform.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/boards/NUTINY-SDK-NUC123-V2.0/board.mk
|
||||
include $(CHIBIOS)/os/hal/osal/os-less/ARMCMx/osal.mk
|
||||
# RTOS files (optional).
|
||||
#include $(CHIBIOS)/os/rt/rt.mk
|
||||
#include $(CHIBIOS)/os/common/ports/ARMv7-M/compilers/GCC/mk/port.mk
|
||||
# Auto-build files in ./source recursively.
|
||||
include $(CHIBIOS)/tools/mk/autobuild.mk
|
||||
# Other files (optional).
|
||||
#include $(CHIBIOS)/test/lib/test.mk
|
||||
#include $(CHIBIOS)/test/rt/rt_test.mk
|
||||
#include $(CHIBIOS)/test/oslib/oslib_test.mk
|
||||
|
||||
# Define linker script file here
|
||||
LDSCRIPT= $(STARTUPLD_CONTRIB)/NUC123SD4AN0.ld
|
||||
|
||||
# C sources that can be compiled in ARM or THUMB mode depending on the global
|
||||
# setting.
|
||||
CSRC = $(ALLCSRC) \
|
||||
$(TESTSRC) \
|
||||
main.c
|
||||
|
||||
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
|
||||
# setting.
|
||||
CPPSRC = $(ALLCPPSRC)
|
||||
|
||||
# List ASM source files here.
|
||||
ASMSRC = $(ALLASMSRC)
|
||||
|
||||
# List ASM with preprocessor source files here.
|
||||
ASMXSRC = $(ALLXASMSRC)
|
||||
|
||||
# Inclusion directories.
|
||||
INCDIR = $(CONFDIR) $(ALLINC) $(TESTINC)
|
||||
|
||||
# Define C warning options here.
|
||||
CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes
|
||||
|
||||
# Define C++ warning options here.
|
||||
CPPWARN = -Wall -Wextra -Wundef
|
||||
|
||||
#
|
||||
# Project, target, sources and paths
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# 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 section
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Common rules
|
||||
#
|
||||
|
||||
RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk
|
||||
include $(RULESPATH)/arm-none-eabi.mk
|
||||
include $(RULESPATH)/rules.mk
|
||||
|
||||
#
|
||||
# Common rules
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Custom rules
|
||||
#
|
||||
|
||||
OPENOCD:=$(shell readlink -f `which openocd`)
|
||||
OPENOCDPATH:=$(shell dirname $(OPENOCD))/../share/openocd
|
||||
|
||||
install-openocd-config:
|
||||
rm $(OPENOCDPATH)/scripts/target/numicroM0.cfg && cp $(CHIBIOS_CONTRIB)/ext/numicroM0.cfg $(OPENOCDPATH)/scripts/target/
|
||||
|
||||
connect:
|
||||
openocd -f ../scripts/interface/nulink.cfg -f ../scripts/target/numicroM0.cfg
|
||||
|
||||
flash: $(BUILDDIR)/$(PROJECT).elf
|
||||
openocd -f ../scripts/interface/nulink.cfg -f ../scripts/target/numicroM0.cfg -c "program $< verify reset exit"
|
||||
|
||||
#
|
||||
# Custom rules
|
||||
##############################################################################
|
|
@ -0,0 +1,531 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2020 Alex Lewontin
|
||||
|
||||
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
|
||||
|
||||
#define _CHIBIOS_HAL_CONF_
|
||||
#define _CHIBIOS_HAL_CONF_VER_7_1_
|
||||
|
||||
#include "mcuconf.h"
|
||||
|
||||
/**
|
||||
* @brief Enables the PAL subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_PAL FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the ADC subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_ADC FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the CAN subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_CAN FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the cryptographic subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_CRY) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_CRY FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the DAC subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_DAC FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the EFlash subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_EFL) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_EFL 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 TRUE
|
||||
#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 FALSE
|
||||
#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 SIO subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SIO) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SIO FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the SPI subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SPI FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the TRNG subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_TRNG) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_TRNG 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
|
||||
|
||||
/**
|
||||
* @brief Enables the WSPI subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_WSPI) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_WSPI FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* PAL driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(PAL_USE_CALLBACKS) || defined(__DOXYGEN__)
|
||||
#define PAL_USE_CALLBACKS FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(PAL_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define PAL_USE_WAIT 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 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enforces the driver to use direct callbacks rather than OSAL events.
|
||||
*/
|
||||
#if !defined(CAN_ENFORCE_USE_CALLBACKS) || defined(__DOXYGEN__)
|
||||
#define CAN_ENFORCE_USE_CALLBACKS FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* CRY driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables the SW fall-back of the cryptographic driver.
|
||||
* @details When enabled, this option, activates a fall-back software
|
||||
* implementation for algorithms not supported by the underlying
|
||||
* hardware.
|
||||
* @note Fall-back implementations may not be present for all algorithms.
|
||||
*/
|
||||
#if !defined(HAL_CRY_USE_FALLBACK) || defined(__DOXYGEN__)
|
||||
#define HAL_CRY_USE_FALLBACK FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Makes the driver forcibly use the fall-back implementations.
|
||||
*/
|
||||
#if !defined(HAL_CRY_ENFORCE_FALLBACK) || defined(__DOXYGEN__)
|
||||
#define HAL_CRY_ENFORCE_FALLBACK FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* DAC driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(DAC_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define DAC_USE_WAIT TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the @p dacAcquireBus() and @p dacReleaseBus() APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(DAC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define DAC_USE_MUTUAL_EXCLUSION TRUE
|
||||
#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 TRUE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* MAC driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables the zero-copy API.
|
||||
*/
|
||||
#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 TRUE
|
||||
#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 TRUE
|
||||
#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 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief OCR initialization constant for V20 cards.
|
||||
*/
|
||||
#if !defined(SDC_INIT_OCR_V20) || defined(__DOXYGEN__)
|
||||
#define SDC_INIT_OCR_V20 0x50FF8000U
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief OCR initialization constant for non-V20 cards.
|
||||
*/
|
||||
#if !defined(SDC_INIT_OCR) || defined(__DOXYGEN__)
|
||||
#define SDC_INIT_OCR 0x80100000U
|
||||
#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 32
|
||||
#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 circular transfers APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(SPI_USE_CIRCULAR) || defined(__DOXYGEN__)
|
||||
#define SPI_USE_CIRCULAR FALSE
|
||||
#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 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Handling method for SPI CS line.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(SPI_SELECT_MODE) || defined(__DOXYGEN__)
|
||||
#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
|
||||
#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
|
||||
|
||||
/*===========================================================================*/
|
||||
/* WSPI driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(WSPI_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define WSPI_USE_WAIT TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the @p wspiAcquireBus() and @p wspiReleaseBus() APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(WSPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define WSPI_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
|
||||
#endif /* HALCONF_H */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
Copyright (C) 2016 Stephane D'Alu
|
||||
|
||||
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_
|
||||
|
||||
/*
|
||||
* Board setting
|
||||
*/
|
||||
|
||||
/*
|
||||
* HAL driver system settings.
|
||||
*/
|
||||
#define NUC123_HSE_ENABLED TRUE
|
||||
#define NUC123_PLL_ENABLED TRUE
|
||||
#define NUC123_PLLSRC NUC123_PLLSRC_HSE
|
||||
#define NUC123_HCLKSRC NUC123_HCLKSRC_PLL
|
||||
|
||||
#define NUC123SD4AN0_MCUCONF
|
||||
|
||||
#endif /* _MCUCONF_H_ */
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2018 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file templates/halconf.h
|
||||
* @brief Bare-metal OSAL configuration header.
|
||||
*
|
||||
* @addtogroup OSAL_CONF
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef OSALCONF_H
|
||||
#define OSALCONF_H
|
||||
|
||||
/**
|
||||
* @brief Frequency in Hertz of the system tick.
|
||||
*/
|
||||
#if !defined(OSAL_ST_FREQUENCY) || defined(__DOXYGEN__)
|
||||
#define OSAL_ST_FREQUENCY 10000
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables OSAL assertions.
|
||||
*/
|
||||
#if !defined(OSAL_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
|
||||
#define OSAL_DBG_ENABLE_ASSERTS FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables OSAL functions parameters checks.
|
||||
*/
|
||||
#if !defined(OSAL_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
|
||||
#define OSAL_DBG_ENABLE_CHECKS FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief OSAL initialization hook.
|
||||
*/
|
||||
#if !defined(OSAL_INIT_HOOK) || defined(__DOXYGEN__)
|
||||
#define OSAL_INIT_HOOK() { \
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Idle loop hook macro.
|
||||
*/
|
||||
#if !defined(OSAL_IDLE_HOOK) || defined(__DOXYGEN__)
|
||||
#define OSAL_IDLE_HOOK() { \
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OSALCONF_H */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
Adapted from ChibiOS-Contrib/testhal/KINETIS/FRDM-KL25Z/PWM
|
||||
(c) 2015 flabbergast <s3+flabbergast@sdfeu.org>
|
||||
Modifications copyright (C) 2020 Alex Lewontin
|
||||
|
||||
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 "hal.h"
|
||||
|
||||
const PWMConfig pwmcfg = {
|
||||
750000,
|
||||
1000,
|
||||
NULL,
|
||||
{
|
||||
{PWM_OUTPUT_ACTIVE_HIGH, NULL, NUC123_PWM_CH0_PIN_PA12},
|
||||
{PWM_OUTPUT_ACTIVE_LOW, NULL, NUC123_PWM_CH1_PIN_PA13},
|
||||
{PWM_OUTPUT_DISABLED, NULL, NUC123_PWM_CH2_PIN_NONE},
|
||||
{PWM_OUTPUT_DISABLED, NULL, NUC123_PWM_CH3_PIN_NONE},
|
||||
},
|
||||
};
|
||||
|
||||
#define BREATHE_STEP 16 /* ms; = 4000ms/TABLE_SIZE */
|
||||
|
||||
/* Breathing Sleep LED brighness(PWM On period) table
|
||||
*
|
||||
* http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
|
||||
* (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i }
|
||||
*/
|
||||
/* ruby -e "a = ((0..255).map{|x| Math.exp(Math.cos(Math::PI+(2*x*(Math::PI)/255)))-Math.exp(-1) }); m = a.max; a.map\!{|x| (10000*x/m).to_i}; p a" */
|
||||
#define TABLE_SIZE 256
|
||||
static const uint16_t breathing_table[TABLE_SIZE] = {
|
||||
0, 0, 1, 4, 7, 11, 17, 23, 30, 38, 47, 58,
|
||||
69, 81, 94, 109, 124, 141, 159, 177, 197, 218, 241, 264,
|
||||
289, 315, 343, 372, 402, 433, 466, 501, 537, 574, 613, 654,
|
||||
696, 741, 786, 834, 883, 935, 988, 1043, 1100, 1159, 1220, 1283,
|
||||
1349, 1416, 1486, 1558, 1632, 1709, 1788, 1870, 1954, 2040, 2129, 2220,
|
||||
2314, 2411, 2510, 2611, 2715, 2822, 2932, 3044, 3158, 3275, 3395, 3517,
|
||||
3641, 3768, 3897, 4028, 4162, 4298, 4436, 4576, 4717, 4861, 5006, 5152,
|
||||
5300, 5449, 5600, 5751, 5903, 6055, 6208, 6361, 6513, 6666, 6818, 6970,
|
||||
7120, 7269, 7417, 7563, 7708, 7850, 7990, 8127, 8261, 8391, 8519, 8643,
|
||||
8762, 8878, 8989, 9095, 9196, 9293, 9383, 9469, 9548, 9622, 9689, 9750,
|
||||
9805, 9853, 9895, 9930, 9957, 9978, 9992, 9999, 10000, 9992, 9978, 9957,
|
||||
9930, 9895, 9853, 9805, 9750, 9689, 9622, 9548, 9469, 9383, 9293, 9196,
|
||||
9095, 8989, 8878, 8762, 8643, 8519, 8391, 8261, 8127, 7990, 7850, 7708,
|
||||
7563, 7417, 7269, 7120, 6970, 6818, 6666, 6513, 6361, 6208, 6055, 5903,
|
||||
5751, 5600, 5449, 5300, 5152, 5006, 4861, 4717, 4576, 4436, 4298, 4162,
|
||||
4028, 3897, 3768, 3641, 3517, 3395, 3275, 3158, 3044, 2932, 2822, 2715,
|
||||
2611, 2510, 2411, 2314, 2220, 2129, 2040, 1954, 1870, 1788, 1709, 1632,
|
||||
1558, 1486, 1416, 1349, 1283, 1220, 1159, 1100, 1043, 988, 935, 883,
|
||||
834, 786, 741, 696, 654, 613, 574, 537, 501, 466, 433, 402,
|
||||
372, 343, 315, 289, 264, 241, 218, 197, 177, 159, 141, 124,
|
||||
109, 94, 81, 69, 58, 47, 38, 30, 23, 17, 11, 7,
|
||||
4, 1, 0, 0};
|
||||
|
||||
uint16_t table_pos = 0;
|
||||
|
||||
|
||||
/*
|
||||
* Application entry point.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* System initializations.
|
||||
* - HAL initialization, this also initializes the configured device drivers
|
||||
* and performs the board-specific initializations.
|
||||
*/
|
||||
|
||||
halInit();
|
||||
|
||||
/*
|
||||
* Enabling interrupts, initialization done.
|
||||
*/
|
||||
osalSysEnable();
|
||||
|
||||
pwmStart(&PWMD1, &pwmcfg);
|
||||
pwmEnableChannel(&PWMD1, 0, 0);
|
||||
pwmEnableChannel(&PWMD1, 1, 0);
|
||||
while (true) {
|
||||
osalThreadSleepMilliseconds(BREATHE_STEP);
|
||||
pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, breathing_table[table_pos]));
|
||||
pwmEnableChannel(&PWMD1, 1, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, breathing_table[table_pos]));
|
||||
table_pos = (table_pos + 1) % TABLE_SIZE;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
*****************************************************************************
|
||||
** ChibiOS/HAL - PWM driver demo for NUC123. **
|
||||
*****************************************************************************
|
||||
|
||||
** TARGET **
|
||||
|
||||
The demo runs on a NUTINY-SDK-NUC123-V2.0 board with a NUC123SD4AN0 MCU.
|
||||
|
||||
** The Demo **
|
||||
|
||||
The application demonstrates the use of the NUC123 PWM driver. When successful,
|
||||
pins 44 and 45 should carry a 750 Hz square wave, the duty cycle of which
|
||||
sinusoidally oscillates between 0% and 100%. One channel is active high, and
|
||||
the other is active low.
|
||||
|
||||
** Board Setup **
|
||||
|
||||
There are multiple ways to observe the PWM output:
|
||||
- Attach channels of a logic analyzer to pins 44 & 45, and a ground pin. Set it
|
||||
to trigger on either (but not both) the rising or falling edge of either (but
|
||||
not both) channel.
|
||||
|
||||
** Build Procedure **
|
||||
|
||||
The demo has been tested using gcc version 9.3.1 (GNU Arm Embedded Toolchain 9-2020-q2-update).
|
||||
Just modify the TRGT line in the makefile in order to use different GCC ports.
|
Loading…
Reference in New Issue