From 4b030d1ad81b6f83f83ad7447b17cfcfc8fd8b04 Mon Sep 17 00:00:00 2001 From: klassents Date: Thu, 5 Sep 2024 11:47:55 +0700 Subject: [PATCH 1/9] =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20?= =?UTF-8?q?=D1=81=20=D1=80=D0=B5=D0=B3=D0=B8=D1=81=D1=82=D1=80=D0=B0=D0=BC?= =?UTF-8?q?=D0=B8=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=B5=D1=81=D0=B5=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=BD=D0=B0=20=D1=83=D1=80=D0=BE=D0=B2=D0=B5=D0=BD?= =?UTF-8?q?=D1=8C=20hal.=20=D0=A2=D0=B0=D0=B9=D0=BC=D0=B5=D1=80=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D1=88=D0=B8=D0=BC=20=D0=B2=D1=8B=D0=BA=D0=BB=D1=8E?= =?UTF-8?q?=D1=87=D0=B0=D0=B5=D1=82=D1=81=D1=8F,=20=D1=82=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=BA=D0=BE=20=D0=B5=D1=81=D0=BB=D0=B8=20=D0=BD=D0=B5=20?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B0=D0=BB=D0=BE=D1=81=D1=8C=20=D0=B1=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D1=88=D0=B5=20=D0=B8=D0=BD=D0=B8=D1=86=D0=B8=D0=B0?= =?UTF-8?q?=D0=BB=D0=B8=D0=B7=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D1=85=20=D0=BA=D0=B0=D0=BD=D0=B0=D0=BB=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../peripherals/Include/mik32_hal_timer32.h | 1 + .../peripherals/Source/mik32_hal_timer32.c | 39 +++++++++++++++- cores/arduino/wiring_analog.c | 44 ++++++------------- 3 files changed, 53 insertions(+), 31 deletions(-) diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer32.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer32.h index 9b3f67e..e044dfd 100644 --- a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer32.h +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer32.h @@ -226,6 +226,7 @@ static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_Timer32_WaitF void HAL_TIMER32_MspInit(TIMER32_HandleTypeDef* htimer32); void HAL_TIMER32_Channel_MspInit(TIMER32_CHANNEL_HandleTypeDef* timerChannel); HAL_StatusTypeDef HAL_Timer32_Init(TIMER32_HandleTypeDef *timer); +HAL_StatusTypeDef HAL_Timer32_Deinit(TIMER32_HandleTypeDef *timer); void HAL_Timer32_State_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_StateTypeDef state); void HAL_Timer32_Top_Set(TIMER32_HandleTypeDef *timer, uint32_t top); void HAL_Timer32_Prescaler_Set(TIMER32_HandleTypeDef *timer, uint32_t prescaler); diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer32.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer32.c index f5b3fe0..ff715ce 100644 --- a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer32.c +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer32.c @@ -78,6 +78,41 @@ HAL_StatusTypeDef HAL_Timer32_Init(TIMER32_HandleTypeDef *timer) return HAL_OK; } +HAL_StatusTypeDef HAL_Timer32_Deinit(TIMER32_HandleTypeDef *timer) +{ + if ((timer->Instance != TIMER32_0) && (timer->Instance != TIMER32_1) && (timer->Instance != TIMER32_2)) + { + return HAL_ERROR; + } + + if (timer->Instance == TIMER32_0) + { + __HAL_PCC_TIMER32_0_CLK_DISABLE(); + } + + if (timer->Instance == TIMER32_1) + { + __HAL_PCC_TIMER32_1_CLK_DISABLE(); + if (timer->Clock.Source == TIMER32_SOURCE_TX_PAD) + HAL_GPIO_PinConfig(GPIO_0, GPIO_PIN_4, HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA); + } + + if (timer->Instance == TIMER32_2) + { + __HAL_PCC_TIMER32_2_CLK_DISABLE(); + if (timer->Clock.Source == TIMER32_SOURCE_TX_PAD) + HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_4, HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA); + } + + HAL_Timer32_InterruptMask_Clear(timer, 0xFFFFFFFF); + HAL_Timer32_Prescaler_Set(timer, 0); + HAL_Timer32_InterruptFlags_ClearMask(timer, 0xFFFFFFFF); + HAL_Timer32_InterruptFlags_Clear(timer); + + return HAL_OK; +} + + void HAL_Timer32_State_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_StateTypeDef state) { timer->State = state; @@ -199,7 +234,7 @@ HAL_StatusTypeDef HAL_Timer32_Channel_Init(TIMER32_CHANNEL_HandleTypeDef *timerC return HAL_ERROR; } - HAL_TIMER32_Channel_MspInit(timerChannel); + // HAL_TIMER32_Channel_MspInit(timerChannel); // здесь инициализируются сразу все каналы выбранного таймера, а нам такого не надо timerChannel->Instance = (TIMER32_CHANNEL_TypeDef *)&(timerChannel->TimerInstance->CHANNELS[timerChannel->ChannelIndex]); @@ -220,6 +255,8 @@ HAL_StatusTypeDef HAL_Timer32_Channel_DeInit(TIMER32_CHANNEL_HandleTypeDef *time return HAL_ERROR; } + timerChannel->Instance = (TIMER32_CHANNEL_TypeDef *)&(timerChannel->TimerInstance->CHANNELS[timerChannel->ChannelIndex]); + HAL_Timer32_Channel_Disable(timerChannel); HAL_Timer32_Channel_CaptureEdge_Set(timerChannel, 0); HAL_Timer32_Channel_ICR_Clear(timerChannel); diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index 75449a2..2a8421a 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -68,25 +68,8 @@ static TIMER32_HandleTypeDef htimer32; static TIMER32_CHANNEL_HandleTypeDef htimer32_channel; static uint32_t WriteValMax = WRITE_VAL_MAX_DEFAULT; static uint32_t pwmTopVal = PWM_TOP_VAL_DEFAULT; -static bool pwmIsInited = false; +static uint8_t pwmIsInited = 0; -HAL_StatusTypeDef Timer32_Channel_Init(TIMER32_CHANNEL_HandleTypeDef *timerChannel) -{ - if (timerChannel->TimerInstance == TIMER32_0) - return HAL_ERROR; - - // gpio init removed from standard function - - timerChannel->Instance = (TIMER32_CHANNEL_TypeDef *)&(timerChannel->TimerInstance->CHANNELS[timerChannel->ChannelIndex]); - HAL_Timer32_Channel_PWM_Invert_Set(timerChannel, timerChannel->PWM_Invert); - HAL_Timer32_Channel_Mode_Set(timerChannel, timerChannel->Mode); - HAL_Timer32_Channel_CaptureEdge_Set(timerChannel, timerChannel->CaptureEdge); - HAL_Timer32_Channel_OCR_Set(timerChannel, timerChannel->OCR); - HAL_Timer32_Channel_ICR_Clear(timerChannel); - HAL_Timer32_Channel_Noise_Set(timerChannel, timerChannel->Noise); - - return HAL_OK; -} /* It is recommended to enable the timer in the following order: @@ -120,15 +103,15 @@ void analogWrite(uint32_t PinNumber, uint32_t writeVal) htimer32_channel.PWM_Invert = TIMER32_CHANNEL_NON_INVERTED_PWM; htimer32_channel.Mode = TIMER32_CHANNEL_MODE_PWM; htimer32_channel.CaptureEdge = TIMER32_CHANNEL_CAPTUREEDGE_RISING; - // cast to uint64_t to avoid overflow when multiplying htimer32_channel.OCR = (uint32_t) (((uint64_t)pwmTopVal * writeVal) / WriteValMax); htimer32_channel.Noise = TIMER32_CHANNEL_FILTER_OFF; - Timer32_Channel_Init(&htimer32_channel); + 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 = true; // if at least one channel is working, say that the module is initialized + pwmIsInited++; // increase inited channels qty } else if(PinNumber == 10) // pin d10 has pwm, but you cannot use it while spi is running ErrorMsgHandler("analogWrite(): D10 cannot be used as PWM pin while SPI is running"); @@ -165,21 +148,22 @@ It is recommended to turn off the timer in the following order: */ void analogWriteStop(uint32_t PinNumber) { - if (pwmIsInited) + if (pwmIsInited > 0) { // load the timer address and channel number corresponding to the specified pin htimer32.Instance = pwmPinToTimer(PinNumber); htimer32_channel.TimerInstance = htimer32.Instance; htimer32_channel.ChannelIndex = pwmPinToTimerChannel(PinNumber); - // in the initChannel function they do it inside, but in deinit they don't. We do it outside - htimer32_channel.Instance = (TIMER32_CHANNEL_TypeDef *)&(htimer32_channel.TimerInstance->CHANNELS[htimer32_channel.ChannelIndex]); - // и все чистим/отключаем - HAL_Timer32_InterruptMask_Clear(&htimer32, 0xFFFFFFFF); - HAL_Timer32_Prescaler_Set(&htimer32, 0); - HAL_Timer32_InterruptFlags_ClearMask(&htimer32, 0xFFFFFFFF); + // deinit channel HAL_Timer32_Channel_DeInit(&htimer32_channel); - HAL_Timer32_Stop(&htimer32); - pwmIsInited = false; + pwmIsInited--; // decrease inited channels qty + + // stop timer if no inited channels left + if (pwmIsInited == 0) + { + HAL_Timer32_Stop(&htimer32); + HAL_Timer32_Deinit(&htimer32); + } } } -- 2.43.0 From 46f68aef2f98ecb50bd6b1fbc2d01da331d04a39 Mon Sep 17 00:00:00 2001 From: klassents Date: Thu, 5 Sep 2024 16:57:35 +0700 Subject: [PATCH 2/9] =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20?= =?UTF-8?q?=D1=81=20=D1=80=D0=B5=D0=B3=D0=B8=D1=81=D1=82=D1=80=D0=B0=D0=BC?= =?UTF-8?q?=D0=B8=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=B5=D1=81=D0=B5=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=B2=20hal,=D0=B2=D1=8B=D0=B7=D1=8B=D0=B2=D0=B0?= =?UTF-8?q?=D0=B5=D0=BC=D1=8B=D0=B5=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8?= =?UTF-8?q?=D0=B8=20=D0=B2=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D1=8F=D1=85=20?= =?UTF-8?q?tim16,=20gpio=20=D0=BE=D0=BF=D1=80=D0=B5=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=BA=D0=B0=D0=BA=20inline?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cores/arduino/Tone.cpp | 15 ++-- .../hal/peripherals/Include/mik32_hal_gpio.h | 83 +++++++++++++++-- .../peripherals/Include/mik32_hal_timer16.h | 32 ++++++- .../hal/peripherals/Source/mik32_hal_gpio.c | 88 ------------------- .../peripherals/Source/mik32_hal_timer16.c | 20 ----- 5 files changed, 115 insertions(+), 123 deletions(-) diff --git a/cores/arduino/Tone.cpp b/cores/arduino/Tone.cpp index 4977133..81899f3 100644 --- a/cores/arduino/Tone.cpp +++ b/cores/arduino/Tone.cpp @@ -100,7 +100,7 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) HAL_EPIC_MaskLevelSet(HAL_EPIC_TIMER16_1_MASK); pinMode(pin, OUTPUT); - timer_pin_port->CLEAR = timer_pin_mask; + HAL_GPIO_WritePin((GPIO_TypeDef *)timer_pin_port, timer_pin_mask, GPIO_PIN_LOW); HAL_Timer16_Counter_Start_IT(&htimer16_1, frequencyParams.period_ticks); timerIsOn = true; @@ -124,8 +124,9 @@ void noTone(uint8_t pin) { if (timerIsOn) { - timer_pin_port->CLEAR = timer_pin_mask; // pin to 0 - htimer16_1.Instance->CR &= ~TIMER16_CR_ENABLE_M; // disable timer + // pin to 0 + HAL_GPIO_WritePin((GPIO_TypeDef *)timer_pin_port, timer_pin_mask, GPIO_PIN_LOW); + HAL_Timer16_Disable(&htimer16_1); // disable timer HAL_EPIC_MaskLevelClear(HAL_EPIC_TIMER16_1_MASK); pinMode(pin, INPUT); // deinit pin timer_pin = -1; // reset to default @@ -136,12 +137,12 @@ void noTone(uint8_t pin) // irq handler extern "C" void tone_interrupt_handler(void) { - if ((htimer16_1.Instance->ISR & htimer16_1.Instance->IER) & TIMER16_ISR_ARR_MATCH_M) + if(HAL_Timer16_GetInterruptStatus_ARRM(&htimer16_1)) { // timer period has passed, change the pin state if (timer_toggle_count != 0) { - timer_pin_port->OUTPUT_ ^= timer_pin_mask; + HAL_GPIO_TogglePin((GPIO_TypeDef*)timer_pin_port, timer_pin_mask); if (timer_toggle_count > 0) timer_toggle_count--; @@ -149,10 +150,10 @@ extern "C" void tone_interrupt_handler(void) else { // turn off if the specified duration has passed - timer_pin_port->CLEAR = timer_pin_mask; + HAL_GPIO_WritePin((GPIO_TypeDef *)timer_pin_port, timer_pin_mask, GPIO_PIN_LOW); noTone(timer_pin); } } // reset timer interrupt flags - htimer16_1.Instance->ICR = 0xFFFFFFFF; + HAL_Timer16_ClearInterruptMask(&htimer16_1, 0xFFFFFFFF); } \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h index b3a6776..e398583 100644 --- a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h @@ -375,14 +375,85 @@ typedef enum __HAL_GPIO_InterruptMode HAL_StatusTypeDef HAL_GPIO_Init(GPIO_TypeDef *GPIO_x, GPIO_InitTypeDef *GPIO_Init); HAL_StatusTypeDef HAL_GPIO_PinConfig(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, HAL_GPIO_ModeTypeDef mode, HAL_GPIO_PullTypeDef pull, HAL_GPIO_DSTypeDef driveStrength); -GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin); -void HAL_GPIO_WritePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, GPIO_PinState pinState); -void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin); HAL_StatusTypeDef HAL_GPIO_InitInterruptLine(HAL_GPIO_Line_Config mux, HAL_GPIO_InterruptMode mode); HAL_StatusTypeDef HAL_GPIO_DeInitInterruptLine(HAL_GPIO_Line irqLine); -uint32_t HAL_GPIO_LineInterruptState(HAL_GPIO_Line irqLine); -GPIO_PinState HAL_GPIO_LinePinState(HAL_GPIO_Line irqLine); -void HAL_GPIO_ClearInterrupts(); + +/** + * @brief Считать текущее состояние выводов порта GPIO_x. + * @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2). + * @param pin маска выводов порта GPIO_x, с которых считывание значение. + * @return @ref GPIO_PIN_HIGH если с одного или больше выводов, указанных в pin, считалась 1. Иначе @ref GPIO_PIN_LOW. + */ +static inline __attribute__((always_inline)) GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin) +{ + if ((GPIO_x->SET & pin) != (uint32_t)GPIO_PIN_LOW) + return GPIO_PIN_HIGH; + else + return GPIO_PIN_LOW; +} + +/** + * @brief Задать логический уровень выходного сигнала для указанных выводов порта GPIO_x. + * @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2). + * @param pin маска выводов порта GPIO_x, к которым применяются указанные настройки. + * @param pinState значение состояние вывода, в которое будут установлены указанные выводы. + * Этот параметр должен быть одним из значений: + * - @ref GPIO_PIN_LOW низкий выходной уровень + * - @ref GPIO_PIN_HIGH высокий выходной уровень + */ +static inline __attribute__((always_inline)) void HAL_GPIO_WritePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, GPIO_PinState pinState) +{ + if (pinState == GPIO_PIN_LOW) + GPIO_x->CLEAR = pin; + else + GPIO_x->SET = pin; +} + +/** + * @brief Переключить логический уровень выходного сигнала для указанных выводов порта GPIO_x. + * @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2). + * @param pin маска выводов порта GPIO_x, к которым применяются указанные настройки. + */ +static inline __attribute__((always_inline)) void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin) +{ + GPIO_x->OUTPUT_ ^= pin; +} + +/** + * @brief Получить состояние линии прерывания. + * @param irqLine номер линии прерывания. + * @return Возвращает 1 если сработало прерывание данной линии, иначе 0. + */ +static inline __attribute__((always_inline)) uint32_t HAL_GPIO_LineInterruptState(HAL_GPIO_Line irqLine) +{ + int irq_line_num = irqLine >> GPIO_IRQ_LINE_S; + return (GPIO_IRQ->INTERRUPT & (1 << (irq_line_num))) != 0; +} + +/** + * @brief Функция чтения логического уровня вывода, подключенного к линии прерывания. + * @param irqLine номер линии прерывания. + * @return Логический уровень вывода. + */ +static inline __attribute__((always_inline)) GPIO_PinState HAL_GPIO_LinePinState(HAL_GPIO_Line irqLine) +{ + int irq_line_num = irqLine >> GPIO_IRQ_LINE_S; + return (GPIO_PinState)((GPIO_IRQ->STATE & (1 << (irq_line_num))) >> irq_line_num); +} + +/** + * @brief Функция сброса регистра состояния прерываний. + * @note Когда срабатывает прерывание на одной из линии, в регистре INTERRUPT + * выставляется 1 в разряде, соответствующем линии прерывания. + * После обработки прерывания необходимо сбросить данный регистр + * в обработчике прерывания trap_handler(). + * Если после обработки прерывания регистр не был сброшен, + * обработчик будет вызван снова, программа будет бесконечно вызывать обработчик. + */ +static inline __attribute__((always_inline)) void HAL_GPIO_ClearInterrupts() +{ + GPIO_IRQ->CLEAR = 0b11111111; +} #ifdef __cplusplus } diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer16.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer16.h index 873a26f..60dcc2c 100644 --- a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer16.h +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_timer16.h @@ -230,8 +230,6 @@ typedef struct __Timer16_HandleTypeDef void HAL_TIMER16_MspInit(Timer16_HandleTypeDef* htimer16); -void HAL_Timer16_Disable(Timer16_HandleTypeDef *htimer16); -void HAL_Timer16_Enable(Timer16_HandleTypeDef *htimer16); void HAL_Timer16_SetActiveEdge(Timer16_HandleTypeDef *htimer16, uint8_t ActiveEdge); void HAL_Timer16_SetSourceClock(Timer16_HandleTypeDef *htimer16, uint8_t SourceClock); void HAL_Timer16_SetCountMode(Timer16_HandleTypeDef *htimer16, uint8_t CountMode); @@ -278,6 +276,26 @@ void HAL_Timer16_SetInterruptARRM(Timer16_HandleTypeDef *htimer16); void HAL_Timer16_SetInterruptCMPM(Timer16_HandleTypeDef *htimer16); void HAL_Timer16_InterruptInit(Timer16_HandleTypeDef *htimer16); +/** + * @brief Выключить таймер. + * Может использоваться для отключения таймера или при записи в регистр CFGR. + * + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +static inline void __attribute__((always_inline)) HAL_Timer16_Disable(Timer16_HandleTypeDef *htimer16) +{ + htimer16->Instance->CR &= ~TIMER16_CR_ENABLE_M; +} + +/** + * @brief Включить таймер + * @param htimer16 Указатель на структуру с настройками Timer16. + */ +static inline void __attribute__((always_inline)) HAL_Timer16_Enable(Timer16_HandleTypeDef *htimer16) +{ + htimer16->Instance->CR |= TIMER16_CR_ENABLE_M; +} + /** * @brief Получить статус прерываний Timer16. * Функция возвращает статус прерываний в соответствии с маской разрешенный прерываний. @@ -291,6 +309,16 @@ static inline __attribute__((always_inline)) uint32_t HAL_Timer16_GetInterruptSt return interrupt_status; } +/** + * @brief Получить статус прерывания по соответствию автозагрузке ARRM + * @param htimer16 Указатель на структуру с настройками Timer16 + * @return Статус прерывания ARRM - true, если прерывание сработало + */ +static inline __attribute__((always_inline)) bool HAL_Timer16_GetInterruptStatus_ARRM(Timer16_HandleTypeDef *htimer16) +{ + return (bool)((htimer16->Instance->ISR & htimer16->Instance->IER) & TIMER16_ISR_ARR_MATCH_M); +} + /** * @brief Очистить флаг прерывания. * @param htimer16 Указатель на структуру с настройками Timer16. diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_gpio.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_gpio.c index ea3e1ae..ce6ae55 100644 --- a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_gpio.c +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_gpio.c @@ -93,58 +93,6 @@ HAL_StatusTypeDef HAL_GPIO_PinConfig(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, return HAL_GPIO_Init(GPIO_x, &GPIO_InitStruct); } -/** - * @brief Считать текущее состояние выводов порта GPIO_x. - * @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2). - * @param pin маска выводов порта GPIO_x, с которых считывание значение. - * @return @ref GPIO_PIN_HIGH если с одного или больше выводов, указанных в pin, считалась 1. Иначе @ref GPIO_PIN_LOW. - */ -GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin) -{ - GPIO_PinState bitStatus; - - if ((GPIO_x->SET & pin) != (uint32_t)GPIO_PIN_LOW) - { - bitStatus = GPIO_PIN_HIGH; - } - else - { - bitStatus = GPIO_PIN_LOW; - } - return bitStatus; -} - -/** - * @brief Задать логический уровень выходного сигнала для указанных выводов порта GPIO_x. - * @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2). - * @param pin маска выводов порта GPIO_x, к которым применяются указанные настройки. - * @param pinState значение состояние вывода, в которое будут установлены указанные выводы. - * Этот параметр должен быть одним из значений: - * - @ref GPIO_PIN_LOW низкий выходной уровень - * - @ref GPIO_PIN_HIGH высокий выходной уровень - */ -void HAL_GPIO_WritePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, GPIO_PinState pinState) -{ - if (pinState == GPIO_PIN_LOW) - { - GPIO_x->CLEAR = pin; - } - else - { - GPIO_x->SET = pin; - } -} - -/** - * @brief Переключить логический уровень выходного сигнала для указанных выводов порта GPIO_x. - * @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2). - * @param pin маска выводов порта GPIO_x, к которым применяются указанные настройки. - */ -void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin) -{ - GPIO_x->OUTPUT_ ^= pin; -} - /** * @brief Функция инициализации линии прерывания. * \param mux настройка мультиплексора линии прерывания. @@ -222,39 +170,3 @@ HAL_StatusTypeDef HAL_GPIO_DeInitInterruptLine(HAL_GPIO_Line irqLine) return HAL_OK; } - -/** - * @brief Получить состояние линии прерывания. - * @param irqLine номер линии прерывания. - * @return Возвращает 1 если сработало прерывание данной линии, иначе 0. - */ -uint32_t HAL_GPIO_LineInterruptState(HAL_GPIO_Line irqLine) -{ - int irq_line_num = irqLine >> GPIO_IRQ_LINE_S; - return (GPIO_IRQ->INTERRUPT & (1 << (irq_line_num))) != 0; -} - -/** - * @brief Функция чтения логического уровня вывода, подключенного к линии прерывания. - * @param irqLine номер линии прерывания. - * @return Логический уровень вывода. - */ -GPIO_PinState HAL_GPIO_LinePinState(HAL_GPIO_Line irqLine) -{ - int irq_line_num = irqLine >> GPIO_IRQ_LINE_S; - return (GPIO_PinState)((GPIO_IRQ->STATE & (1 << (irq_line_num))) >> irq_line_num); -} - -/** - * @brief Функция сброса регистра состояния прерываний. - * @note Когда срабатывает прерывание на одной из линии, в регистре INTERRUPT - * выставляется 1 в разряде, соответствующем линии прерывания. - * После обработки прерывания необходимо сбросить данный регистр - * в обработчике прерывания trap_handler(). - * Если после обработки прерывания регистр не был сброшен, - * обработчик будет вызван снова, программа будет бесконечно вызывать обработчик. - */ -void HAL_GPIO_ClearInterrupts() -{ - GPIO_IRQ->CLEAR = 0b11111111; -} diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer16.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer16.c index 7bcda80..8756bb7 100644 --- a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer16.c +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_timer16.c @@ -99,26 +99,6 @@ __attribute__((weak)) void HAL_TIMER16_MspInit(Timer16_HandleTypeDef* htimer16) } } -/** - * @brief Выключить таймер. - * Может использоваться для отключения таймера или при записи в регистр CFGR. - * - * @param htimer16 Указатель на структуру с настройками Timer16. - */ -void HAL_Timer16_Disable(Timer16_HandleTypeDef *htimer16) -{ - htimer16->Instance->CR &= ~TIMER16_CR_ENABLE_M; -} - -/** - * @brief Включить таймер - * @param htimer16 Указатель на структуру с настройками Timer16. - */ -void HAL_Timer16_Enable(Timer16_HandleTypeDef *htimer16) -{ - htimer16->Instance->CR |= TIMER16_CR_ENABLE_M; -} - /** * @brief Установить активный фронт для подсчёта или задать подрежим энкодера. * Используется при тактировании Timer16 от внешнего источника тактового сигнала на выводе Input1. -- 2.43.0 From 670c48acab558af1d3d18b8d45137e6c09a596bd Mon Sep 17 00:00:00 2001 From: klassents Date: Fri, 6 Sep 2024 11:15:19 +0700 Subject: [PATCH 3/9] =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20?= =?UTF-8?q?=D1=81=20=D1=80=D0=B5=D0=B3=D0=B8=D1=81=D1=82=D1=80=D0=B0=D0=BC?= =?UTF-8?q?=D0=B8=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=B5=D1=81=D0=B5=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=B2=20hal,=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=B5=20?= =?UTF-8?q?=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8=20=D1=82=D0=B8=D0=BF?= =?UTF-8?q?=D0=B0=20inline?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 6 ++ .../hal/peripherals/Include/mik32_hal_i2c.h | 58 +++++++++++++++- .../hal/peripherals/Source/mik32_hal_i2c.c | 36 +++++----- libraries/Wire/src/utility/twi.c | 69 +++++++------------ variants/standart/pins_arduino.h | 2 +- 5 files changed, 105 insertions(+), 66 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..69cabaf --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "files.associations": { + "mik32_hal_irq.h": "c", + "mik32_hal_i2c.h": "c" + } +} \ No newline at end of file diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_i2c.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_i2c.h index 68a5a6c..547f48b 100644 --- a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_i2c.h +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_i2c.h @@ -380,9 +380,6 @@ typedef struct void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c); -void HAL_I2C_Disable(I2C_HandleTypeDef *hi2c); -void HAL_I2C_Reset(I2C_HandleTypeDef *hi2c); -void HAL_I2C_Enable(I2C_HandleTypeDef *hi2c); void HAL_I2C_AnalogFilterInit(I2C_HandleTypeDef *hi2c, HAL_I2C_AnalogFilterTypeDef AnalogFilter); void HAL_I2C_DigitalFilterInit(I2C_HandleTypeDef *hi2c, HAL_I2C_DigitalFilterTypeDef DigitalFilter); void HAL_I2C_SetClockSpeed(I2C_HandleTypeDef *hi2c); @@ -394,6 +391,7 @@ void HAL_I2C_SBCMode(I2C_HandleTypeDef *hi2c, HAL_I2C_SBCModeTypeDef SBCMode); void HAL_I2C_SlaveInit(I2C_HandleTypeDef *hi2c); void HAL_I2C_MasterInit(I2C_HandleTypeDef *hi2c); HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c); +HAL_StatusTypeDef HAL_I2C_Deinit(I2C_HandleTypeDef *hi2c); void HAL_I2C_AutoEnd(I2C_HandleTypeDef *hi2c, HAL_I2C_AutoEndModeTypeDef AutoEnd); HAL_StatusTypeDef HAL_I2C_Master_WaitTXIS(I2C_HandleTypeDef *hi2c, uint32_t Timeout); HAL_StatusTypeDef HAL_I2C_Master_WaitRXNE(I2C_HandleTypeDef *hi2c, uint32_t Timeout); @@ -427,6 +425,60 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pDa HAL_StatusTypeDef HAL_I2C_Slave_Receive_NOSTRETCH_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize); HAL_StatusTypeDef HAL_I2C_Slave_ReceiveSBC_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize); + +static inline __attribute__((always_inline)) void HAL_I2C_Disable(I2C_HandleTypeDef *hi2c) +{ + hi2c->Instance->CR1 &= ~I2C_CR1_PE_M; +} + +static inline __attribute__((always_inline)) void HAL_I2C_Reset(I2C_HandleTypeDef *hi2c) +{ + hi2c->ErrorCode = I2C_ERROR_NONE; + + hi2c->Instance->CR1 &= ~I2C_CR1_PE_M; + hi2c->Instance->CR1 |= I2C_CR1_PE_M; +} + +static inline __attribute__((always_inline)) void HAL_I2C_Enable(I2C_HandleTypeDef *hi2c) +{ + hi2c->Instance->CR1 |= I2C_CR1_PE_M; +} + +static inline __attribute__((always_inline)) void HAL_I2C_Reset_Interrupt_Flag(I2C_HandleTypeDef *hi2c, uint32_t mask) +{ + hi2c->Instance->ICR |= mask; +} + +static inline __attribute__((always_inline)) void HAL_I2C_Reset_TXDR_Content(I2C_HandleTypeDef *hi2c) +{ + hi2c->Instance->ISR |= I2C_ISR_TXE_M; +} + +static inline __attribute__((always_inline)) uint32_t HAL_I2C_Get_Interrupts_Status(I2C_HandleTypeDef *hi2c) +{ + return hi2c->Instance->ISR; +} + +static inline __attribute__((always_inline)) uint32_t HAL_I2C_Get_CR1_Content(I2C_HandleTypeDef *hi2c) +{ + return hi2c->Instance->CR1; +} + +static inline __attribute__((always_inline)) void HAL_I2C_Write_TXDR(I2C_HandleTypeDef *hi2c, uint8_t value) +{ + hi2c->Instance->TXDR = value; +} + +static inline __attribute__((always_inline)) uint8_t HAL_I2C_Get_RXDR(I2C_HandleTypeDef *hi2c) +{ + return hi2c->Instance->RXDR; +} + +static inline __attribute__((always_inline)) void HAL_I2C_Clear_Reload(I2C_HandleTypeDef *hi2c) +{ + hi2c->Instance->CR2 &= ~I2C_CR2_RELOAD_M; +} + static inline __attribute__((always_inline)) void HAL_I2C_ADDR_IRQ(I2C_HandleTypeDef *hi2c) { if (hi2c->Instance->CR1 & I2C_CR1_SBC_M) diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_i2c.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_i2c.c index 2a2cd16..f44138a 100644 --- a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_i2c.c +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_i2c.c @@ -26,24 +26,6 @@ __attribute__((weak)) void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c) } -void HAL_I2C_Disable(I2C_HandleTypeDef *hi2c) -{ - hi2c->Instance->CR1 &= ~I2C_CR1_PE_M; -} - -void HAL_I2C_Reset(I2C_HandleTypeDef *hi2c) -{ - hi2c->ErrorCode = I2C_ERROR_NONE; - - hi2c->Instance->CR1 &= ~I2C_CR1_PE_M; - hi2c->Instance->CR1 |= I2C_CR1_PE_M; -} - -void HAL_I2C_Enable(I2C_HandleTypeDef *hi2c) -{ - hi2c->Instance->CR1 |= I2C_CR1_PE_M; -} - void HAL_I2C_AnalogFilterInit(I2C_HandleTypeDef *hi2c, HAL_I2C_AnalogFilterTypeDef AnalogFilter) { hi2c->Init.AnalogFilter = AnalogFilter; @@ -244,6 +226,24 @@ HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c) return HAL_OK; } +HAL_StatusTypeDef HAL_I2C_Deinit(I2C_HandleTypeDef *hi2c) +{ + HAL_I2C_Disable(hi2c); + + if (hi2c->Instance == I2C_0) + { + __HAL_PCC_I2C_0_CLK_DISABLE(); + HAL_GPIO_PinConfig(GPIO_0, GPIO_PIN_9 | GPIO_PIN_10, HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA); + } + else if(hi2c->Instance == I2C_1) + { + __HAL_PCC_I2C_1_CLK_DISABLE(); + HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_12 | GPIO_PIN_13, HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA); + } + + return HAL_OK; +} + void HAL_I2C_AutoEnd(I2C_HandleTypeDef *hi2c, HAL_I2C_AutoEndModeTypeDef AutoEnd) { hi2c->Instance->CR2 &= ~I2C_CR2_AUTOEND_M; diff --git a/libraries/Wire/src/utility/twi.c b/libraries/Wire/src/utility/twi.c index 2483806..0d4c86b 100644 --- a/libraries/Wire/src/utility/twi.c +++ b/libraries/Wire/src/utility/twi.c @@ -88,36 +88,22 @@ void twi_deinit(void) { uint32_t EPICmask; - HAL_I2C_Disable(&hi2c); - // disable clock #if I2C_NUM == 0 hi2c.Instance = I2C_0; EPICmask = HAL_EPIC_I2C_0_MASK; - __HAL_PCC_I2C_0_CLK_DISABLE(); #elif I2C_NUM == 1 hi2c.Instance = I2C_1; EPICmask = HAL_EPIC_I2C_1_MASK; - __HAL_PCC_I2C_1_CLK_DISABLE(); #else #error "Unsupported I2C_NUM value in pins_arduino.h" #endif + HAL_I2C_Deinit(&hi2c); + // for slave mode disable interrupts from i2c if (hi2c.Init.Mode == HAL_I2C_MODE_SLAVE) HAL_EPIC_MaskLevelClear(EPICmask); - // reconfigure pins to z state - GPIO_InitTypeDef GPIO_InitStruct; - memset(&GPIO_InitStruct, 0, sizeof(GPIO_InitStruct)); - // SDA - GPIO_InitStruct.Pin = (HAL_PinsTypeDef)digitalPinToBitMask(PIN_WIRE_SDA); - GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_INPUT; - GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; - HAL_GPIO_Init(digitalPinToPort(PIN_WIRE_SDA), &GPIO_InitStruct); - // SCL - GPIO_InitStruct.Pin = (HAL_PinsTypeDef)digitalPinToBitMask(PIN_WIRE_SCL); - HAL_GPIO_Init(digitalPinToPort(PIN_WIRE_SCL), &GPIO_InitStruct); - twiIsOn = false; } @@ -252,7 +238,7 @@ uint8_t twi_masterWriteTo(uint8_t address, uint8_t* data, uint8_t length, uint8_ // parse errors // check separately, because in hal libraries not all functions look at this - if (hi2c.Instance->ISR & I2C_ISR_NACKF_M) + if (HAL_I2C_Get_Interrupts_Status(&hi2c) & I2C_ISR_NACKF_M) hi2c.ErrorCode = I2C_ERROR_NACK; if (hi2c.ErrorCode == (HAL_I2C_ErrorTypeDef)I2C_ERROR_TIMEOUT) ret = I2C_TIMEOUT; // timeout else if (hi2c.ErrorCode == (HAL_I2C_ErrorTypeDef)I2C_ERROR_NACK) ret = I2C_NACK_DATA; // didn't receive ACK @@ -275,39 +261,35 @@ i2c_status_e twi_slaveWrite(uint8_t *txData, uint8_t bytesNum) if ((hi2c.ErrorCode != I2C_ERROR_NONE)) HAL_I2C_Reset(&hi2c); - // отправка данных + // send data HAL_StatusTypeDef error_code = HAL_OK; - - hi2c.Instance->CR2 &= ~I2C_CR2_RELOAD_M; + HAL_I2C_Clear_Reload(&hi2c); + if (!(HAL_I2C_Get_CR1_Content(&hi2c) & I2C_CR1_NOSTRETCH_M)) // NOSTRETCH = 0 + HAL_I2C_Reset_TXDR_Content(&hi2c); + HAL_I2C_Write_TXDR(&hi2c, txData[0]); // first recording is made in advance - if (!(hi2c.Instance->CR1 & I2C_CR1_NOSTRETCH_M)) // NOSTRETCH = 0 - hi2c.Instance->ISR |= I2C_ISR_TXE_M; // Reset TXDR contents - - hi2c.Instance->TXDR = txData[0]; // The first recording is made in advance - - // Запись байта + // write byte for (uint32_t tx_count = 1; tx_count < bytesNum; tx_count++) { if ((error_code = HAL_I2C_Slave_WaitTXIS(&hi2c, TIMEOUT_TICKS)) != HAL_OK) { - // неудачная запись - hi2c.Instance->ISR |= I2C_ISR_TXE_M; // Reset TXDR contents - hi2c.Instance->ICR |= I2C_ICR_STOPCF_M; // Clear the STOP detection flag on the bus + // failed to write + HAL_I2C_Reset_TXDR_Content(&hi2c); + HAL_I2C_Reset_Interrupt_Flag(&hi2c, I2C_ICR_STOPCF_M); // Clear the STOP detection flag on the bus HAL_I2C_Reset(&hi2c); return I2C_TIMEOUT; } - hi2c.Instance->TXDR = txData[tx_count]; + HAL_I2C_Write_TXDR(&hi2c, txData[tx_count]); } if ((error_code = HAL_I2C_WaitBusy(&hi2c, TIMEOUT_TICKS)) != HAL_OK) { - // неудачное завершение транзакции + // failed to complete transaction HAL_I2C_Reset(&hi2c); return I2C_TIMEOUT; } - - hi2c.Instance->ISR |= I2C_ISR_TXE_M; // Reset TXDR contents - hi2c.Instance->ICR |= I2C_ICR_STOPCF_M; // Clear the STOP detection flag on the bus + HAL_I2C_Reset_TXDR_Content(&hi2c); + HAL_I2C_Reset_Interrupt_Flag(&hi2c, I2C_ICR_STOPCF_M); // Clear the STOP detection flag on the bus return I2C_OK; } @@ -343,25 +325,24 @@ void twi_attachSlaveTxEvent( void (*function)(void) ) */ void twi_interruptHandler(void) { - uint32_t int_mask = hi2c.Instance->CR1 & I2C_INTMASK; // interrupts allowed - uint32_t interrupt_status = hi2c.Instance->ISR; // current flags + uint32_t int_mask = HAL_I2C_Get_CR1_Content(&hi2c) & I2C_INTMASK; // interrupts allowed + uint32_t interrupt_status = HAL_I2C_Get_Interrupts_Status(&hi2c); // current flags // master calls by address, device in slave mode if ((interrupt_status & I2C_ISR_ADDR_M) && (int_mask & I2C_CR1_ADDRIE_M)) { // reset ADDR flag - hi2c.Instance->ICR |= I2C_ICR_ADDRCF_M; + HAL_I2C_Reset_Interrupt_Flag(&hi2c, I2C_ICR_ADDRCF_M); // look at the transmission direction and respond to the request if (interrupt_status & I2C_ISR_DIR_M) // master reads, slave sends - // отправляем данные - twi_onSlaveTransmit(); + twi_onSlaveTransmit(); // slave send data else // master writes, slave reads { twi_rxBufferIndex = 0; // write from the beginning of the buffer hi2c.State = HAL_I2C_STATE_BUSY; - hi2c.Instance->CR2 &= ~I2C_CR2_RELOAD_M; - // wait for interrupts because of receiving a byte or a stop condition + HAL_I2C_Clear_Reload(&hi2c); + // wait for interrupts by receiving a byte or a stop condition } } @@ -369,15 +350,15 @@ void twi_interruptHandler(void) if ((interrupt_status & I2C_ISR_RXNE_M) && (int_mask & I2C_CR1_RXIE_M)) { // put new byte into buffer - twi_rxBuffer[twi_rxBufferIndex++] = (uint8_t)hi2c.Instance->RXDR; + twi_rxBuffer[twi_rxBufferIndex++] = HAL_I2C_Get_RXDR(&hi2c); } // master sent a STOP to the bus if ((interrupt_status & I2C_ISR_STOPF_M) && (int_mask & I2C_CR1_STOPIE_M)) { hi2c.State = HAL_I2C_STATE_END; - hi2c.Instance->ISR |= I2C_ISR_TXE_M; // Reset TXDR contents - hi2c.Instance->ICR |= I2C_ICR_STOPCF_M; // Clear the STOP detection flag on the bus + HAL_I2C_Reset_TXDR_Content(&hi2c); + HAL_I2C_Reset_Interrupt_Flag(&hi2c, I2C_ICR_STOPCF_M); // Clear the STOP detection flag on the bus // pass the received data to callback function twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); } diff --git a/variants/standart/pins_arduino.h b/variants/standart/pins_arduino.h index dabd353..3700923 100644 --- a/variants/standart/pins_arduino.h +++ b/variants/standart/pins_arduino.h @@ -106,7 +106,7 @@ inline void unblockSpiPin(void) // I2C #define PIN_WIRE_SDA (18) #define PIN_WIRE_SCL (19) -#define I2C_NUM (1) // i2c number 0 or 1 +#define I2C_NUM (1) // i2c number 1 static const uint8_t SDA = PIN_WIRE_SDA; static const uint8_t SCL = PIN_WIRE_SCL; // available frequencies -- 2.43.0 From 23dfaab238c1d51b8de282bba2defabbda6c778d Mon Sep 17 00:00:00 2001 From: klassents Date: Fri, 6 Sep 2024 11:19:10 +0700 Subject: [PATCH 4/9] =?UTF-8?q?=D1=83=D0=B4=D0=B0=D0=BB=D0=B8=D0=BB=D0=B0?= =?UTF-8?q?=20=D0=BB=D0=B8=D1=88=D0=BD=D1=8E=D1=8E=20=D0=BF=D0=B0=D0=BF?= =?UTF-8?q?=D0=BA=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 69cabaf..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "files.associations": { - "mik32_hal_irq.h": "c", - "mik32_hal_i2c.h": "c" - } -} \ No newline at end of file -- 2.43.0 From b528af8a90bb70490781ef73557024a51a56143a Mon Sep 17 00:00:00 2001 From: klassents Date: Fri, 6 Sep 2024 11:22:10 +0700 Subject: [PATCH 5/9] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=D0=B0=20.vscode=20=D0=B2=20.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5d15477..5bce97a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -installed.json \ No newline at end of file +installed.json +.vscode/ \ No newline at end of file -- 2.43.0 From fec81e89e75717c0f69f1bc410d5cd5658a93f68 Mon Sep 17 00:00:00 2001 From: klassents Date: Fri, 6 Sep 2024 17:06:35 +0700 Subject: [PATCH 6/9] =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=B5=D1=81?= =?UTF-8?q?=D0=BB=D0=B0=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=83=20=D1=81=20?= =?UTF-8?q?=D1=80=D0=B5=D0=B3=D0=B8=D1=81=D1=82=D1=80=D0=B0=D0=BC=D0=B8=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20setclock,=20setmode=20=D0=B2=20spi.=D0=B2?= =?UTF-8?q?=20=D0=BF=D1=80=D0=BE=D1=86=D0=B5=D1=81=D1=81=D0=B5=20=D0=BE?= =?UTF-8?q?=D0=BF=D1=82=D0=B8=D0=BC=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=B2=20begin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hal/peripherals/Include/mik32_hal_gpio.h | 11 ++ .../hal/peripherals/Include/mik32_hal_spi.h | 3 +- .../hal/peripherals/Source/mik32_hal_spi.c | 43 +++++++ libraries/SPI/src/SPI.cpp | 117 ++++++------------ libraries/SPI/src/utility/spiElbear.cpp | 49 ++++++++ libraries/SPI/src/utility/spiElbear.h | 2 + 6 files changed, 144 insertions(+), 81 deletions(-) create mode 100644 libraries/SPI/src/utility/spiElbear.cpp create mode 100644 libraries/SPI/src/utility/spiElbear.h diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h index e398583..bc3237d 100644 --- a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h @@ -419,6 +419,17 @@ static inline __attribute__((always_inline)) void HAL_GPIO_TogglePin(GPIO_TypeDe GPIO_x->OUTPUT_ ^= pin; } +/** + * @brief Возвращает направление вывода при работе в режиме вход/выход + * @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2). + * @param pin маска вывода порта GPIO_x, направление которого необходимо узнать. + * @return Возвращает направление вывода - input или output. + */ +static inline __attribute__((always_inline)) HAL_GPIO_ModeTypeDef HAL_GPIO_GetPinDirection(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin) +{ + return (GPIO_x->DIRECTION_IN & pin) == 0 ? HAL_GPIO_MODE_GPIO_OUTPUT : HAL_GPIO_MODE_GPIO_INPUT; +} + /** * @brief Получить состояние линии прерывания. * @param irqLine номер линии прерывания. diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_spi.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_spi.h index f95a8ec..4886377 100644 --- a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_spi.h +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_spi.h @@ -253,7 +253,8 @@ void HAL_SPI_CS_Disable(SPI_HandleTypeDef *hspi); HAL_StatusTypeDef HAL_SPI_Exchange(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t Size, uint32_t Timeout); HAL_StatusTypeDef HAL_SPI_ExchangeThreshold(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t DataSize, uint32_t Timeout); HAL_StatusTypeDef HAL_SPI_Exchange_IT(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t Size); - +void HAL_SPI_Set_Clock_Divider(SPI_HandleTypeDef *hspi, uint8_t clockDiv); +void HAL_SPI_Set_Clock_Mode(SPI_HandleTypeDef *hspi, uint8_t CLKPhase, uint8_t CLKPolarity); /** * @brief Разрешить прерывания в соответствии с маской. diff --git a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_spi.c b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_spi.c index 3c07a13..e70587e 100644 --- a/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_spi.c +++ b/cores/arduino/mik32/hal/peripherals/Source/mik32_hal_spi.c @@ -282,6 +282,49 @@ HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi) return error_code; } +/** + * @brief Установить новый делитель частоты + * + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + * @param clockDiv делитель частоты в пределах от SPI_BAUDRATE_DIV4 до SPI_BAUDRATE_DIV256 + */ +void HAL_SPI_Set_Clock_Divider(SPI_HandleTypeDef *hspi, uint8_t clockDiv) +{ + uint32_t config = hspi->Instance->CONFIG; + HAL_SPI_Disable(hspi); + hspi->Init.BaudRateDiv = clockDiv; + config &= ~(0b111 << SPI_CONFIG_BAUD_RATE_DIV_S); // очистить + config |= (hspi->Init.BaudRateDiv << SPI_CONFIG_BAUD_RATE_DIV_S); // установить новое + hspi->Instance->CONFIG = config; // сохранить конфигурацию + HAL_SPI_Enable(hspi); +} + +/** + * @brief Установить новый режим работы + * + * @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит + * информацию о конфигурации для модуля SPI. + * @param CLKPhase фаза тактирующего сигнала: + * 1 - тактовая частота SPI неактивна вне слова, + * 0 - тактовая частота SPI активна вне слова + * @param CLKPolarity полярность тактирующего сигнала + * 1 - тактовый сигнал удерживается на высоком уровне, + * 0 - тактовый сигнал удерживается на низком уровне + */ +void HAL_SPI_Set_Clock_Mode(SPI_HandleTypeDef *hspi, uint8_t CLKPhase, uint8_t CLKPolarity) +{ + uint32_t config = hspi->Instance->CONFIG; + HAL_SPI_Disable(hspi); + hspi->Init.CLKPhase = CLKPhase; + hspi->Init.CLKPolarity = CLKPolarity; + config &= ~((1 << SPI_CONFIG_CLK_PH_S) | (1 << SPI_CONFIG_CLK_POL_S)); // очистить + config |= ((hspi->Init.CLKPhase << SPI_CONFIG_CLK_PH_S) | + (hspi->Init.CLKPolarity << SPI_CONFIG_CLK_POL_S)); // установить новые значения + hspi->Instance->CONFIG = config; // сохранить конфигурацию + HAL_SPI_Enable(hspi); +} + /** * @brief Очистить буфер TX_FIFO. * diff --git a/libraries/SPI/src/SPI.cpp b/libraries/SPI/src/SPI.cpp index 7a28066..3885866 100644 --- a/libraries/SPI/src/SPI.cpp +++ b/libraries/SPI/src/SPI.cpp @@ -1,5 +1,6 @@ #include "SPI.h" #include "mik32_hal_spi.h" +#include "utility/spiElbear.h" SPI_HandleTypeDef hspi; bool newConfig = false; @@ -50,54 +51,18 @@ void SPISettings::spiUpdateSettings(uint32_t speedMaximum, uint8_t dataOrder, ui } // ------------------------------------------------------------------ // -// pins shift in gpio register -#define PIN_1_3_GPIO_S 3 -#define PIN_1_4_GPIO_S 4 + SPIClass SPI; bool SPIClass::spiInUse = false; uint8_t SPIClass::interruptMode = 0; uint8_t SPIClass::interruptMask = 0; +#define PAD_GET_PIN_CONFIG(port, pin) (((PAD_CONFIG->port) & (0b11<<(2*pin))) >> (2*pin)) + void SPIClass::begin() { - // there is a seller on pin 1.6 which replace D10 from spi NSS pin 1.3 to pin 1.4, - // because spi needs pin 1.3 for correct work - - // replace config from 1.3 to 1.4 - uint8_t config = ((PAD_CONFIG->PORT_1_CFG) & (0b11<<(2*PIN_1_3_GPIO_S))) >> (2*PIN_1_3_GPIO_S); - if (config == 0) // common gpio - { - // pin direction - uint8_t direction = ((GPIO_1->DIRECTION_IN) & (1<> PIN_1_3_GPIO_S; - if (direction == 1) // input - GPIO_1->DIRECTION_IN |= (1<DIRECTION_OUT |= (1<PORT_1_PUPD) & (0b11<<(2*PIN_1_3_GPIO_S))) >> (2*PIN_1_3_GPIO_S); - PAD_CONFIG ->PORT_1_PUPD &= (~(0b11<<(2*PIN_1_4_GPIO_S))); // clear - PAD_CONFIG ->PORT_1_PUPD |= ((pupd_1_3&0b11)<<(2*PIN_1_4_GPIO_S)); // set new - - //current state - uint8_t state1_3 = ((GPIO_1->OUTPUT_) & (1<> PIN_1_3_GPIO_S; - GPIO_1->OUTPUT_ &= (~(0b1<OUTPUT_ |= ((state1_3&0b1)<PORT_1_CFG &= (~(0b11<<(2*PIN_1_3_GPIO_S))); // set config to 0 - common gpio mode + // // return D10 with common gpio config to pin 1.3 + // PAD_CONFIG->PORT_1_CFG &= (~(0b11<<(2*PIN_1_3_GPIO_S))); // set config to 0 - common gpio mode - // pin direction - uint8_t direction = ((GPIO_1->DIRECTION_IN) & (1<> PIN_1_4_GPIO_S; - if (direction == 1) // input - GPIO_1->DIRECTION_IN |= (1<DIRECTION_OUT |= (1<DIRECTION_IN) & (1<> PIN_1_4_GPIO_S; + // if (direction == 1) // input + // GPIO_1->DIRECTION_IN |= (1<DIRECTION_OUT |= (1<PORT_1_PUPD) & (0b11<<(2*PIN_1_4_GPIO_S))) >> (2*PIN_1_4_GPIO_S); - PAD_CONFIG ->PORT_1_PUPD &= (~(0b11<<(2*PIN_1_3_GPIO_S))); // clear - PAD_CONFIG ->PORT_1_PUPD |= ((pupd_1_4&0b11)<<(2*PIN_1_3_GPIO_S)); // set new + // // pull up/down + // uint8_t pupd_1_4 = ((PAD_CONFIG ->PORT_1_PUPD) & (0b11<<(2*PIN_1_4_GPIO_S))) >> (2*PIN_1_4_GPIO_S); + // PAD_CONFIG ->PORT_1_PUPD &= (~(0b11<<(2*PIN_1_3_GPIO_S))); // clear + // PAD_CONFIG ->PORT_1_PUPD |= ((pupd_1_4&0b11)<<(2*PIN_1_3_GPIO_S)); // set new - // current state - uint8_t state1_4 = ((GPIO_1->OUTPUT_) & (1<> PIN_1_4_GPIO_S; - GPIO_1->OUTPUT_ &= (~(0b1<OUTPUT_ |= ((state1_4&0b1)<OUTPUT_) & (1<> PIN_1_4_GPIO_S; + // GPIO_1->OUTPUT_ &= (~(0b1<OUTPUT_ |= ((state1_4&0b1)<CONFIG; - HAL_SPI_Disable(&hspi); - hspi.Init.CLKPhase = dataMode & 0b00000001; - hspi.Init.CLKPolarity = (dataMode & 0b00000010)>>1; - config &= ~((1 << SPI_CONFIG_CLK_PH_S) | (1 << SPI_CONFIG_CLK_POL_S)); // clear - config |= ((hspi.Init.CLKPhase << SPI_CONFIG_CLK_PH_S) | - (hspi.Init.CLKPolarity << SPI_CONFIG_CLK_POL_S)); // set new - hspi.Instance->CONFIG = config; - HAL_SPI_Enable(&hspi); + // ClkPhase ClkPolarity + HAL_SPI_Set_Clock_Mode(&hspi, (dataMode&0b00000001), (dataMode&0b00000010)>>1); } void SPIClass::setClockDivider(uint8_t clockDiv) { - // if divider is in valid range - if ((clockDiv >= SPI_CLOCK_DIV4) && (clockDiv <= SPI_CLOCK_DIV256)) + // if divider is valid + if ((clockDiv == SPI_CLOCK_DIV4) || (clockDiv == SPI_CLOCK_DIV8) || + (clockDiv == SPI_CLOCK_DIV16) || (clockDiv == SPI_CLOCK_DIV32) || + (clockDiv == SPI_CLOCK_DIV64) || (clockDiv == SPI_CLOCK_DIV128) || + (clockDiv == SPI_CLOCK_DIV256)) { - uint32_t config = hspi.Instance->CONFIG; - HAL_SPI_Disable(&hspi); - hspi.Init.BaudRateDiv = clockDiv; - config &= ~(0b111 << SPI_CONFIG_BAUD_RATE_DIV_S); // clear - config |= (hspi.Init.BaudRateDiv << SPI_CONFIG_BAUD_RATE_DIV_S); // set new - hspi.Instance->CONFIG = config; - HAL_SPI_Enable(&hspi); + HAL_SPI_Set_Clock_Divider(&hspi, clockDiv); } + else + ErrorMsgHandler("SPI.setClockDivider(): Invalid clock devider"); } static uint8_t reverse_bits(uint8_t byte) diff --git a/libraries/SPI/src/utility/spiElbear.cpp b/libraries/SPI/src/utility/spiElbear.cpp new file mode 100644 index 0000000..8ccb935 --- /dev/null +++ b/libraries/SPI/src/utility/spiElbear.cpp @@ -0,0 +1,49 @@ +#include "Arduino.h" +#include "spiElbear.h" +#include "mik32_hal_gpio.h" +#include "xprintf.h" + +// pins shift in registers +#define PIN_3_SHIFT 3 +#define PIN_4_SHIFT 4 +#define PORT1_GET_PAD_CONFIG(pinShift) ((PAD_CONFIG->PORT_1_CFG >> (pinShift<<1)) & 0b11) +#define PORT1_GET_PAD_PUPD(pinShift) ((PAD_CONFIG->PORT_1_PUPD >> (pinShift<<1)) & 0b11) +#define PORT1_GET_GPIO_STATE(pinShift) ((GPIO_1->OUTPUT_ >> pinShift) & 0b1) + +void spiElbear_prepareBegin(void) +{ + // there is a seller on pin 1.6 which replace D10 from spi NSS pin 1.3 to pin 1.4, + // because spi needs pin 1.3 for correct work + + // replace config from 1.3 to 1.4 + uint8_t config = PORT1_GET_PAD_CONFIG(PIN_3_SHIFT); + if (config == 0) // common gpio + { + // pin direction + HAL_GPIO_ModeTypeDef pin3_direction = HAL_GPIO_GetPinDirection(GPIO_1, GPIO_PIN_3); + // pull up/down + HAL_GPIO_PullTypeDef pin3_pupd = (HAL_GPIO_PullTypeDef)PORT1_GET_PAD_PUPD(PIN_3_SHIFT); + //current state + uint8_t pin3_state = PORT1_GET_GPIO_STATE(PIN_3_SHIFT); + + // init and set state + HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_4, pin3_direction, pin3_pupd, HAL_GPIO_DS_2MA); + HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_4, pin3_state); + // todo ПРОВЕРИТЬ, что по факту устанавливается то, что я говорю в HAL_GPIO_PinConfig + + } + else if(config == 2) // timer for pwm + { + // вместо это возвращать что-то, что покажет, что это не gpio и снаружи выбросит предупреждение это + + // // if D10 (spi NSS pin) was used as pwm, we need to stop timer, + // // because 1.4 don't support timer + // analogWriteStop(10); + // ErrorMsgHandler("analogWrite(): D10 cannot be used as PWM pin while SPI is running"); + } + + // switch seller to pin 1.4 + HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_6, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA); + HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_6, GPIO_PIN_HIGH); + blockSpiPin(); +} \ No newline at end of file diff --git a/libraries/SPI/src/utility/spiElbear.h b/libraries/SPI/src/utility/spiElbear.h new file mode 100644 index 0000000..8367111 --- /dev/null +++ b/libraries/SPI/src/utility/spiElbear.h @@ -0,0 +1,2 @@ + +void spiElbear_prepareBegin(void); \ No newline at end of file -- 2.43.0 From 4ecc7f948bf1a3f8702c02a3450927af239c121e Mon Sep 17 00:00:00 2001 From: klassents Date: Mon, 9 Sep 2024 10:31:33 +0700 Subject: [PATCH 7/9] =?UTF-8?q?=D0=B7=D0=B0=D0=BC=D0=B5=D0=BD=D0=B8=D0=BB?= =?UTF-8?q?=D0=B0=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8=20=D0=B2=20?= =?UTF-8?q?spi.begin,=20spi.end.=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=B5=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libraries/SPI/src/SPI.cpp | 39 +++++----------------- libraries/SPI/src/utility/spiElbear.cpp | 44 ++++++++++++++----------- libraries/SPI/src/utility/spiElbear.h | 3 +- 3 files changed, 35 insertions(+), 51 deletions(-) diff --git a/libraries/SPI/src/SPI.cpp b/libraries/SPI/src/SPI.cpp index 3885866..4166d74 100644 --- a/libraries/SPI/src/SPI.cpp +++ b/libraries/SPI/src/SPI.cpp @@ -62,7 +62,8 @@ uint8_t SPIClass::interruptMask = 0; void SPIClass::begin() { - spiElbear_prepareBegin(); + spi_onBegin(); + spiInUse = true; } @@ -73,36 +74,14 @@ void SPIClass::end() // turn off spi HAL_SPI_Disable(&hspi); - // // deinit spi gpio pins - // if (hspi.Instance == SPI_1) // only spi1 is using in currunt version - // { - // HAL_GPIO_PinConfig(GPIO_1, (HAL_PinsTypeDef)(GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2), - // HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA); - // } + // deinit spi gpio pins + if (hspi.Instance == SPI_1) // only spi1 is using in currunt version + { + HAL_GPIO_PinConfig(GPIO_1, (HAL_PinsTypeDef)(GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2), + HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA); + } - // // return D10 with common gpio config to pin 1.3 - // PAD_CONFIG->PORT_1_CFG &= (~(0b11<<(2*PIN_1_3_GPIO_S))); // set config to 0 - common gpio mode - - // // pin direction - // uint8_t direction = ((GPIO_1->DIRECTION_IN) & (1<> PIN_1_4_GPIO_S; - // if (direction == 1) // input - // GPIO_1->DIRECTION_IN |= (1<DIRECTION_OUT |= (1<PORT_1_PUPD) & (0b11<<(2*PIN_1_4_GPIO_S))) >> (2*PIN_1_4_GPIO_S); - // PAD_CONFIG ->PORT_1_PUPD &= (~(0b11<<(2*PIN_1_3_GPIO_S))); // clear - // PAD_CONFIG ->PORT_1_PUPD |= ((pupd_1_4&0b11)<<(2*PIN_1_3_GPIO_S)); // set new - - // // current state - // uint8_t state1_4 = ((GPIO_1->OUTPUT_) & (1<> PIN_1_4_GPIO_S; - // GPIO_1->OUTPUT_ &= (~(0b1<OUTPUT_ |= ((state1_4&0b1)<PORT_1_PUPD >> (pinShift<<1)) & 0b11) #define PORT1_GET_GPIO_STATE(pinShift) ((GPIO_1->OUTPUT_ >> pinShift) & 0b1) -void spiElbear_prepareBegin(void) +void spi_onBegin(void) { // there is a seller on pin 1.6 which replace D10 from spi NSS pin 1.3 to pin 1.4, // because spi needs pin 1.3 for correct work - + // replace config from 1.3 to 1.4 uint8_t config = PORT1_GET_PAD_CONFIG(PIN_3_SHIFT); if (config == 0) // common gpio { - // pin direction - HAL_GPIO_ModeTypeDef pin3_direction = HAL_GPIO_GetPinDirection(GPIO_1, GPIO_PIN_3); - // pull up/down - HAL_GPIO_PullTypeDef pin3_pupd = (HAL_GPIO_PullTypeDef)PORT1_GET_PAD_PUPD(PIN_3_SHIFT); - //current state - uint8_t pin3_state = PORT1_GET_GPIO_STATE(PIN_3_SHIFT); - - // init and set state - HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_4, pin3_direction, pin3_pupd, HAL_GPIO_DS_2MA); - HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_4, pin3_state); - // todo ПРОВЕРИТЬ, что по факту устанавливается то, что я говорю в HAL_GPIO_PinConfig - + // get info from pin gpio1.3 and set config to gpio1.4 + HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_4, HAL_GPIO_GetPinDirection(GPIO_1, GPIO_PIN_3), + (HAL_GPIO_PullTypeDef)PORT1_GET_PAD_PUPD(PIN_3_SHIFT), HAL_GPIO_DS_2MA); + HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_4, (GPIO_PinState)PORT1_GET_GPIO_STATE(PIN_3_SHIFT)); + + // pin D10 was switched to different gpio and can be used further } else if(config == 2) // timer for pwm { - // вместо это возвращать что-то, что покажет, что это не gpio и снаружи выбросит предупреждение это - - // // if D10 (spi NSS pin) was used as pwm, we need to stop timer, - // // because 1.4 don't support timer - // analogWriteStop(10); - // ErrorMsgHandler("analogWrite(): D10 cannot be used as PWM pin while SPI is running"); + // if D10 (spi NSS pin) was used as pwm, we need to stop timer, + // because 1.4 don't support timer + analogWriteStop(10); + ErrorMsgHandler("analogWrite(): D10 cannot be used as PWM pin while SPI is running"); } // switch seller to pin 1.4 HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_6, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA); HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_6, GPIO_PIN_HIGH); blockSpiPin(); +} + +void spi_onEnd(void) +{ + // get info from pin gpio1.4 and set config to gpio1.3 + HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_3, HAL_GPIO_GetPinDirection(GPIO_1, GPIO_PIN_4), + (HAL_GPIO_PullTypeDef)PORT1_GET_PAD_PUPD(PIN_4_SHIFT), HAL_GPIO_DS_2MA); + HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_3, (GPIO_PinState)PORT1_GET_GPIO_STATE(PIN_4_SHIFT)); + + // switch seller back to pin 1.3 + HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_6, GPIO_PIN_LOW); + unblockSpiPin(); } \ No newline at end of file diff --git a/libraries/SPI/src/utility/spiElbear.h b/libraries/SPI/src/utility/spiElbear.h index 8367111..53a286b 100644 --- a/libraries/SPI/src/utility/spiElbear.h +++ b/libraries/SPI/src/utility/spiElbear.h @@ -1,2 +1,3 @@ -void spiElbear_prepareBegin(void); \ No newline at end of file +void spi_onBegin(void); +void spi_onEnd(void); \ No newline at end of file -- 2.43.0 From 39ee35f88d4c7a6968cd43498ef2715bfcbe87d5 Mon Sep 17 00:00:00 2001 From: klassents Date: Mon, 9 Sep 2024 10:57:21 +0700 Subject: [PATCH 8/9] =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=B5=D1=81?= =?UTF-8?q?=D0=BB=D0=B0=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BA=D0=BB=D1=8E=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BD=D0=BE=D0=B3=D0=B8=20spi=20?= =?UTF-8?q?=D0=B2=20=D0=BF=D0=BB=D0=B0=D1=82=D0=BE=D0=B7=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D1=81=D0=B8=D0=BC=D1=8B=D0=B9=20=D1=84=D0=B0=D0=B9=D0=BB=20var?= =?UTF-8?q?iants.c?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libraries/SPI/src/SPI.cpp | 1 - libraries/SPI/src/utility/spiElbear.cpp | 53 ------------------------- libraries/SPI/src/utility/spiElbear.h | 3 -- variants/standart/pins_arduino.h | 12 +----- variants/standart/variant.c | 50 +++++++++++++++++++++++ 5 files changed, 52 insertions(+), 67 deletions(-) delete mode 100644 libraries/SPI/src/utility/spiElbear.cpp delete mode 100644 libraries/SPI/src/utility/spiElbear.h diff --git a/libraries/SPI/src/SPI.cpp b/libraries/SPI/src/SPI.cpp index 4166d74..10a9270 100644 --- a/libraries/SPI/src/SPI.cpp +++ b/libraries/SPI/src/SPI.cpp @@ -1,6 +1,5 @@ #include "SPI.h" #include "mik32_hal_spi.h" -#include "utility/spiElbear.h" SPI_HandleTypeDef hspi; bool newConfig = false; diff --git a/libraries/SPI/src/utility/spiElbear.cpp b/libraries/SPI/src/utility/spiElbear.cpp deleted file mode 100644 index 23d29b0..0000000 --- a/libraries/SPI/src/utility/spiElbear.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "Arduino.h" -#include "spiElbear.h" -#include "mik32_hal_gpio.h" -#include "xprintf.h" - -// pins shift in registers -#define PIN_3_SHIFT 3 -#define PIN_4_SHIFT 4 -#define PORT1_GET_PAD_CONFIG(pinShift) ((PAD_CONFIG->PORT_1_CFG >> (pinShift<<1)) & 0b11) -#define PORT1_GET_PAD_PUPD(pinShift) ((PAD_CONFIG->PORT_1_PUPD >> (pinShift<<1)) & 0b11) -#define PORT1_GET_GPIO_STATE(pinShift) ((GPIO_1->OUTPUT_ >> pinShift) & 0b1) - -void spi_onBegin(void) -{ - // there is a seller on pin 1.6 which replace D10 from spi NSS pin 1.3 to pin 1.4, - // because spi needs pin 1.3 for correct work - - // replace config from 1.3 to 1.4 - uint8_t config = PORT1_GET_PAD_CONFIG(PIN_3_SHIFT); - if (config == 0) // common gpio - { - // get info from pin gpio1.3 and set config to gpio1.4 - HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_4, HAL_GPIO_GetPinDirection(GPIO_1, GPIO_PIN_3), - (HAL_GPIO_PullTypeDef)PORT1_GET_PAD_PUPD(PIN_3_SHIFT), HAL_GPIO_DS_2MA); - HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_4, (GPIO_PinState)PORT1_GET_GPIO_STATE(PIN_3_SHIFT)); - - // pin D10 was switched to different gpio and can be used further - } - else if(config == 2) // timer for pwm - { - // if D10 (spi NSS pin) was used as pwm, we need to stop timer, - // because 1.4 don't support timer - analogWriteStop(10); - ErrorMsgHandler("analogWrite(): D10 cannot be used as PWM pin while SPI is running"); - } - - // switch seller to pin 1.4 - HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_6, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA); - HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_6, GPIO_PIN_HIGH); - blockSpiPin(); -} - -void spi_onEnd(void) -{ - // get info from pin gpio1.4 and set config to gpio1.3 - HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_3, HAL_GPIO_GetPinDirection(GPIO_1, GPIO_PIN_4), - (HAL_GPIO_PullTypeDef)PORT1_GET_PAD_PUPD(PIN_4_SHIFT), HAL_GPIO_DS_2MA); - HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_3, (GPIO_PinState)PORT1_GET_GPIO_STATE(PIN_4_SHIFT)); - - // switch seller back to pin 1.3 - HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_6, GPIO_PIN_LOW); - unblockSpiPin(); -} \ No newline at end of file diff --git a/libraries/SPI/src/utility/spiElbear.h b/libraries/SPI/src/utility/spiElbear.h deleted file mode 100644 index 53a286b..0000000 --- a/libraries/SPI/src/utility/spiElbear.h +++ /dev/null @@ -1,3 +0,0 @@ - -void spi_onBegin(void); -void spi_onEnd(void); \ No newline at end of file diff --git a/variants/standart/pins_arduino.h b/variants/standart/pins_arduino.h index 3700923..5f59b36 100644 --- a/variants/standart/pins_arduino.h +++ b/variants/standart/pins_arduino.h @@ -32,8 +32,6 @@ extern "C" { #include "mik32_hal_gpio.h" #include "mik32_hal_timer32.h" -extern bool spiNssPinIsBlocked; - // analog pins #define PIN_A0 (14) #define PIN_A1 (15) @@ -94,14 +92,8 @@ static const uint8_t MISO = PIN_SPI_MISO; static const uint8_t SCK = PIN_SPI_SCK; // config SEL_NSS1 to replace D10 to different controller pin, // because pin 1.3 which is D10 by default is needed to spi -inline void blockSpiPin(void) -{ - spiNssPinIsBlocked = true; -} -inline void unblockSpiPin(void) -{ - spiNssPinIsBlocked = false; -} +void spi_onBegin(void); +void spi_onEnd(void); // I2C #define PIN_WIRE_SDA (18) diff --git a/variants/standart/variant.c b/variants/standart/variant.c index f38cf1f..1cec497 100644 --- a/variants/standart/variant.c +++ b/variants/standart/variant.c @@ -13,6 +13,7 @@ #include "pins_arduino.h" #include "mik32_hal_adc.h" +#include "wiring_analog.h" #ifdef __cplusplus extern "C" { @@ -225,4 +226,53 @@ int8_t digitalPinToInterrupt(uint32_t digPinNumber) return i; } return NOT_AN_INTERRUPT; +} + +// ---------------------- SPI ---------------------- // +// pins shift in registers +#define PIN_3_SHIFT 3 +#define PIN_4_SHIFT 4 +#define PORT1_GET_PAD_CONFIG(pinShift) ((PAD_CONFIG->PORT_1_CFG >> (pinShift<<1)) & 0b11) +#define PORT1_GET_PAD_PUPD(pinShift) ((PAD_CONFIG->PORT_1_PUPD >> (pinShift<<1)) & 0b11) +#define PORT1_GET_GPIO_STATE(pinShift) ((GPIO_1->OUTPUT_ >> pinShift) & 0b1) + +void spi_onBegin(void) +{ + // On Elbear Ace-Uno rev1.1.0 there is a seller on pin 1.6 which replace D10 from spi NSS pin 1.3 to pin 1.4, + // because spi needs pin 1.3 for correct work + + // replace config from 1.3 to 1.4 + uint8_t config = PORT1_GET_PAD_CONFIG(PIN_3_SHIFT); + if (config == 0) // common gpio + { + // get info from pin gpio1.3 and set config to gpio1.4 + HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_4, HAL_GPIO_GetPinDirection(GPIO_1, GPIO_PIN_3), + (HAL_GPIO_PullTypeDef)PORT1_GET_PAD_PUPD(PIN_3_SHIFT), HAL_GPIO_DS_2MA); + HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_4, (GPIO_PinState)PORT1_GET_GPIO_STATE(PIN_3_SHIFT)); + + // pin D10 was switched to different gpio and can be used further + } + else if(config == 2) // timer for pwm + { + // if D10 (spi NSS pin) was used as pwm, we need to stop timer, because 1.4 don't support it + analogWriteStop(10); + ErrorMsgHandler("analogWrite(): D10 cannot be used as PWM pin while SPI is running"); + } + + // switch seller to pin 1.4 + HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_6, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA); + HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_6, GPIO_PIN_HIGH); + spiNssPinIsBlocked = true; // block spi pin +} + +void spi_onEnd(void) +{ + // get info from pin gpio1.4 and set config to gpio1.3 + HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_3, HAL_GPIO_GetPinDirection(GPIO_1, GPIO_PIN_4), + (HAL_GPIO_PullTypeDef)PORT1_GET_PAD_PUPD(PIN_4_SHIFT), HAL_GPIO_DS_2MA); + HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_3, (GPIO_PinState)PORT1_GET_GPIO_STATE(PIN_4_SHIFT)); + + // switch seller back to pin 1.3 + HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_6, GPIO_PIN_LOW); + spiNssPinIsBlocked = false; // unblock spi pin } \ No newline at end of file -- 2.43.0 From e548e7e48623d509c7af80d1d5616c5a4ba3def9 Mon Sep 17 00:00:00 2001 From: klassents Date: Wed, 11 Sep 2024 14:39:58 +0700 Subject: [PATCH 9/9] =?UTF-8?q?=D0=BF=D1=80=D0=B8=20=D0=BE=D1=82=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8=20=D1=88=D0=B8=D0=BC=20?= =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=D0=B0=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D1=83,=20=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D0=B0=D0=B5=D1=82=20=D0=BB=D0=B8=20=D0=BD=D0=B0=20?= =?UTF-8?q?=D1=8D=D1=82=D0=BE=D0=BC=20=D0=BA=D0=BE=D0=BD=D0=BA=D1=80=D0=B5?= =?UTF-8?q?=D1=82=D0=BD=D0=BE=D0=BC=20=D0=BF=D0=B8=D0=BD=D0=B5=20=D1=81?= =?UTF-8?q?=D0=B5=D0=B9=D1=87=D0=B0=D1=81=20=D1=82=D0=B0=D0=B9=D0=BC=D0=B5?= =?UTF-8?q?=D1=80.=20=D0=B5=D1=81=D0=BB=D0=B8=20=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=B0=D0=B5=D1=82,=20=D1=82=D0=BE=D0=B3=D0=B4=D0=B0=20?= =?UTF-8?q?=D0=B2=D1=8B=D0=BA=D0=BB=D1=8E=D1=87=D0=B0=D0=B5=D0=BC=20=D0=B5?= =?UTF-8?q?=D0=B3=D0=BE=20=D0=B8=20=D0=BF=D0=B8=D0=BD=20=D0=BD=D0=B0=D1=81?= =?UTF-8?q?=D1=82=D1=80=D0=B0=D0=B8=D0=B2=D0=B0=D0=B5=D0=BC=20=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=B2=D1=85=D0=BE=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cores/arduino/wiring_analog.c | 6 ++++- variants/standart/pins_arduino.h | 1 + variants/standart/variant.c | 39 ++++++++++++++++++++++++++++++-- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index 2a8421a..cdf1226 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -148,7 +148,7 @@ It is recommended to turn off the timer in the following order: */ void analogWriteStop(uint32_t PinNumber) { - if (pwmIsInited > 0) + if ((pwmIsInited > 0) && (digitalPinPwmIsOn(PinNumber))) { // load the timer address and channel number corresponding to the specified pin htimer32.Instance = pwmPinToTimer(PinNumber); @@ -164,6 +164,10 @@ void analogWriteStop(uint32_t PinNumber) HAL_Timer32_Stop(&htimer32); HAL_Timer32_Deinit(&htimer32); } + + // config pin as input when timer channel off + HAL_GPIO_PinConfig(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber), + HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA); } } diff --git a/variants/standart/pins_arduino.h b/variants/standart/pins_arduino.h index 5f59b36..16dc84b 100644 --- a/variants/standart/pins_arduino.h +++ b/variants/standart/pins_arduino.h @@ -76,6 +76,7 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber); // PWM bool digitalPinHasPWM(uint8_t p); +bool digitalPinPwmIsOn(uint8_t digitalPin); // use only if digitalPinHasPWM() == true // determines which timer the pin belongs to TIMER32_TypeDef* pwmPinToTimer(uint32_t digPinNumber); // determines which timer channel the pin belongs to diff --git a/variants/standart/variant.c b/variants/standart/variant.c index 1cec497..62b59fb 100644 --- a/variants/standart/variant.c +++ b/variants/standart/variant.c @@ -107,6 +107,10 @@ volatile uint32_t* portInputRegister(GPIO_TypeDef* GPIO_x) return &GPIO_x->STATE; } +// return config of pin with pinShift(0...16) in portReg (config, pupd, ds for ports 0...2) +#define PIN_PAD_CONFIG(portReg, pinShift) ((PAD_CONFIG->portReg >> (pinShift<<1)) & 0b11) + + // ---------------------- ADC ---------------------- // // determines the ADC channel number by the board pin number uint32_t analogInputToChannelNumber(uint32_t PinNumber) @@ -142,6 +146,38 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber) } // ---------------------- PWM ---------------------- // +// use only if digitalPinHasPWM() == true +#define PWM_PIN_TO_PORT_NUMBER(pin) (((pin==10)||(pin==11)) ? 1:0) +// use only if digitalPinHasPWM() == true +static inline uint8_t pwmPinToGpioPinShift(uint8_t digitalPin) +{ + if (digitalPin == 3) + return 0; + else if ((digitalPin == 5) || (digitalPin == 11)) + return 1; + else if (digitalPin == 6) + return 2; + else // pins 9 10 + return 3; +} +// use only if digitalPinHasPWM() == true +// return true if digitalPin configured as pwm +bool digitalPinPwmIsOn(uint8_t digitalPin) +{ + uint8_t config = 0; + uint8_t pinShift = pwmPinToGpioPinShift(digitalPin); + + if (PWM_PIN_TO_PORT_NUMBER(digitalPin) == 0) + config = PIN_PAD_CONFIG(PORT_0_CFG, pinShift); + else + config = PIN_PAD_CONFIG(PORT_1_CFG, pinShift); + + if (config == 2) + return true; + else + return false; +} + bool digitalPinHasPWM(uint8_t p) { bool ret = false; @@ -232,7 +268,6 @@ int8_t digitalPinToInterrupt(uint32_t digPinNumber) // pins shift in registers #define PIN_3_SHIFT 3 #define PIN_4_SHIFT 4 -#define PORT1_GET_PAD_CONFIG(pinShift) ((PAD_CONFIG->PORT_1_CFG >> (pinShift<<1)) & 0b11) #define PORT1_GET_PAD_PUPD(pinShift) ((PAD_CONFIG->PORT_1_PUPD >> (pinShift<<1)) & 0b11) #define PORT1_GET_GPIO_STATE(pinShift) ((GPIO_1->OUTPUT_ >> pinShift) & 0b1) @@ -242,7 +277,7 @@ void spi_onBegin(void) // because spi needs pin 1.3 for correct work // replace config from 1.3 to 1.4 - uint8_t config = PORT1_GET_PAD_CONFIG(PIN_3_SHIFT); + uint8_t config = PIN_PAD_CONFIG(PORT_1_CFG, PIN_3_SHIFT); if (config == 0) // common gpio { // get info from pin gpio1.3 and set config to gpio1.4 -- 2.43.0