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"
|
#include "hal.h"
|
||||||
|
|
||||||
|
#if HAL_USE_PAL
|
||||||
const PALConfig pal_default_config;
|
const PALConfig pal_default_config;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Board-specific initialization code.
|
* @brief Board-specific initialization code.
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#define NUC123SD4AN0
|
#define NUC123SD4AN0
|
||||||
#define BOARD_NAME "NUTINY SDK NUC123 V2.0"
|
#define BOARD_NAME "NUTINY SDK NUC123 V2.0"
|
||||||
|
|
||||||
|
|
||||||
#define NUC123_LSE_BYPASS TRUE
|
#define NUC123_LSE_BYPASS TRUE
|
||||||
/*
|
/*
|
||||||
* Board specific settings.
|
* Board specific settings.
|
||||||
|
|
|
@ -4,9 +4,5 @@ BOARDSRC = $(CHIBIOS_CONTRIB)/os/hal/boards/NUTINY-SDK-NUC123-V2.0/board.c
|
||||||
# Required include directories
|
# Required include directories
|
||||||
BOARDINC = $(CHIBIOS_CONTRIB)/os/hal/boards/NUTINY-SDK-NUC123-V2.0
|
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)
|
ALLCSRC += $(BOARDSRC)
|
||||||
ALLINC += $(BOARDINC)
|
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
|
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)
|
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/GPIOv1
|
||||||
# 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
|
|
|
@ -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/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
|
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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -30,22 +30,124 @@
|
||||||
/* Driver local definitions. */
|
/* 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. */
|
/* Driver exported variables. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PWMD1 driver identifier.
|
||||||
|
*/
|
||||||
|
#if (NUC123_PWM_USE_PWM1 == TRUE) || defined(__DOXYGEN__)
|
||||||
|
PWMDriver PWMD1;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver local variables and types. */
|
/* 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. */
|
/* 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. */
|
/* 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. */
|
/* Driver exported functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -55,175 +157,277 @@
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
// void pwm_lld_init(void) {
|
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)
|
|
||||||
{
|
{
|
||||||
uint32_t regSource;
|
|
||||||
uint32_t clkSource;
|
|
||||||
uint32_t pwmClk;
|
|
||||||
uint8_t divider = 1;
|
|
||||||
uint8_t prescale = 0xFF;
|
|
||||||
uint16_t CNR = 0xFFFF;
|
|
||||||
|
|
||||||
if (channel < 2) {
|
#if (NUC123_PWM_USE_PWM1 == TRUE)
|
||||||
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);
|
/* Driver initialization.*/
|
||||||
} else {
|
pwmObjectInit(&PWMD1);
|
||||||
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);
|
PWMD1.channels = PWM_CHANNELS;
|
||||||
}
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (regSource == 2) {
|
/**
|
||||||
SystemCoreClockUpdate();
|
* @brief Configures and activates the PWM peripheral.
|
||||||
clkSource = SystemCoreClock;
|
* @note Starting a driver that is already in the @p PWM_READY state
|
||||||
} else {
|
* disables all the active channels.
|
||||||
switch (regSource) {
|
*
|
||||||
case 0:
|
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||||
clkSource = __HXT;
|
*
|
||||||
break;
|
* @notapi
|
||||||
case 1:
|
*/
|
||||||
case 4:
|
void pwm_lld_start(PWMDriver *pwmp)
|
||||||
case 5:
|
{
|
||||||
case 6:
|
uint32_t clksel1;
|
||||||
clkSource = 0;
|
uint32_t clksel2;
|
||||||
break;
|
uint32_t prescale;
|
||||||
case 2:
|
uint32_t pcr;
|
||||||
SystemCoreClockUpdate();
|
if (pwmp->state == PWM_STOP) {
|
||||||
clkSource = SystemCoreClock;
|
clksel1 = CLK->CLKSEL1;
|
||||||
break;
|
clksel2 = CLK->CLKSEL2;
|
||||||
case 3:
|
clksel1 = (clksel1 & ~(CLK_CLKSEL1_PWM01_S_Msk)) |
|
||||||
clkSource = __HIRC;
|
((NUC123_PWM_CLKSRC_HCLK << CLK_CLKSEL1_PWM01_S_Pos) &
|
||||||
break;
|
CLK_CLKSEL1_PWM01_S_Msk);
|
||||||
case 7:
|
clksel1 = (clksel1 & ~(CLK_CLKSEL1_PWM23_S_Msk)) |
|
||||||
clkSource = __LIRC;
|
((NUC123_PWM_CLKSRC_HCLK << CLK_CLKSEL1_PWM23_S_Pos) &
|
||||||
break;
|
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 */
|
if (pwmp->config->channels[1].mode != PWM_OUTPUT_DISABLED) {
|
||||||
while (divider < 17) {
|
if (pwmp->config->channels[1].pinmask & NUC123_PWM_CH1_PIN_PA13) {
|
||||||
pwmClk = (clkSource / (freq)) / divider;
|
SYS->GPA_MFP |= (1 << 13);
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 */
|
if (pwmp->config->channels[2].pinmask & NUC123_PWM_CH2_PIN_PC12) {
|
||||||
prescale -= 1;
|
SYS->GPC_MFP |= (1 << 12);
|
||||||
CNR -= 1;
|
SYS->ALT_MFP |= SYS_ALT_MFP_PC12_MFP1_Msk;
|
||||||
|
}
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prescaler is shared every two channels (01/23/etc.)
|
if (pwmp->config->channels[3].mode != PWM_OUTPUT_DISABLED) {
|
||||||
(pwm)->PPR = ((pwm)->PPR & ~(PWM_PPR_CP01_Msk << ((channel >> 1) * 8))) | (prescale << ((channel >> 1) * 8));
|
if (pwmp->config->channels[3].pinmask & NUC123_PWM_CH3_PIN_PA15) {
|
||||||
(pwm)->CSR = ((pwm)->CSR & ~(PWM_CSR_CSR0_Msk << (4 * channel))) | (divider << (4 * channel));
|
SYS->GPA_MFP |= (1 << 15);
|
||||||
|
SYS->ALT_MFP &= ~SYS_ALT_MFP_PA15_MFP1_Msk;
|
||||||
|
}
|
||||||
|
|
||||||
// Set edge-aligned PWM
|
if (pwmp->config->channels[3].pinmask & NUC123_PWM_CH3_PIN_PC13) {
|
||||||
(pwm)->PCR &= ~(PWM_PCR_PWM01TYPE_Msk << (channel >> 1));
|
SYS->GPC_MFP |= (1 << 13);
|
||||||
(pwm)->PCR |= PWM_PCR_CH0MOD_Msk << (8 * channel);
|
SYS->ALT_MFP |= SYS_ALT_MFP_PC13_MFP1_Msk;
|
||||||
|
}
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*((__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 */
|
#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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -25,9 +25,7 @@
|
||||||
#ifndef HAL_PWM_LLD_H
|
#ifndef HAL_PWM_LLD_H
|
||||||
#define HAL_PWM_LLD_H
|
#define HAL_PWM_LLD_H
|
||||||
|
|
||||||
// #if HAL_USE_PWM || defined(__DOXYGEN__)
|
#if (HAL_USE_PWM == TRUE) || defined(__DOXYGEN__)
|
||||||
|
|
||||||
// #include "stm32_tim.h"
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver constants. */
|
/* Driver constants. */
|
||||||
|
@ -36,84 +34,237 @@
|
||||||
/**
|
/**
|
||||||
* @brief Number of PWM channels per PWM driver.
|
* @brief Number of PWM channels per PWM driver.
|
||||||
*/
|
*/
|
||||||
#define PWM_CHANNELS (4)
|
#define PWM_CHANNELS 4
|
||||||
|
|
||||||
#define PWM_CH0 0x0ul
|
/**
|
||||||
#define PWM_CH1 0x1ul
|
* @brief Possible per-channel output pin mask values.
|
||||||
#define PWM_CH2 0x2ul
|
* @{
|
||||||
#define PWM_CH3 0x3ul
|
*/
|
||||||
|
/**
|
||||||
|
* @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 */
|
* @brief Channel 2 output pin mask values.
|
||||||
#define PWM_CLK_DIV_4 (0x01ul) /*!< Divide by 4 */
|
*/
|
||||||
#define PWM_CLK_DIV_8 (0x02ul) /*!< Divide by 8 */
|
#define NUC123_PWM_CH2_PIN_NONE 0x0
|
||||||
#define PWM_CLK_DIV_16 (0x03ul) /*!< Divide by 16 */
|
#define NUC123_PWM_CH2_PIN_PA14 0x1
|
||||||
|
#define NUC123_PWM_CH2_PIN_PC12 0x2
|
||||||
#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 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. */
|
/* 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. */
|
/* Configuration checks. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver data structures and types. */
|
/* 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. */
|
/* 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. */
|
/* External declarations. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if (NUC123_PWM_USE_PWM1 == TRUE) && !defined(__DOXYGEN__)
|
||||||
|
extern PWMDriver PWMD1;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
// void pwm_lld_init(void);
|
void pwm_lld_init(void);
|
||||||
// void pwm_lld_start(PWMDriver *pwmp);
|
void pwm_lld_start(PWMDriver *pwmp);
|
||||||
// void pwm_lld_stop(PWMDriver *pwmp);
|
void pwm_lld_stop(PWMDriver *pwmp);
|
||||||
// void pwm_lld_enable_channel(PWMDriver *pwmp,
|
void pwm_lld_enable_channel(PWMDriver *pwmp,
|
||||||
// pwmchannel_t channel,
|
pwmchannel_t channel,
|
||||||
// pwmcnt_t width);
|
pwmcnt_t width);
|
||||||
// void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel);
|
void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel);
|
||||||
// void pwm_lld_enable_periodic_notification(PWMDriver *pwmp);
|
void pwm_lld_enable_periodic_notification(PWMDriver *pwmp);
|
||||||
// void pwm_lld_disable_periodic_notification(PWMDriver *pwmp);
|
void pwm_lld_disable_periodic_notification(PWMDriver *pwmp);
|
||||||
// void pwm_lld_enable_channel_notification(PWMDriver *pwmp,
|
void pwm_lld_enable_channel_notification(PWMDriver *pwmp,
|
||||||
// pwmchannel_t channel);
|
pwmchannel_t channel);
|
||||||
// void pwm_lld_disable_channel_notification(PWMDriver *pwmp,
|
void pwm_lld_disable_channel_notification(PWMDriver *pwmp,
|
||||||
// pwmchannel_t channel);
|
pwmchannel_t channel);
|
||||||
// void pwm_lld_serve_interrupt(PWMDriver *pwmp);
|
void _pwm_lld_change_period(PWMDriver *pwmp, pwmcnt_t period);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// #endif /* HAL_USE_PWM */
|
#endif /* HAL_USE_PWM */
|
||||||
|
|
||||||
#endif /* HAL_PWM_LLD_H */
|
#endif /* HAL_PWM_LLD_H */
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,7 @@ PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
|
||||||
|
|
||||||
# Optional platform files.
|
# Optional platform files.
|
||||||
ifeq ($(USE_SMART_BUILD),yes)
|
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
|
endif
|
||||||
|
|
||||||
# Drivers compatible with the platform.
|
# 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/rt/rt_test.mk
|
||||||
#include $(CHIBIOS)/test/oslib/oslib_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
|
# C sources that can be compiled in ARM or THUMB mode depending on the global
|
||||||
# setting.
|
# setting.
|
||||||
CSRC = $(ALLCSRC) \
|
CSRC = $(ALLCSRC) \
|
||||||
|
@ -183,7 +186,6 @@ include $(RULESPATH)/rules.mk
|
||||||
# Custom rules
|
# Custom rules
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
OPENOCD:=$(shell readlink -f `which openocd`)
|
OPENOCD:=$(shell readlink -f `which openocd`)
|
||||||
OPENOCDPATH:=$(shell dirname $(OPENOCD))/../share/openocd
|
OPENOCDPATH:=$(shell dirname $(OPENOCD))/../share/openocd
|
||||||
|
|
||||||
|
@ -195,11 +197,3 @@ connect:
|
||||||
|
|
||||||
flash: $(BUILDDIR)/$(PROJECT).elf
|
flash: $(BUILDDIR)/$(PROJECT).elf
|
||||||
openocd -f ../scripts/interface/nulink.cfg -f ../scripts/target/numicroM0.cfg -c "program $< verify reset exit"
|
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