From 1056ce0dc6f5c4339f2e7d5972a0b8c2d9f767dc Mon Sep 17 00:00:00 2001 From: KLASSENTS Date: Mon, 27 Jan 2025 16:12:38 +0700 Subject: [PATCH] =?UTF-8?q?=D0=BD=D0=B0=D1=87=D0=B8=D0=BD=D0=B0=D1=8E=20?= =?UTF-8?q?=D0=B4=D0=B5=D0=BB=D0=B0=D1=82=D1=8C=20=D1=84=D0=B0=D0=B9=D0=BB?= =?UTF-8?q?=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- variants/elsomik/pins_arduino.h | 191 ++++++++++++++++++++++++++++ variants/elsomik/variant.c | 212 ++++++++++++++++++++++++++++++++ 2 files changed, 403 insertions(+) create mode 100644 variants/elsomik/pins_arduino.h create mode 100644 variants/elsomik/variant.c diff --git a/variants/elsomik/pins_arduino.h b/variants/elsomik/pins_arduino.h new file mode 100644 index 0000000..58c4dff --- /dev/null +++ b/variants/elsomik/pins_arduino.h @@ -0,0 +1,191 @@ +/* + pins_arduino.h - Pin definition functions for Arduino + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2007 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include "wiring_constants.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mik32_hal_gpio.h" +#include "mik32_hal_timer32.h" + +#define PORT_PIN_MASK 0xF + +// digital pins +#define P0_0 0 +#define P0_1 1 +#define P0_2 2 +#define P0_3 3 +#define P0_4 4 +#define P0_5 5 +#define P0_6 6 +#define P0_7 7 +#define P0_8 8 +#define P0_9 9 +#define P0_10 10 +#define P0_11 11 +#define P0_12 12 +#define P0_13 13 +#define P0_14 14 +#define P0_15 15 +#define P1_0 16 +#define P1_1 17 +#define P1_2 18 +#define P1_3 19 +#define P1_4 20 +#define P1_5 21 +#define P1_6 22 +#define P1_7 23 +#define P1_8 24 +#define P1_9 25 +#define P1_10 26 +#define P1_11 27 +#define P1_12 28 +#define P1_13 29 +#define P1_14 30 +#define P1_15 31 +#define P2_0 32 +#define P2_1 33 +#define P2_2 34 +#define P2_3 35 +#define P2_4 36 +#define P2_5 37 +#define P2_6 38 +#define P2_7 39 + +// analog pins +#define PIN_A0 (P1_5) +#define PIN_A1 (P1_7) +#define PIN_A2 (P0_2) +#define PIN_A3 (P0_4) +#define PIN_A4 (P0_7) +#define PIN_A5 (P0_9) +#define PIN_A6 (P0_11) +#define PIN_A7 (P0_13) + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6; +static const uint8_t A7 = PIN_A7; + + +// User led and button +#define LED_BUILTIN0 (P0_3) +#define LED_BUILTIN1 (P1_3) +#define LED_BUILTIN LED_BUILTIN0 +#define BTN_BUILTIN (P0_8) + +// determines the address of the port by the board pin number to which this pin belongs on the MCU +GPIO_TypeDef* digitalPinToPort(uint32_t digPinNumber); +// determines the pin address inside the port by the board pin number +static inline HAL_PinsTypeDef digitalPinToBitMask(uint32_t digitalPinNumber) +{ + return (HAL_PinsTypeDef)(1 << (digitalPinNumber & 0xF)); +} +// total number of pins available for initialization +static inline uint16_t pinCommonQty(void) +{ + return (uint16_t)40; +} +// the function returns a reference to the OUTPUT address of the GPIO register +volatile uint32_t* portOutputRegister(GPIO_TypeDef* GPIO_x); +// the function returns a reference to the STATE address of the GPIO register +volatile uint32_t* portInputRegister(GPIO_TypeDef* GPIO_x); +// the function is needed for compatibility with other boards +static inline void additionalPinsInit(uint32_t PinNumber) {} + +// UART +// available uarts quantity +#define SERIAL_PORT_QTY 2 + +// ADC +#define MCU_ADC_RESOLUTION 12 // bits +// determines the ADC channel number by the board pin number +uint32_t analogInputToChannelNumber(uint32_t PinNumber); + +// PWM +#define PWM_FREQUENCY_MAX 1000000 // Hz +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 +HAL_TIMER32_CHANNEL_IndexTypeDef pwmPinToTimerChannel(uint32_t digPinNumber); + +// SPI +#define PIN_SPI_SS (P1_3) +#define PIN_SPI_MOSI (P1_1) +#define PIN_SPI_MISO (P1_0) +#define PIN_SPI_SCK (P1_2) +static const uint8_t SS = PIN_SPI_SS; +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK; +// functions is needed for compatibility with other boards +static inline void spi_onBegin(void) {} +static inline void spi_onEnd(void) {} + +// I2C +#define PIN_WIRE_SDA (P1_12) +#define PIN_WIRE_SCL (P1_13) +#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 +#define WIRE_FREQ_100K 100000 +#define WIRE_FREQ_400K 400000 +#define WIRE_FREQ_1000K 1000000 + +// interrupts +#define EXTERNAL_INTERRUPTS_QTY 8 +extern uint8_t interruptInfo[EXTERNAL_INTERRUPTS_QTY][3]; +// determines the board pin number by interrupt number +#define interruptToDigitalPin(interruptNum) (interruptInfo[interruptNum][0]) +// determines gpio interrupt line by interrupt number +#define interruptToGpioIntLine(interruptNum) ((uint8_t)interruptInfo[interruptNum][1]) +// determines gpio interrupt mux by interrupt number +#define interruptToGpioIntMux(interruptNum) ((uint8_t)interruptInfo[interruptNum][2]) +// determines interrupt number by the board pin number +int8_t digitalPinToInterrupt(uint32_t digPinNumber); +// determines interrupt number by the gpio interrupt line +int8_t gpioIntLineToInterrupt(uint32_t gpioIntLine); +// determines gpio interrupt mux by the board pin number +int8_t digitalPinToGpioIntMux(uint8_t digPinNumber); +// determines gpio interrupt line by the board pin number +int8_t digitalPinToGpioIntLine(uint8_t digPinNumber); + + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/variants/elsomik/variant.c b/variants/elsomik/variant.c new file mode 100644 index 0000000..d220902 --- /dev/null +++ b/variants/elsomik/variant.c @@ -0,0 +1,212 @@ +/** + ******************************************************************************* + * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. + * All rights reserved. + * + * This software component is licensed by WCH under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +#include "pins_arduino.h" +#include "mik32_hal_adc.h" +#include "wiring_analog.h" +#include "wiring_LL.h" + +/** + * @brief Determines the address of the port by the board pin number to which this pin belongs on the MCU + * @return The address of the port corresponding to the board pin number. Can return 0 if the pin not exists + */ + +GPIO_TypeDef *digitalPinToPort(uint32_t digitalPinNumber) +{ + if (digitalPinNumber < 16u) + { + return GPIO_0; + } + else if ((digitalPinNumber >= 16u) && (digitalPinNumber < 32u)) + { + return GPIO_1; + } + else if ((digitalPinNumber >= 32u) && (digitalPinNumber < 40u)) + { + return GPIO_2; + } + else + { + return NULL; + } +} + +// the function returns a reference to the OUTPUT address of the GPIO register +volatile uint32_t *portOutputRegister(GPIO_TypeDef *GPIO_x) +{ + return &GPIO_x->OUTPUT_; +} + +// the function returns a reference to the STATE address of the GPIO register +volatile uint32_t *portInputRegister(GPIO_TypeDef *GPIO_x) +{ + return &GPIO_x->STATE; +} + +// ---------------------- ADC ---------------------- // +// determines the ADC channel number by the board pin number +uint32_t analogInputToChannelNumber(uint32_t PinNumber) +{ + uint32_t adcChannel = 0; + + switch (PinNumber) + { + case PIN_A0: + adcChannel = ADC_CHANNEL0; + break; + case PIN_A1: + adcChannel = ADC_CHANNEL1; + break; + case PIN_A2: + adcChannel = ADC_CHANNEL2; + break; + case PIN_A3: + adcChannel = ADC_CHANNEL3; + break; + case PIN_A4: + adcChannel = ADC_CHANNEL4; + break; + case PIN_A5: + adcChannel = ADC_CHANNEL5; + break; + case PIN_A6: + adcChannel = ADC_CHANNEL6; + break; + case PIN_A7: + adcChannel = ADC_CHANNEL7; + break; + default: + adcChannel = NC; + } + return adcChannel; +} + +// ---------------------- PWM ---------------------- // +// use only if digitalPinHasPWM() == true +#define PWM_PIN_TO_PORT_NUMBER(pin) (((pin) & 16) ? 1 : 0) +// use only if digitalPinHasPWM() == true +static inline uint8_t pwmPinToGpioPinShift(uint8_t digitalPin) +{ + return digitalPin & 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_GET_PAD_CONFIG(PORT_0_CFG, pinShift); + else + config = PIN_GET_PAD_CONFIG(PORT_1_CFG, pinShift); + + if (config == 2) + return true; + else + return false; +} + +bool digitalPinHasPWM(uint8_t p) +{ + return (p < 32) && ((p & 0xF) < 4); +} + +// function is used only if digitalPinHasPWM() is true +TIMER32_TypeDef *pwmPinToTimer(uint32_t digPinNumber) +{ + if (digPinNumber < 16) + { + return TIMER32_1; + } + else if ((digPinNumber >= 16) && (digPinNumber < 32)) + { + return TIMER32_2; + } + else + { + return NULL; + } +} + +// function is used only if digitalPinHasPWM() is true +HAL_TIMER32_CHANNEL_IndexTypeDef pwmPinToTimerChannel(uint32_t digPinNumber) +{ + switch (digPinNumber & 0x3) + { + case 0: + return TIMER32_CHANNEL_0; + case 1: + return TIMER32_CHANNEL_1; + case 2: + return TIMER32_CHANNEL_2; + case 3: + return TIMER32_CHANNEL_3; + default: + return 255; + } +} + +// ---------------------- interrupts ---------------------- // +// interrupt table is stored in ram to improve performance +// index = interrupt number. In each row {digitalPinNumber, IntLineValue, IntMuxValue} +uint8_t interruptInfo[EXTERNAL_INTERRUPTS_QTY][3] = +{ + {BTN_BUILTIN, GPIO_LINE_0, GPIO_MUX_LINE_0_PORT0_8}, // INT0 + {P1_9, GPIO_LINE_1, GPIO_MUX_LINE_1_PORT1_9}, // INT1 + {P0_10, GPIO_LINE_2, GPIO_MUX_LINE_2_PORT0_10}, // INT2 + {P1_15, GPIO_LINE_3, GPIO_MUX_LINE_3_PORT1_15}, // INT3 + {P0_12, GPIO_LINE_4, GPIO_MUX_LINE_4_PORT0_12}, // INT4 + {P0_13, GPIO_LINE_5, GPIO_MUX_LINE_5_PORT0_13}, // INT5 + {P0_14, GPIO_LINE_6, GPIO_MUX_LINE_6_PORT0_14}, // INT6 + {P0_15, GPIO_LINE_7, GPIO_MUX_LINE_7_PORT0_15}, // INT7 +}; + +int8_t digitalPinToGpioIntMux(uint8_t digPinNumber) +{ + for (uint8_t i = 0; i < EXTERNAL_INTERRUPTS_QTY; i++) + { + if (interruptInfo[i][0] == digPinNumber) + return interruptInfo[i][2]; + } + return NOT_AN_INTERRUPT; +} +int8_t digitalPinToGpioIntLine(uint8_t digPinNumber) +{ + for (uint8_t i = 0; i < EXTERNAL_INTERRUPTS_QTY; i++) + { + if (interruptInfo[i][0] == digPinNumber) + return interruptInfo[i][1]; + } + return NOT_AN_INTERRUPT; +} + +int8_t gpioIntLineToInterrupt(uint32_t gpioIntLine) +{ + for (uint8_t i = 0; i < EXTERNAL_INTERRUPTS_QTY; i++) + { + if (interruptInfo[i][1] == gpioIntLine) + return i; + } + return NOT_AN_INTERRUPT; +} + +int8_t digitalPinToInterrupt(uint32_t digPinNumber) +{ + for (uint8_t i = 0; i < EXTERNAL_INTERRUPTS_QTY; i++) + { + if (interruptInfo[i][0] == digPinNumber) + return i; + } + return NOT_AN_INTERRUPT; +} \ No newline at end of file