v0.5.3
- начальный загрузчик для плат elbear, elsomik обновлен до версии 0.2.0 - исключено появление краткосрочных просадок при работе ШИМ с максимальным коэффициентом заполнения - добавлена возможность пропускать код стандартного обработчика прерываний при использовании пользовательского обработчика - добавлена возможность конфигурирования вывода на вход с притяжкой к земле (INPUT_PULLDOWN) - исправление известных ошибок
This commit was merged in pull request #29.
This commit is contained in:
1 parent
8a675b2f61
commit
0fbfd77518
42 files changed
+1007
-762
No files matched your search
@@ -18,12 +18,12 @@ void __attribute__((weak)) IRremote_interrupt_handler(void)
|
||||
// dummy function for case when IRremote library is not in use
|
||||
}
|
||||
|
||||
void __attribute__((weak)) ISR(void)
|
||||
{
|
||||
bool __attribute__((section(".ram_text"), weak)) ISR(void)
|
||||
{
|
||||
/*
|
||||
A dummy function for the case when additional interrupts are not used in the project.
|
||||
In the project, you need to create a function of the form:
|
||||
extern "C" void ISR()
|
||||
extern "C" __attribute__((section(".ram_text"))) bool ISR(void)
|
||||
{
|
||||
if (EPIC_CHECK_TIMER16_1())
|
||||
{
|
||||
@@ -35,20 +35,31 @@ void __attribute__((weak)) ISR(void)
|
||||
// reset timer interrupt flags
|
||||
TIM16_CLEAR_INT_MASK(htimer16_1_, 0xFFFFFFFF);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
If you don't need to call standard trap_handler() code, you can return true from this function
|
||||
and trap_handler() code will be missed. But you must carefully clear interrupt flags by yourself
|
||||
in your custom ISR() function.
|
||||
|
||||
libraries required to use this example:
|
||||
#include "mik32_hal_timer16.h"
|
||||
#include "mik32_hal_irq.h"
|
||||
#include "wiring_LL.h"
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
// ---------------------------------------------- //
|
||||
void __attribute__((noinline, section(".ram_text"), optimize("O3"))) trap_handler (void)
|
||||
{
|
||||
// custom interrupt
|
||||
ISR();
|
||||
|
||||
if(ISR())
|
||||
{
|
||||
// reset all interrupts and miss trap_handler() code
|
||||
EPIC_CLEAR_ALL();
|
||||
return;
|
||||
}
|
||||
|
||||
// gpio interrupt
|
||||
if (EPIC_CHECK_GPIO_IRQ())
|
||||
gpio_interrupt_handler();
|
||||
@@ -77,6 +88,7 @@ void __attribute__((noinline, section(".ram_text"), optimize("O3"))) trap_handle
|
||||
if (EPIC_CHECK_I2C_0())
|
||||
wire_interrupt_handler(0);
|
||||
|
||||
// i2c1 interrupt
|
||||
if (EPIC_CHECK_I2C_1())
|
||||
wire_interrupt_handler(1);
|
||||
|
||||
|
||||
@@ -104,55 +104,64 @@ It is recommended to enable the timer in the following order:
|
||||
*/
|
||||
void analogWrite(uint32_t PinNumber, uint32_t writeVal)
|
||||
{
|
||||
if (writeVal > WriteValMax) writeVal = WriteValMax;
|
||||
|
||||
if (digitalPinPwmIsOn(PinNumber) > 0) // pin has pwm and pwm is already on
|
||||
if (writeVal >= WriteValMax)
|
||||
{
|
||||
// we can only change writeVal if it is differ from current value
|
||||
TIMER32_TypeDef* timer = pwmPinToTimer(PinNumber);
|
||||
uint32_t newOCR = (uint32_t) (((uint64_t)pwmTopVal * writeVal) / WriteValMax);
|
||||
if (timer->CHANNELS[pwmPinToTimerChannel(PinNumber)].OCR != newOCR)
|
||||
// if we need max value, use digitalWrite to supply constant level
|
||||
digitalWrite(PinNumber, HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we need less then max, use pwm
|
||||
int8_t pwmState = digitalPinPwmIsOn(PinNumber);
|
||||
|
||||
if (pwmState > 0) // pin has pwm and pwm is already on
|
||||
{
|
||||
// if new ocr differs from current, set new ocr
|
||||
timer->CHANNELS[pwmPinToTimerChannel(PinNumber)].OCR = newOCR;
|
||||
// we can only change writeVal if it is differ from current value
|
||||
TIMER32_TypeDef* timer = pwmPinToTimer(PinNumber);
|
||||
uint32_t newOCR = (uint32_t) (((uint64_t)pwmTopVal * writeVal) / WriteValMax);
|
||||
if (timer->CHANNELS[pwmPinToTimerChannel(PinNumber)].OCR != newOCR)
|
||||
{
|
||||
// if new ocr differs from current, set new ocr
|
||||
timer->CHANNELS[pwmPinToTimerChannel(PinNumber)].OCR = newOCR;
|
||||
}
|
||||
}
|
||||
else if (pwmState == 0) // pin has pwm and pwm is off
|
||||
{
|
||||
// init pin as pwm
|
||||
uint32_t OCRval = (pwmTopVal * writeVal) / WriteValMax;
|
||||
|
||||
// initialization of the required timer
|
||||
htimer32.Instance = pwmPinToTimer(PinNumber);
|
||||
htimer32.Top = pwmTopVal;
|
||||
htimer32.State = TIMER32_STATE_DISABLE;
|
||||
htimer32.Clock.Source = TIMER32_SOURCE_PRESCALER;
|
||||
htimer32.Clock.Prescaler = 0; // Prescaler = 1
|
||||
htimer32.InterruptMask = 0;
|
||||
htimer32.CountMode = TIMER32_COUNTMODE_FORWARD;
|
||||
HAL_Timer32_Init(&htimer32);
|
||||
|
||||
// gpio init as timer channel pin
|
||||
HAL_GPIO_PinConfig(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber),
|
||||
HAL_GPIO_MODE_TIMER_SERIAL, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
|
||||
|
||||
htimer32_channel.TimerInstance = htimer32.Instance;
|
||||
htimer32_channel.ChannelIndex = pwmPinToTimerChannel(PinNumber);
|
||||
htimer32_channel.PWM_Invert = TIMER32_CHANNEL_NON_INVERTED_PWM;
|
||||
htimer32_channel.Mode = TIMER32_CHANNEL_MODE_PWM;
|
||||
htimer32_channel.CaptureEdge = TIMER32_CHANNEL_CAPTUREEDGE_RISING;
|
||||
htimer32_channel.OCR = OCRval;
|
||||
htimer32_channel.Noise = TIMER32_CHANNEL_FILTER_OFF;
|
||||
HAL_Timer32_Channel_Init(&htimer32_channel);
|
||||
|
||||
// start timer with initialized channel
|
||||
HAL_Timer32_Channel_Enable(&htimer32_channel);
|
||||
HAL_Timer32_Value_Clear(&htimer32);
|
||||
HAL_Timer32_Start(&htimer32);
|
||||
pwmIsInited++; // increase inited channels qty
|
||||
}
|
||||
else // pin doesn't have pwm
|
||||
ErrorMsgHandler("analogWrite(): invalid pwm pin number");
|
||||
}
|
||||
else if (digitalPinPwmIsOn(PinNumber) == 0) // pin has pwm and pwm is off
|
||||
{
|
||||
// init pin as pwm
|
||||
uint32_t OCRval = (uint32_t) (((uint64_t)pwmTopVal * writeVal) / WriteValMax);
|
||||
|
||||
// initialization of the required timer
|
||||
htimer32.Instance = pwmPinToTimer(PinNumber);
|
||||
htimer32.Top = pwmTopVal;
|
||||
htimer32.State = TIMER32_STATE_DISABLE;
|
||||
htimer32.Clock.Source = TIMER32_SOURCE_PRESCALER;
|
||||
htimer32.Clock.Prescaler = 0; // Prescaler = 1
|
||||
htimer32.InterruptMask = 0;
|
||||
htimer32.CountMode = TIMER32_COUNTMODE_FORWARD;
|
||||
HAL_Timer32_Init(&htimer32);
|
||||
|
||||
// gpio init as timer channel pin
|
||||
HAL_GPIO_PinConfig(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber),
|
||||
HAL_GPIO_MODE_TIMER_SERIAL, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
|
||||
|
||||
htimer32_channel.TimerInstance = htimer32.Instance;
|
||||
htimer32_channel.ChannelIndex = pwmPinToTimerChannel(PinNumber);
|
||||
htimer32_channel.PWM_Invert = TIMER32_CHANNEL_NON_INVERTED_PWM;
|
||||
htimer32_channel.Mode = TIMER32_CHANNEL_MODE_PWM;
|
||||
htimer32_channel.CaptureEdge = TIMER32_CHANNEL_CAPTUREEDGE_RISING;
|
||||
htimer32_channel.OCR = OCRval;
|
||||
htimer32_channel.Noise = TIMER32_CHANNEL_FILTER_OFF;
|
||||
HAL_Timer32_Channel_Init(&htimer32_channel);
|
||||
|
||||
// start timer with initialized channel
|
||||
HAL_Timer32_Channel_Enable(&htimer32_channel);
|
||||
HAL_Timer32_Value_Clear(&htimer32);
|
||||
HAL_Timer32_Start(&htimer32);
|
||||
pwmIsInited++; // increase inited channels qty
|
||||
}
|
||||
else // pin doesn't have pwm
|
||||
ErrorMsgHandler("analogWrite(): invalid pwm pin number");
|
||||
}
|
||||
|
||||
// Set the resolution of analogWrite parameters
|
||||
|
||||
@@ -23,12 +23,14 @@
|
||||
#include <stdint.h>
|
||||
#include "wiring_private.h"
|
||||
|
||||
#define HIGH 0x1
|
||||
#define LOW 0x0
|
||||
#define INPUT 0x0
|
||||
#define OUTPUT 0x1
|
||||
#define INPUT_PULLUP 0x2
|
||||
#define NC 0xFFFFFFFF // Not connected
|
||||
#define HIGH 0x1
|
||||
#define LOW 0x0
|
||||
|
||||
#define INPUT 0x0
|
||||
#define OUTPUT 0x1
|
||||
#define INPUT_PULLUP 0x2
|
||||
#define INPUT_PULLDOWN 0x3
|
||||
#define NC 0xFFFFFFFF // Not connected
|
||||
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
#define HALF_PI 1.5707963267948966192313216916398
|
||||
|
||||
@@ -37,7 +37,7 @@ void pinMode(uint32_t PinNumber, uint32_t PinMode)
|
||||
return;
|
||||
}
|
||||
|
||||
if (digitalPinPwmIsOn(PinNumber))
|
||||
if (digitalPinPwmIsOn(PinNumber) > 0 )
|
||||
// if the pin use PWM, disable PWM
|
||||
analogWriteStop(PinNumber);
|
||||
|
||||
@@ -56,6 +56,10 @@ void pinMode(uint32_t PinNumber, uint32_t PinMode)
|
||||
GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_INPUT;
|
||||
GPIO_InitStruct.Pull = HAL_GPIO_PULL_UP;
|
||||
break;
|
||||
case INPUT_PULLDOWN:
|
||||
GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_INPUT;
|
||||
GPIO_InitStruct.Pull = HAL_GPIO_PULL_DOWN;
|
||||
break;
|
||||
case OUTPUT:
|
||||
GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_OUTPUT;
|
||||
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
|
||||
@@ -102,15 +106,22 @@ __attribute__((noinline, section(".ram_text"))) void digitalWrite(uint32_t PinNu
|
||||
ErrorMsgHandler("digitalWrite(): pin number exceeds the total number of pins");
|
||||
return;
|
||||
}
|
||||
|
||||
if (digitalPinPwmIsOn(PinNumber))
|
||||
|
||||
GPIO_TypeDef* port = digitalPinToPort(PinNumber);
|
||||
HAL_PinsTypeDef mask = digitalPinToBitMask(PinNumber);
|
||||
|
||||
if (digitalPinPwmIsOn(PinNumber) > 0)
|
||||
{
|
||||
// if the pin use PWM, disable PWM
|
||||
analogWriteStop(PinNumber);
|
||||
|
||||
// and configure pin as output
|
||||
HAL_GPIO_PinConfig(port, mask, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
|
||||
}
|
||||
|
||||
if (Val == HIGH)
|
||||
GPIO_SET_PIN(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber));
|
||||
GPIO_SET_PIN(port, mask);
|
||||
else
|
||||
GPIO_CLEAR_PIN(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber));
|
||||
GPIO_CLEAR_PIN(port, mask);
|
||||
}
|
||||
|
||||
// read pin
|
||||
@@ -122,9 +133,9 @@ __attribute__((noinline, section(".ram_text"))) int digitalRead(uint32_t PinNumb
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (digitalPinPwmIsOn(PinNumber))
|
||||
if (digitalPinPwmIsOn(PinNumber) > 0)
|
||||
// if the pin use PWM, disable PWM
|
||||
analogWriteStop(PinNumber);
|
||||
analogWriteStop(PinNumber); // pin is configured as input here
|
||||
|
||||
return GPIO_READ_PIN(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber));
|
||||
}
|
||||
@@ -138,11 +149,17 @@ __attribute__((noinline, section(".ram_text"))) void digitalToggle(uint32_t PinN
|
||||
return;
|
||||
}
|
||||
|
||||
if (digitalPinPwmIsOn(PinNumber))
|
||||
GPIO_TypeDef* port = digitalPinToPort(PinNumber);
|
||||
HAL_PinsTypeDef mask = digitalPinToBitMask(PinNumber);
|
||||
|
||||
if (digitalPinPwmIsOn(PinNumber) > 0)
|
||||
{
|
||||
// if the pin use PWM, disable PWM
|
||||
analogWriteStop(PinNumber);
|
||||
|
||||
GPIO_TOGGLE_PIN(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber));
|
||||
// and configure pin as output
|
||||
HAL_GPIO_PinConfig(port, mask, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
|
||||
}
|
||||
GPIO_TOGGLE_PIN(port, mask);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
Reference in new issue
Block a user