diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cbb0ca7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +# Specific +astyle.out +boards.local.txt +platform.local.txt +path_config.json +update_config.json +variant_config.json + +# Backup +*.bak +*.gho +*.ori +*.swp +*.tmp + +# macOS +# General +.DS_Store +.AppleDouble +.LSOverride + +# Patch +*.orig +*.rej + +# Python +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# VisualStudioCode +.vscode/* +*.code-workspace + +Unsupport/* diff --git a/ArduinoCore-AT32F403A/boards.txt b/ArduinoCore-AT32F403A/boards.txt new file mode 100644 index 0000000..ee7c063 --- /dev/null +++ b/ArduinoCore-AT32F403A/boards.txt @@ -0,0 +1,88 @@ +# +menu.upload_method=Upload method +menu.pll_clock_source=pll_clock_source +menu.pll_mult=pll_mult +menu.pll_output_range=pll_output_range + +WeActStudioAT32F4.name=AT32F403ACGU7 BlackPill Boards +WeActStudioAT32F4.build.mcu=cortex-m4 +WeActStudioAT32F4.build.f_cpu=80000000L +WeActStudioAT32F4.build.board=AT32F403ACGxx +WeActStudioAT32F4.build.vect_flags=-DUSER_ADDR_ROM=0x08000000 +WeActStudioAT32F4.build.core=arduino +WeActStudioAT32F4.build.extra_flags=-DAT32F403ACGU7 -USE_STDPERIPH_DRIVER +WeActStudioAT32F4.build.variant=AT32F403ACGU7 +WeActStudioAT32F4.build.variant_system_lib=FrameLib.a +WeActStudioAT32F4.build.ldscript=linker_scripts\AT32F403AxG_FLASH.ld + +WeActStudioAT32F4.menu.pll_clock_source.hext_div2=high speed external crystal div 2 +WeActStudioAT32F4.menu.pll_clock_source.hext_div2.build.f_pll_clock_source=2 +WeActStudioAT32F4.menu.pll_clock_source.hext_div2.build.f_hext_div=CRM_HEXT_DIV_2 +WeActStudioAT32F4.menu.pll_clock_source.hext_div2.build.f_hsi_div=CRM_HICK48_DIV6 +WeActStudioAT32F4.menu.pll_clock_source.hext_div3=high speed external crystal div 3 +WeActStudioAT32F4.menu.pll_clock_source.hext_div3.build.f_pll_clock_source=2 +WeActStudioAT32F4.menu.pll_clock_source.hext_div3.build.f_hext_div=CRM_HEXT_DIV_3 +WeActStudioAT32F4.menu.pll_clock_source.hext_div3.build.f_hsi_div=CRM_HICK48_DIV6 +WeActStudioAT32F4.menu.pll_clock_source.hext_div4=high speed external crystal div 4 +WeActStudioAT32F4.menu.pll_clock_source.hext_div4.build.f_pll_clock_source=2 +WeActStudioAT32F4.menu.pll_clock_source.hext_div4.build.f_hext_div=CRM_HEXT_DIV_4 +WeActStudioAT32F4.menu.pll_clock_source.hext_div4.build.f_hsi_div=CRM_HICK48_DIV6 +WeActStudioAT32F4.menu.pll_clock_source.hext_div5=high speed external crystal div 5 +WeActStudioAT32F4.menu.pll_clock_source.hext_div5.build.f_pll_clock_source=2 +WeActStudioAT32F4.menu.pll_clock_source.hext_div5.build.f_hext_div=CRM_HEXT_DIV_5 +WeActStudioAT32F4.menu.pll_clock_source.hext_div5.build.f_hsi_div=CRM_HICK48_DIV6 +WeActStudioAT32F4.menu.pll_clock_source.hext_div1=high speed external crystal div 1 +WeActStudioAT32F4.menu.pll_clock_source.hext_div1.build.f_pll_clock_source=1 +WeActStudioAT32F4.menu.pll_clock_source.hext_div1.build.f_hext_div=CRM_HEXT_DIV_2 +WeActStudioAT32F4.menu.pll_clock_source.hext_div1.build.f_hsi_div=CRM_HICK48_DIV6 +WeActStudioAT32F4.menu.pll_clock_source.hsi_div6=high speed internal clock(48mhz) div 6 +WeActStudioAT32F4.menu.pll_clock_source.hsi_div6.build.f_pll_clock_source=0 +WeActStudioAT32F4.menu.pll_clock_source.hsi_div6.build.f_hsi_div=CRM_HICK48_DIV6 +WeActStudioAT32F4.menu.pll_clock_source.hsi_div6.build.f_hext_div=CRM_HEXT_DIV_2 +WeActStudioAT32F4.menu.pll_clock_source.hsi_div1=high speed internal clock(48mhz) +WeActStudioAT32F4.menu.pll_clock_source.hsi_div1.build.f_pll_clock_source=0 +WeActStudioAT32F4.menu.pll_clock_source.hsi_div1.build.f_hsi_div=CRM_HICK48_NODIV +WeActStudioAT32F4.menu.pll_clock_source.hsi_div1.build.f_hext_div=CRM_HEXT_DIV_2 + +WeActStudioAT32F4.menu.pll_mult.pll_mult_60=pll multiplication factor 60 +WeActStudioAT32F4.menu.pll_mult.pll_mult_60.build.f_pll_mult=CRM_PLL_MULT_60 +WeActStudioAT32F4.menu.pll_mult.pll_mult_59=pll multiplication factor 59 +WeActStudioAT32F4.menu.pll_mult.pll_mult_59.build.f_pll_mult=CRM_PLL_MULT_59 +WeActStudioAT32F4.menu.pll_mult.pll_mult_58=pll multiplication factor 58 +WeActStudioAT32F4.menu.pll_mult.pll_mult_58.build.f_pll_mult=CRM_PLL_MULT_58 +WeActStudioAT32F4.menu.pll_mult.pll_mult_57=pll multiplication factor 57 +WeActStudioAT32F4.menu.pll_mult.pll_mult_57.build.f_pll_mult=CRM_PLL_MULT_57 +WeActStudioAT32F4.menu.pll_mult.pll_mult_56=pll multiplication factor 56 +WeActStudioAT32F4.menu.pll_mult.pll_mult_56.build.f_pll_mult=CRM_PLL_MULT_56 +WeActStudioAT32F4.menu.pll_mult.pll_mult_55=pll multiplication factor 55 +WeActStudioAT32F4.menu.pll_mult.pll_mult_55.build.f_pll_mult=CRM_PLL_MULT_55 +WeActStudioAT32F4.menu.pll_mult.pll_mult_54=pll multiplication factor 54 +WeActStudioAT32F4.menu.pll_mult.pll_mult_54.build.f_pll_mult=CRM_PLL_MULT_54 +WeActStudioAT32F4.menu.pll_mult.pll_mult_53=pll multiplication factor 53 +WeActStudioAT32F4.menu.pll_mult.pll_mult_53.build.f_pll_mult=CRM_PLL_MULT_53 +WeActStudioAT32F4.menu.pll_mult.pll_mult_52=pll multiplication factor 52 +WeActStudioAT32F4.menu.pll_mult.pll_mult_52.build.f_pll_mult=CRM_PLL_MULT_52 +WeActStudioAT32F4.menu.pll_mult.pll_mult_51=pll multiplication factor 51 +WeActStudioAT32F4.menu.pll_mult.pll_mult_51.build.f_pll_mult=CRM_PLL_MULT_51 +WeActStudioAT32F4.menu.pll_mult.pll_mult_50=pll multiplication factor 50 +WeActStudioAT32F4.menu.pll_mult.pll_mult_50.build.f_pll_mult=CRM_PLL_MULT_50 +WeActStudioAT32F4.menu.pll_mult.pll_mult_40=pll multiplication factor 40 +WeActStudioAT32F4.menu.pll_mult.pll_mult_40.build.f_pll_mult=CRM_PLL_MULT_40 +WeActStudioAT32F4.menu.pll_mult.pll_mult_30=pll multiplication factor 30 +WeActStudioAT32F4.menu.pll_mult.pll_mult_30.build.f_pll_mult=CRM_PLL_MULT_30 +WeActStudioAT32F4.menu.pll_mult.pll_mult_20=pll multiplication factor 20 +WeActStudioAT32F4.menu.pll_mult.pll_mult_20.build.f_pll_mult=CRM_PLL_MULT_20 +WeActStudioAT32F4.menu.pll_mult.pll_mult_10=pll multiplication factor 10 +WeActStudioAT32F4.menu.pll_mult.pll_mult_10.build.f_pll_mult=CRM_PLL_MULT_10 +WeActStudioAT32F4.menu.pll_mult.pll_mult_2=pll multiplication factor 2 +WeActStudioAT32F4.menu.pll_mult.pll_mult_2.build.f_pll_mult=CRM_PLL_MULT_2 + +WeActStudioAT32F4.menu.pll_output_range.pll_output_range_gt72mhz=pll clock output range greater than 72mhz +WeActStudioAT32F4.menu.pll_output_range.pll_output_range_gt72mhz.build.f_pll_output_range=CRM_PLL_OUTPUT_RANGE_GT72MHZ +WeActStudioAT32F4.menu.pll_output_range.pll_output_range_le72mhz=pll clock output range less than or equal to 72mhz +WeActStudioAT32F4.menu.pll_output_range.pll_output_range_le72mhz.build.f_pll_output_range=CRM_PLL_OUTPUT_RANGE_LE72MHZ + +WeActStudioAT32F4.menu.upload_method.USBDFUMethod=Artery DFU ISP +WeActStudioAT32F4.menu.upload_method.USBDFUMethod.upload.protocol=Artery_ISP +WeActStudioAT32F4.menu.upload_method.USBDFUMethod.upload.tool=Artery_ISP_Console +WeActStudioAT32F4.menu.upload_method.USBDFUMethod.upload.maximum_size=1048576 \ No newline at end of file diff --git a/ArduinoCore-AT32F403A/cores/arduino/Arduino.h b/ArduinoCore-AT32F403A/cores/arduino/Arduino.h new file mode 100644 index 0000000..f9bc4d1 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/Arduino.h @@ -0,0 +1,118 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARDUINO_H +#define __ARDUINO_H + +#include +#include +#include "libcore/mcu_core.h" +#include "binary.h" +#include "avr/pgmspace.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define KEILDUINO_VERSION 100 + +#define PI 3.1415926535897932384626433832795f +#define HALF_PI 1.5707963267948966192313216916398f +#define TWO_PI 6.283185307179586476925286766559f +#define DEG_TO_RAD 0.017453292519943295769236907684886f +#define RAD_TO_DEG 57.295779513082320876798154814105f +#define EULER 2.718281828459045235360287471352f + +#define SERIAL 0x0 +#define DISPLAY 0x1 + +#define LSBFIRST 0x0 +#define MSBFIRST 0x1 + +#define LOW 0x0 +#define HIGH 0x1 + +#define min(a,b) ((a)<(b)?(a):(b)) +#define max(a,b) ((a)>(b)?(a):(b)) +#define ABS(x) (((x)>0)?(x):-(x)) //abs(x) is define in stdlib.h +#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) +#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) +#define radians(deg) ((deg)*DEG_TO_RAD) +#define degrees(rad) ((rad)*RAD_TO_DEG) +#define sq(x) ((x)*(x)) + +#define lowByte(w) ((uint8_t) ((w) & 0xff)) +#define highByte(w) ((uint8_t) ((w) >> 8)) + +#define bitRead(value, bit) (((value) >> (bit)) & 0x01) +#define bitSet(value, bit) ((value) |= (1UL << (bit))) +#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) +#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) + +#ifndef _BV +# define _BV(bit) (1 << (bit)) +#endif + +#define clockCyclesPerMicrosecond() (F_CPU / 1000000L) +#define clockCyclesToMicroseconds(a) (((a) * 1000L) / (F_CPU / 1000L)) +#define microsecondsToClockCycles(a) ((a) * (F_CPU / 1000000L)) + +#define delay(ms) delay_ms(ms) +#define delayMicroseconds(us) delay_us(us) + +#define interrupts() sei() +#define noInterrupts() cli() + +#define NOT_A_PIN 0xFF +#define NOT_A_PORT 0xFF +#define NOT_AN_INTERRUPT -1 + +#define boolean bool +typedef unsigned char byte; + +void pinMode(uint8_t pin, PinMode_TypeDef mode); +void digitalWrite(uint8_t pin, uint8_t value); +uint8_t digitalRead(uint8_t pin); +void analogWrite(uint8_t pin, uint16_t value); +uint16_t analogRead(uint8_t pin); +uint16_t analogRead_DMA(uint8_t pin); +void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t value); +uint32_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint32_t bitOrder); +uint32_t pulseIn(uint32_t pin, uint32_t state, uint32_t timeout); + +long map(long x, long in_min, long in_max, long out_min, long out_max); +float fmap(float x, float in_min, float in_max, float out_min, float out_max); +void yield(void); + +#ifdef __cplusplus +}// extern "C" +#endif + +#ifdef __cplusplus +# include "WCharacter.h" +# include "WString.h" +# include "WMath.h" +# include +# include +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/Print.cpp b/ArduinoCore-AT32F403A/cores/arduino/Print.cpp new file mode 100644 index 0000000..f404404 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/Print.cpp @@ -0,0 +1,288 @@ +/* + Print.cpp - Base class that provides print() and println() + Copyright (c) 2008 David A. Mellis. All right reserved. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 23 November 2006 by David A. Mellis + Modified 03 August 2015 by Chuck Todd + */ + +#include +#include +#include +#include "Print.h" +#include "libcore/config/mcu_config.h" + +// Public Methods ////////////////////////////////////////////////////////////// + +/* default implementation: may be overridden */ +size_t Print::write(const uint8_t *buffer, size_t size) +{ + size_t n = 0; + while (size--) + { + if (write(*buffer++)) n++; + else break; + } + return n; +} + +size_t Print::print(const __FlashStringHelper *ifsh) +{ + PGM_P p = reinterpret_cast(ifsh); + size_t n = 0; + while (1) + { + unsigned char c = pgm_read_byte(p++); + if (c == 0) break; + if (write(c)) n++; + else break; + } + return n; +} + +size_t Print::print(const String &s) +{ + return write(s.c_str(), s.length()); +} + +size_t Print::print(const char str[]) +{ + return write(str); +} + +size_t Print::print(char c) +{ + return write(c); +} + +size_t Print::print(unsigned char b, int base) +{ + return print((unsigned long) b, base); +} + +size_t Print::print(int n, int base) +{ + return print((long) n, base); +} + +size_t Print::print(unsigned int n, int base) +{ + return print((unsigned long) n, base); +} + +size_t Print::print(long n, int base) +{ + if (base == 0) + { + return write(n); + } + else if (base == 10) + { + if (n < 0) + { + int t = print('-'); + n = -n; + return printNumber(n, 10) + t; + } + return printNumber(n, 10); + } + else + { + return printNumber(n, base); + } +} + +size_t Print::print(unsigned long n, int base) +{ + if (base == 0) return write(n); + else return printNumber(n, base); +} + +size_t Print::print(double n, int digits) +{ + return printFloat(n, digits); +} + +size_t Print::println(const __FlashStringHelper *ifsh) +{ + size_t n = print(ifsh); + n += println(); + return n; +} + +size_t Print::print(const Printable& x) +{ + return x.printTo(*this); +} + +size_t Print::println(void) +{ + return write("\r\n"); +} + +size_t Print::println(const String &s) +{ + size_t n = print(s); + n += println(); + return n; +} + +size_t Print::println(const char c[]) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(char c) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(unsigned char b, int base) +{ + size_t n = print(b, base); + n += println(); + return n; +} + +size_t Print::println(int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(double num, int digits) +{ + size_t n = print(num, digits); + n += println(); + return n; +} + +size_t Print::println(const Printable& x) +{ + size_t n = print(x); + n += println(); + return n; +} + +// Private Methods ///////////////////////////////////////////////////////////// + +size_t Print::printNumber(unsigned long n, uint8_t base) +{ + char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. + char *str = &buf[sizeof(buf) - 1]; + + *str = '\0'; + + // prevent crash if called with base == 1 + if (base < 2) base = 10; + + do + { + char c = n % base; + n /= base; + + *--str = c < 10 ? c + '0' : c + 'A' - 10; + } + while(n); + + return write(str); +} + +size_t Print::printFloat(double number, uint8_t digits) +{ + size_t n = 0; + + if (isnan(number)) return print("nan"); + if (isinf(number)) return print("inf"); + if (number > 4294967040.0) return print ("ovf"); // constant determined empirically + if (number < -4294967040.0) return print ("ovf"); // constant determined empirically + + // Handle negative numbers + if (number < 0.0) + { + n += print('-'); + number = -number; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + for (uint8_t i = 0; i < digits; ++i) + rounding /= 10.0; + + number += rounding; + + // Extract the integer part of the number and print it + unsigned long int_part = (unsigned long)number; + double remainder = number - (double)int_part; + n += print(int_part); + + // Print the decimal point, but only if there are digits beyond + if (digits > 0) + { + n += print('.'); + } + + // Extract digits from the remainder one at a time + while (digits-- > 0) + { + remainder *= 10.0; + unsigned int toPrint = (unsigned int)(remainder); + n += print(toPrint); + remainder -= toPrint; + } + + return n; +} + +int Print::printf (const char *__restrict __format, ...) +{ + char printf_buff[PRINT_PRINTF_BUFFER_LENGTH]; + + va_list args; + va_start(args, __format); + int ret_status = vsnprintf(printf_buff, sizeof(printf_buff), __format, args); + va_end(args); + print(printf_buff); + + return ret_status; +} diff --git a/ArduinoCore-AT32F403A/cores/arduino/Print.h b/ArduinoCore-AT32F403A/cores/arduino/Print.h new file mode 100644 index 0000000..343cae6 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/Print.h @@ -0,0 +1,109 @@ +/* + Print.h - Base class that provides print() and println() + Copyright (c) 2008 David A. Mellis. All right reserved. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Print_h +#define Print_h + +#include +#include // for size_t + +#include "WString.h" +#include "Printable.h" + +#define DEC 10 +#define HEX 16 +#define OCT 8 +#ifdef BIN // Prevent warnings if BIN is previously defined in "iotnx4.h" or similar +#undef BIN +#endif +#define BIN 2 + +class Print +{ +private: + int write_error; + size_t printNumber(unsigned long, uint8_t); + size_t printFloat(double, uint8_t); +protected: + void setWriteError(int err = 1) + { + write_error = err; + } +public: + Print() : write_error(0) {} + + int getWriteError() + { + return write_error; + } + void clearWriteError() + { + setWriteError(0); + } + + virtual size_t write(uint8_t) = 0; + size_t write(const char *str) + { + if (str == NULL) return 0; + return write((const uint8_t *)str, strlen(str)); + } + virtual size_t write(const uint8_t *buffer, size_t size); + size_t write(const char *buffer, size_t size) + { + return write((const uint8_t *)buffer, size); + } + + // default to zero, meaning "a single write may block" + // should be overridden by subclasses with buffering + virtual int availableForWrite() + { + return 0; + } + + size_t print(const __FlashStringHelper *); + size_t print(const String &); + size_t print(const char[]); + size_t print(char); + size_t print(unsigned char, int = DEC); + size_t print(int, int = DEC); + size_t print(unsigned int, int = DEC); + size_t print(long, int = DEC); + size_t print(unsigned long, int = DEC); + size_t print(double, int = 2); + size_t print(const Printable&); + + size_t println(const __FlashStringHelper *); + size_t println(const String &s); + size_t println(const char[]); + size_t println(char); + size_t println(unsigned char, int = DEC); + size_t println(int, int = DEC); + size_t println(unsigned int, int = DEC); + size_t println(long, int = DEC); + size_t println(unsigned long, int = DEC); + size_t println(double, int = 2); + size_t println(const Printable&); + size_t println(void); + + int printf(const char * format, ...); + + virtual void flush() { /* Empty implementation for backward compatibility */ } +}; + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/Printable.h b/ArduinoCore-AT32F403A/cores/arduino/Printable.h new file mode 100644 index 0000000..2a1b2e9 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/Printable.h @@ -0,0 +1,40 @@ +/* + Printable.h - Interface class that allows printing of complex types + Copyright (c) 2011 Adrian McEwen. All right reserved. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Printable_h +#define Printable_h + +#include + +class Print; + +/** The Printable class provides a way for new classes to allow themselves to be printed. + By deriving from Printable and implementing the printTo method, it will then be possible + for users to print out instances of this class by passing them into the usual + Print::print and Print::println methods. +*/ + +class Printable +{ + public: + virtual size_t printTo(Print& p) const = 0; +}; + +#endif + diff --git a/ArduinoCore-AT32F403A/cores/arduino/Stream.cpp b/ArduinoCore-AT32F403A/cores/arduino/Stream.cpp new file mode 100644 index 0000000..0b81275 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/Stream.cpp @@ -0,0 +1,346 @@ +/* + Stream.cpp - adds parsing methods to Stream class + Copyright (c) 2008 David A. Mellis. All right reserved. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Created July 2011 + parsing functions based on TextFinder library by Michael Margolis + + findMulti/findUntil routines written by Jim Leonard/Xuth + */ + +#include "Arduino.h" +#include "Stream.h" + +#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait + +// protected method to read stream with timeout +int Stream::timedRead() +{ + int c; + _startMillis = millis(); + do + { + c = read(); + if (c >= 0) return c; + } + while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// protected method to peek stream with timeout +int Stream::timedPeek() +{ + int c; + _startMillis = millis(); + do + { + c = peek(); + if (c >= 0) return c; + } + while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// returns peek of the next digit in the stream or -1 if timeout +// discards non-numeric characters +int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal) +{ + int c; + while (1) + { + c = timedPeek(); + + if( c < 0 || + c == '-' || + (c >= '0' && c <= '9') || + (detectDecimal && c == '.')) return c; + + switch( lookahead ) + { + case SKIP_NONE: + return -1; // Fail code. + case SKIP_WHITESPACE: + switch( c ) + { + case ' ': + case '\t': + case '\r': + case '\n': + break; + default: + return -1; // Fail code. + } + case SKIP_ALL: + break; + } + read(); // discard non-numeric + } +} + +// Public Methods +////////////////////////////////////////////////////////////// + +void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait +{ + _timeout = timeout; +} + +// find returns true if the target string is found +bool Stream::find(char *target) +{ + return findUntil(target, strlen(target), NULL, 0); +} + +// reads data from the stream until the target string of given length is found +// returns true if target string is found, false if timed out +bool Stream::find(char *target, size_t length) +{ + return findUntil(target, length, NULL, 0); +} + +// as find but search ends if the terminator string is found +bool Stream::findUntil(char *target, char *terminator) +{ + return findUntil(target, strlen(target), terminator, strlen(terminator)); +} + +// reads data from the stream until the target string of the given length is found +// search terminated if the terminator string is found +// returns true if target string is found, false if terminated or timed out +bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen) +{ + if (terminator == NULL) + { + MultiTarget t[1] = {{target, targetLen, 0}}; + return findMulti(t, 1) == 0 ? true : false; + } + else + { + MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}}; + return findMulti(t, 2) == 0 ? true : false; + } +} + +// returns the first valid (long) integer value from the current position. +// lookahead determines how parseInt looks ahead in the stream. +// See LookaheadMode enumeration at the top of the file. +// Lookahead is terminated by the first character that is not a valid part of an integer. +// Once parsing commences, 'ignore' will be skipped in the stream. +long Stream::parseInt(LookaheadMode lookahead, char ignore) +{ + bool isNegative = false; + long value = 0; + int c; + + c = peekNextDigit(lookahead, false); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do + { + if(c == ignore) + ; // ignore this character + else if(c == '-') + isNegative = true; + else if(c >= '0' && c <= '9') // is c a digit? + value = value * 10 + c - '0'; + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || c == ignore ); + + if(isNegative) + value = -value; + return value; +} + +// as parseInt but returns a floating point value +float Stream::parseFloat(LookaheadMode lookahead, char ignore) +{ + bool isNegative = false; + bool isFraction = false; + long value = 0; + int c; + float fraction = 1.0; + + c = peekNextDigit(lookahead, true); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do + { + if(c == ignore) + ; // ignore + else if(c == '-') + isNegative = true; + else if (c == '.') + isFraction = true; + else if(c >= '0' && c <= '9') // is c a digit? + { + value = value * 10 + c - '0'; + if(isFraction) + fraction *= 0.1f; + } + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || (c == '.' && !isFraction) || c == ignore ); + + if(isNegative) + value = -value; + if(isFraction) + return value * fraction; + else + return value; +} + +// read characters from stream into buffer +// terminates if length characters have been read, or timeout (see setTimeout) +// returns the number of characters placed in the buffer +// the buffer is NOT null terminated. +// +size_t Stream::readBytes(char *buffer, size_t length) +{ + size_t count = 0; + while (count < length) + { + int c = timedRead(); + if (c < 0) break; + *buffer++ = (char)c; + count++; + } + return count; +} + + +// as readBytes with terminator character +// terminates if length characters have been read, timeout, or if the terminator character detected +// returns the number of characters placed in the buffer (0 means no valid data found) + +size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) +{ + size_t index = 0; + while (index < length) + { + int c = timedRead(); + if (c < 0 || c == terminator) break; + *buffer++ = (char)c; + index++; + } + return index; // return number of characters, not including null terminator +} + +String Stream::readString() +{ + String ret; + int c = timedRead(); + while (c >= 0) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +String Stream::readStringUntil(char terminator) +{ + String ret; + int c = timedRead(); + while (c >= 0 && c != terminator) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) +{ + // any zero length target string automatically matches and would make + // a mess of the rest of the algorithm. + for (struct MultiTarget *t = targets; t < targets + tCount; ++t) + { + if (t->len <= 0) + return t - targets; + } + + while (1) + { + int c = timedRead(); + if (c < 0) + return -1; + + for (struct MultiTarget *t = targets; t < targets + tCount; ++t) + { + // the simple case is if we match, deal with that first. + if (c == t->str[t->index]) + { + if (++t->index == t->len) + return t - targets; + else + continue; + } + + // if not we need to walk back and see if we could have matched further + // down the stream (ie '1112' doesn't match the first position in '11112' + // but it will match the second position so we can't just reset the current + // index to 0 when we find a mismatch. + if (t->index == 0) + continue; + + int origIndex = t->index; + do + { + --t->index; + // first check if current char works against the new current index + if (c != t->str[t->index]) + continue; + + // if it's the only char then we're good, nothing more to check + if (t->index == 0) + { + t->index++; + break; + } + + // otherwise we need to check the rest of the found string + int diff = origIndex - t->index; + size_t i; + for (i = 0; i < t->index; ++i) + { + if (t->str[i] != t->str[i + diff]) + break; + } + + // if we successfully got through the previous loop then our current + // index is good. + if (i == t->index) + { + t->index++; + break; + } + + // otherwise we just try the next index + } + while (t->index); + } + } + // unreachable + //return -1; +} diff --git a/ArduinoCore-AT32F403A/cores/arduino/Stream.h b/ArduinoCore-AT32F403A/cores/arduino/Stream.h new file mode 100644 index 0000000..99471ac --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/Stream.h @@ -0,0 +1,165 @@ +/* + Stream.h - base class for character-based streams. + Copyright (c) 2010 David A. Mellis. All right reserved. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + parsing functions based on TextFinder library by Michael Margolis +*/ + +#ifndef Stream_h +#define Stream_h + +#include +#include "Print.h" + +// compatibility macros for testing +/* +#define getInt() parseInt() +#define getInt(ignore) parseInt(ignore) +#define getFloat() parseFloat() +#define getFloat(ignore) parseFloat(ignore) +#define getString( pre_string, post_string, buffer, length) +readBytesBetween( pre_string, terminator, buffer, length) +*/ + +// This enumeration provides the lookahead options for parseInt(), parseFloat() +// The rules set out here are used until either the first valid character is found +// or a time out occurs due to lack of input. +enum LookaheadMode +{ + SKIP_ALL, // All invalid characters are ignored. + SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid. + SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped. +}; + +#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field + +class Stream : public Print +{ +protected: + unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read + unsigned long _startMillis; // used for timeout measurement + int timedRead(); // read stream with timeout + int timedPeek(); // peek stream with timeout + int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout + +public: + virtual int available() = 0; + virtual int read() = 0; + virtual int peek() = 0; + + Stream() + : _timeout(1000) + , _startMillis(0) + { + } + +// parsing methods + + void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second + unsigned long getTimeout(void) + { + return _timeout; + } + + bool find(char *target); // reads data from the stream until the target string is found + bool find(uint8_t *target) + { + return find ((char *)target); + } + // returns true if target string is found, false if timed out (see setTimeout) + + bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found + bool find(uint8_t *target, size_t length) + { + return find ((char *)target, length); + } + // returns true if target string is found, false if timed out + + bool find(char target) + { + return find (&target, 1); + } + + bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found + bool findUntil(uint8_t *target, char *terminator) + { + return findUntil((char *)target, terminator); + } + + bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found + bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) + { + return findUntil((char *)target, targetLen, terminate, termLen); + } + + long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); + // returns the first valid (long) integer value from the current position. + // lookahead determines how parseInt looks ahead in the stream. + // See LookaheadMode enumeration at the top of the file. + // Lookahead is terminated by the first character that is not a valid part of an integer. + // Once parsing commences, 'ignore' will be skipped in the stream. + + float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); + // float version of parseInt + + size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer + size_t readBytes( uint8_t *buffer, size_t length) + { + return readBytes((char *)buffer, length); + } + // terminates if length characters have been read or timeout (see setTimeout) + // returns the number of characters placed in the buffer (0 means no valid data found) + + size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character + size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) + { + return readBytesUntil(terminator, (char *)buffer, length); + } + // terminates if length characters have been read, timeout, or if the terminator character detected + // returns the number of characters placed in the buffer (0 means no valid data found) + + // Arduino String functions to be added here + String readString(); + String readStringUntil(char terminator); + +protected: + long parseInt(char ignore) + { + return parseInt(SKIP_ALL, ignore); + } + float parseFloat(char ignore) + { + return parseFloat(SKIP_ALL, ignore); + } + // These overload exists for compatibility with any class that has derived + // Stream and used parseFloat/Int with a custom ignore character. To keep + // the public API simple, these overload remains protected. + + struct MultiTarget + { + const char *str; // string you're searching for + size_t len; // length of string you're searching for + size_t index; // index used by the search routine. + }; + + // This allows you to search for an arbitrary number of strings. + // Returns index of the target that is found first or -1 if timeout occurs. + int findMulti(struct MultiTarget *targets, int tCount); +}; + +#undef NO_IGNORE_CHAR +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/WCharacter.h b/ArduinoCore-AT32F403A/cores/arduino/WCharacter.h new file mode 100644 index 0000000..fcd6329 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/WCharacter.h @@ -0,0 +1,171 @@ +/* + WCharacter.h - Character utility functions for Wiring & Arduino + Copyright (c) 2010 Hernando Barragan. All right reserved. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef Character_h +#define Character_h + +#include + +// #define isascii(c) ((unsigned int)c < 0x7F) +// #define toascii(c) ((unsigned char)c) + +// WCharacter.h prototypes +inline bool isAlphaNumeric(int c) __attribute__((always_inline)); +inline bool isAlpha(int c) __attribute__((always_inline)); +inline bool isAscii(int c) __attribute__((always_inline)); +inline bool isWhitespace(int c) __attribute__((always_inline)); +inline bool isControl(int c) __attribute__((always_inline)); +inline bool isDigit(int c) __attribute__((always_inline)); +inline bool isGraph(int c) __attribute__((always_inline)); +inline bool isLowerCase(int c) __attribute__((always_inline)); +inline bool isPrintable(int c) __attribute__((always_inline)); +inline bool isPunct(int c) __attribute__((always_inline)); +inline bool isSpace(int c) __attribute__((always_inline)); +inline bool isUpperCase(int c) __attribute__((always_inline)); +inline bool isHexadecimalDigit(int c) __attribute__((always_inline)); +inline int toAscii(int c) __attribute__((always_inline)); +inline int toLowerCase(int c) __attribute__((always_inline)); +inline int toUpperCase(int c)__attribute__((always_inline)); + + +// Checks for an alphanumeric character. +// It is equivalent to (isalpha(c) || isdigit(c)). +inline bool isAlphaNumeric(int c) +{ + return ( isalnum(c) == 0 ? false : true); +} + + +// Checks for an alphabetic character. +// It is equivalent to (isupper(c) || islower(c)). +inline bool isAlpha(int c) +{ + return ( isalpha(c) == 0 ? false : true); +} + + +// Checks whether c is a 7-bit unsigned char value +// that fits into the ASCII character set. +inline bool isAscii(int c) +{ + return ( isascii (c) == 0 ? false : true); +} + + +// Checks for a blank character, that is, a space or a tab. +inline bool isWhitespace(int c) +{ + return ( isblank (c) == 0 ? false : true); +} + + +// Checks for a control character. +inline bool isControl(int c) +{ + return ( iscntrl (c) == 0 ? false : true); +} + + +// Checks for a digit (0 through 9). +inline bool isDigit(int c) +{ + return ( isdigit (c) == 0 ? false : true); +} + + +// Checks for any printable character except space. +inline bool isGraph(int c) +{ + return ( isgraph (c) == 0 ? false : true); +} + + +// Checks for a lower-case character. +inline bool isLowerCase(int c) +{ + return (islower (c) == 0 ? false : true); +} + + +// Checks for any printable character including space. +inline bool isPrintable(int c) +{ + return ( isprint (c) == 0 ? false : true); +} + + +// Checks for any printable character which is not a space +// or an alphanumeric character. +inline bool isPunct(int c) +{ + return ( ispunct (c) == 0 ? false : true); +} + + +// Checks for white-space characters. For the avr-libc library, +// these are: space, formfeed ('\f'), newline ('\n'), carriage +// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). +inline bool isSpace(int c) +{ + return ( isspace (c) == 0 ? false : true); +} + + +// Checks for an uppercase letter. +inline bool isUpperCase(int c) +{ + return ( isupper (c) == 0 ? false : true); +} + + +// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7 +// 8 9 a b c d e f A B C D E F. +inline bool isHexadecimalDigit(int c) +{ + return ( isxdigit (c) == 0 ? false : true); +} + + +// Converts c to a 7-bit unsigned char value that fits into the +// ASCII character set, by clearing the high-order bits. +inline int toAscii(int c) +{ + return toascii (c); +} + + +// Warning: +// Many people will be unhappy if you use this function. +// This function will convert accented letters into random +// characters. + +// Converts the letter c to lower case, if possible. +inline int toLowerCase(int c) +{ + return tolower (c); +} + + +// Converts the letter c to upper case, if possible. +inline int toUpperCase(int c) +{ + return toupper (c); +} + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/WMath.cpp b/ArduinoCore-AT32F403A/cores/arduino/WMath.cpp new file mode 100644 index 0000000..649e587 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/WMath.cpp @@ -0,0 +1,60 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Wiring project - http://wiring.org.co + Copyright (c) 2004-06 Hernando Barragan + Modified 13 August 2006, David A. Mellis for Arduino - http://www.arduino.cc/ + + 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 +*/ +#include "WMath.h" + +void randomSeed(unsigned long seed) +{ + if (seed != 0) + { + srand(seed); + } +} + +long random(long howbig) +{ + if (howbig == 0) + { + return 0; + } + return rand() % howbig; +} + +long random(long howsmall, long howbig) +{ + if (howsmall >= howbig) + { + return howsmall; + } + long diff = howbig - howsmall; + return random(diff) + howsmall; +} + +unsigned int makeWord(unsigned int w) +{ + return w; +} + +unsigned int makeWord(unsigned char h, unsigned char l) +{ + return (h << 8) | l; +} diff --git a/ArduinoCore-AT32F403A/cores/arduino/WMath.h b/ArduinoCore-AT32F403A/cores/arduino/WMath.h new file mode 100644 index 0000000..f19920e --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/WMath.h @@ -0,0 +1,12 @@ +#ifndef __WMATH_H +#define __WMATH_H + +extern "C" { +#include "stdlib.h" +} + +void randomSeed(unsigned long seed); +long random(long howbig); +long random(long howsmall, long howbig); + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/WProgram.h b/ArduinoCore-AT32F403A/cores/arduino/WProgram.h new file mode 100644 index 0000000..10af95c --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/WProgram.h @@ -0,0 +1,6 @@ +#ifndef __WPROGRAM_H +#define __WPROGRAM_H + +#include "Arduino.h" + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/WString.cpp b/ArduinoCore-AT32F403A/cores/arduino/WString.cpp new file mode 100644 index 0000000..775fce1 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/WString.cpp @@ -0,0 +1,791 @@ +/* + WString.cpp - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All rights reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "WString.h" +#include "itoa.h" +#include "dtostrf.h" +#include "libcore/config/mcu_config.h" +#include WSTRING_MEM_INCLUDE + +/*********************************************/ +/* Constructors */ +/*********************************************/ + +String::String(const char *cstr) +{ + init(); + if (cstr) copy(cstr, strlen(cstr)); +} + +String::String(const String &value) +{ + init(); + *this = value; +} + +String::String(const __FlashStringHelper *pstr) +{ + init(); + *this = pstr; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +String::String(String &&rval) +{ + init(); + move(rval); +} +String::String(StringSumHelper &&rval) +{ + init(); + move(rval); +} +#endif + +String::String(char c) +{ + init(); + char buf[2]; + buf[0] = c; + buf[1] = 0; + *this = buf; +} + +String::String(unsigned char value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned char)]; + utoa(value, buf, base); + *this = buf; +} + +String::String(int value, unsigned char base) +{ + init(); + char buf[2 + 8 * sizeof(int)]; + itoa(value, buf, base); + *this = buf; +} + +String::String(unsigned int value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned int)]; + utoa(value, buf, base); + *this = buf; +} + +String::String(long value, unsigned char base) +{ + init(); + char buf[2 + 8 * sizeof(long)]; + ltoa(value, buf, base); + *this = buf; +} + +String::String(unsigned long value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned long)]; + ultoa(value, buf, base); + *this = buf; +} + +String::String(float value, unsigned char decimalPlaces) +{ + init(); + char buf[33]; + *this = dtostrnf(value, (decimalPlaces + 2), decimalPlaces, buf, sizeof(buf)); +} + +String::String(double value, unsigned char decimalPlaces) +{ + init(); + char buf[33]; + *this = dtostrnf(value, (decimalPlaces + 2), decimalPlaces, buf, sizeof(buf)); +} + +String::~String() +{ + if (buffer) WSTRING_MEM_FREE(buffer); +} + +/*********************************************/ +/* Memory Management */ +/*********************************************/ + +inline void String::init(void) +{ + buffer = NULL; + capacity = 0; + len = 0; +} + +void String::invalidate(void) +{ + if (buffer) WSTRING_MEM_FREE(buffer); + buffer = NULL; + capacity = len = 0; +} + +unsigned char String::reserve(unsigned int size) +{ + if (buffer && capacity >= size) return 1; + if (changeBuffer(size)) + { + if (len == 0) buffer[0] = 0; + return 1; + } + return 0; +} + +unsigned char String::changeBuffer(unsigned int maxStrLen) +{ + char *newbuffer = (char *)WSTRING_MEM_REALLOC(buffer, maxStrLen + 1); + if (newbuffer) + { + buffer = newbuffer; + capacity = maxStrLen; + return 1; + } + return 0; +} + +/*********************************************/ +/* Copy and Move */ +/*********************************************/ + +String & String::copy(const char *cstr, unsigned int length) +{ + if (!reserve(length)) + { + invalidate(); + return *this; + } + len = length; + strcpy(buffer, cstr); + return *this; +} + +String & String::copy(const __FlashStringHelper *pstr, unsigned int length) +{ + if (!reserve(length)) + { + invalidate(); + return *this; + } + len = length; + strcpy(buffer, (PGM_P)pstr); + return *this; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +void String::move(String &rhs) +{ + if (buffer) + { + if (rhs && capacity >= rhs.len) + { + strcpy(buffer, rhs.buffer); + len = rhs.len; + rhs.len = 0; + return; + } + else + { + WSTRING_MEM_FREE(buffer); + } + } + buffer = rhs.buffer; + capacity = rhs.capacity; + len = rhs.len; + rhs.buffer = NULL; + rhs.capacity = 0; + rhs.len = 0; +} +#endif + +String & String::operator = (const String &rhs) +{ + if (this == &rhs) return *this; + + if (rhs.buffer) copy(rhs.buffer, rhs.len); + else invalidate(); + + return *this; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +String & String::operator = (String &&rval) +{ + if (this != &rval) move(rval); + return *this; +} + +String & String::operator = (StringSumHelper &&rval) +{ + if (this != &rval) move(rval); + return *this; +} +#endif + +String & String::operator = (const char *cstr) +{ + if (cstr) copy(cstr, strlen(cstr)); + else invalidate(); + + return *this; +} + +String & String::operator = (const __FlashStringHelper *pstr) +{ + if (pstr) copy(pstr, strlen((PGM_P)pstr)); + else invalidate(); + + return *this; +} + +/*********************************************/ +/* concat */ +/*********************************************/ + +unsigned char String::concat(const String &s) +{ + return concat(s.buffer, s.len); +} + +unsigned char String::concat(const char *cstr, unsigned int length) +{ + unsigned int newlen = len + length; + if (!cstr) return 0; + if (length == 0) return 1; + if (!reserve(newlen)) return 0; + strcpy(buffer + len, cstr); + len = newlen; + return 1; +} + +unsigned char String::concat(const char *cstr) +{ + if (!cstr) return 0; + return concat(cstr, strlen(cstr)); +} + +unsigned char String::concat(char c) +{ + char buf[2]; + buf[0] = c; + buf[1] = 0; + return concat(buf, 1); +} + +unsigned char String::concat(unsigned char num) +{ + char buf[1 + 3 * sizeof(unsigned char)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(int num) +{ + char buf[2 + 3 * sizeof(int)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned int num) +{ + char buf[1 + 3 * sizeof(unsigned int)]; + utoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(long num) +{ + char buf[2 + 3 * sizeof(long)]; + ltoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned long num) +{ + char buf[1 + 3 * sizeof(unsigned long)]; + ultoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(float num) +{ + char buf[20]; + char* string = dtostrnf(num, 4, 2, buf, sizeof(buf)); + return concat(string, strlen(string)); +} + +unsigned char String::concat(double num) +{ + char buf[20]; + char* string = dtostrnf(num, 4, 2, buf, sizeof(buf)); + return concat(string, strlen(string)); +} + +unsigned char String::concat(const __FlashStringHelper * str) +{ + if (!str) return 0; + int length = strlen((const char *) str); + if (length == 0) return 1; + unsigned int newlen = len + length; + if (!reserve(newlen)) return 0; + strcpy(buffer + len, (const char *) str); + len = newlen; + return 1; +} + +/*********************************************/ +/* Concatenate */ +/*********************************************/ + +StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr) +{ + StringSumHelper &a = const_cast(lhs); + if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, char c) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(c)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, float num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, double num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs)) a.invalidate(); + return a; +} + +/*********************************************/ +/* Comparison */ +/*********************************************/ + +int String::compareTo(const String &s) const +{ + if (!buffer || !s.buffer) + { + if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer; + if (buffer && len > 0) return *(unsigned char *)buffer; + return 0; + } + return strcmp(buffer, s.buffer); +} + +unsigned char String::equals(const String &s2) const +{ + return (len == s2.len && compareTo(s2) == 0); +} + +unsigned char String::equals(const char *cstr) const +{ + if (len == 0) return (cstr == NULL || *cstr == 0); + if (cstr == NULL) return buffer[0] == 0; + return strcmp(buffer, cstr) == 0; +} + +unsigned char String::operator<(const String &rhs) const +{ + return compareTo(rhs) < 0; +} + +unsigned char String::operator>(const String &rhs) const +{ + return compareTo(rhs) > 0; +} + +unsigned char String::operator<=(const String &rhs) const +{ + return compareTo(rhs) <= 0; +} + +unsigned char String::operator>=(const String &rhs) const +{ + return compareTo(rhs) >= 0; +} + +unsigned char String::equalsIgnoreCase( const String &s2 ) const +{ + if (this == &s2) return 1; + if (len != s2.len) return 0; + if (len == 0) return 1; + const char *p1 = buffer; + const char *p2 = s2.buffer; + while (*p1) + { + if (tolower(*p1++) != tolower(*p2++)) return 0; + } + return 1; +} + +unsigned char String::startsWith( const String &s2 ) const +{ + if (len < s2.len) return 0; + return startsWith(s2, 0); +} + +unsigned char String::startsWith( const String &s2, unsigned int offset ) const +{ + if (offset > len - s2.len || !buffer || !s2.buffer) return 0; + return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0; +} + +unsigned char String::endsWith( const String &s2 ) const +{ + if ( len < s2.len || !buffer || !s2.buffer) return 0; + return strcmp(&buffer[len - s2.len], s2.buffer) == 0; +} + +/*********************************************/ +/* Character Access */ +/*********************************************/ + +char String::charAt(unsigned int loc) const +{ + return operator[](loc); +} + +void String::setCharAt(unsigned int loc, char c) +{ + if (loc < len) buffer[loc] = c; +} + +char & String::operator[](unsigned int index) +{ + static char dummy_writable_char; + if (index >= len || !buffer) + { + dummy_writable_char = 0; + return dummy_writable_char; + } + return buffer[index]; +} + +char String::operator[]( unsigned int index ) const +{ + if (index >= len || !buffer) return 0; + return buffer[index]; +} + +void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const +{ + if (!bufsize || !buf) return; + if (index >= len) + { + buf[0] = 0; + return; + } + unsigned int n = bufsize - 1; + if (n > len - index) n = len - index; + strncpy((char *)buf, buffer + index, n); + buf[n] = 0; +} + +/*********************************************/ +/* Search */ +/*********************************************/ + +int String::indexOf(char c) const +{ + return indexOf(c, 0); +} + +int String::indexOf( char ch, unsigned int fromIndex ) const +{ + if (fromIndex >= len) return -1; + const char* temp = strchr(buffer + fromIndex, ch); + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::indexOf(const String &s2) const +{ + return indexOf(s2, 0); +} + +int String::indexOf(const String &s2, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + const char *found = strstr(buffer + fromIndex, s2.buffer); + if (found == NULL) return -1; + return found - buffer; +} + +int String::lastIndexOf( char theChar ) const +{ + return lastIndexOf(theChar, len - 1); +} + +int String::lastIndexOf(char ch, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + char tempchar = buffer[fromIndex + 1]; + buffer[fromIndex + 1] = '\0'; + char* temp = strrchr( buffer, ch ); + buffer[fromIndex + 1] = tempchar; + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::lastIndexOf(const String &s2) const +{ + return lastIndexOf(s2, len - s2.len); +} + +int String::lastIndexOf(const String &s2, unsigned int fromIndex) const +{ + if (s2.len == 0 || len == 0 || s2.len > len) return -1; + if (fromIndex >= len) fromIndex = len - 1; + int found = -1; + for (char *p = buffer; p <= buffer + fromIndex; p++) + { + p = strstr(p, s2.buffer); + if (!p) break; + if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; + } + return found; +} + +String String::substring(unsigned int left, unsigned int right) const +{ + if (left > right) + { + unsigned int temp = right; + right = left; + left = temp; + } + String out; + if (left >= len) return out; + if (right > len) right = len; + char temp = buffer[right]; // save the replaced character + buffer[right] = '\0'; + out = buffer + left; // pointer arithmetic + buffer[right] = temp; //restore character + return out; +} + +/*********************************************/ +/* Modification */ +/*********************************************/ + +void String::replace(char find, char replace) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) + { + if (*p == find) *p = replace; + } +} + +void String::replace(const String& find, const String& replace) +{ + if (len == 0 || find.len == 0) return; + int diff = replace.len - find.len; + char *readFrom = buffer; + char *foundAt; + if (diff == 0) + { + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) + { + memcpy(foundAt, replace.buffer, replace.len); + readFrom = foundAt + replace.len; + } + } + else if (diff < 0) + { + char *writeTo = buffer; + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) + { + unsigned int n = foundAt - readFrom; + memcpy(writeTo, readFrom, n); + writeTo += n; + memcpy(writeTo, replace.buffer, replace.len); + writeTo += replace.len; + readFrom = foundAt + find.len; + len += diff; + } + strcpy(writeTo, readFrom); + } + else + { + unsigned int size = len; // compute size needed for result + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) + { + readFrom = foundAt + find.len; + size += diff; + } + if (size == len) return; + if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! + int index = len - 1; + while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) + { + readFrom = buffer + index + find.len; + memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); + len += diff; + buffer[len] = 0; + memcpy(buffer + index, replace.buffer, replace.len); + index--; + } + } +} + +void String::remove(unsigned int index) +{ + // Pass the biggest integer as the count. The remove method + // below will take care of truncating it at the end of the + // string. + remove(index, (unsigned int) -1); +} + +void String::remove(unsigned int index, unsigned int count) +{ + if (index >= len) + { + return; + } + if (count == 0) + { + return; + } + if (count > len - index) + { + count = len - index; + } + char *writeTo = buffer + index; + len = len - count; + strncpy(writeTo, buffer + index + count, len - index); + buffer[len] = 0; +} + +void String::toLowerCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) + { + *p = tolower(*p); + } +} + +void String::toUpperCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) + { + *p = toupper(*p); + } +} + +void String::trim(void) +{ + if (!buffer || len == 0) return; + char *begin = buffer; + while (isspace(*begin)) begin++; + char *end = buffer + len - 1; + while (isspace(*end) && end >= begin) end--; + len = end + 1 - begin; + if (begin > buffer) memcpy(buffer, begin, len); + buffer[len] = 0; +} + +/*********************************************/ +/* Parsing / Conversion */ +/*********************************************/ + +long String::toInt(void) const +{ + if (buffer) return atol(buffer); + return 0; +} + +float String::toFloat(void) const +{ + return float(toDouble()); +} + +double String::toDouble(void) const +{ + if (buffer) return atof(buffer); + return 0; +} diff --git a/ArduinoCore-AT32F403A/cores/arduino/WString.h b/ArduinoCore-AT32F403A/cores/arduino/WString.h new file mode 100644 index 0000000..0d513f5 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/WString.h @@ -0,0 +1,311 @@ +/* + WString.h - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All right reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef String_class_h +#define String_class_h +#ifdef __cplusplus + +#include +#include +#include +#include + +// When compiling programs with this class, the following gcc parameters +// dramatically increase performance and memory (RAM) efficiency, typically +// with little or no increase in code size. +// -felide-constructors +// -std=c++0x + +class __FlashStringHelper; +#define F(string_literal) (reinterpret_cast(PSTR(string_literal))) + +// An inherited class for holding the result of a concatenation. These +// result objects are assumed to be writable by subsequent concatenations. +class StringSumHelper; + +// The string class +class String +{ + // use a function pointer to allow for "if (s)" without the + // complications of an operator bool(). for more information, see: + // http://www.artima.com/cppsource/safebool.html + typedef void (String::*StringIfHelperType)() const; + void StringIfHelper() const {} + +public: + // constructors + // creates a copy of the initial value. + // if the initial value is null or invalid, or if memory allocation + // fails, the string will be marked as invalid (i.e. "if (s)" will + // be false). + String(const char *cstr = ""); + String(const String &str); + String(const __FlashStringHelper *str); +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + String(String &&rval); + String(StringSumHelper &&rval); +#endif + explicit String(char c); + explicit String(unsigned char, unsigned char base = 10); + explicit String(int, unsigned char base = 10); + explicit String(unsigned int, unsigned char base = 10); + explicit String(long, unsigned char base = 10); + explicit String(unsigned long, unsigned char base = 10); + explicit String(float, unsigned char decimalPlaces = 2); + explicit String(double, unsigned char decimalPlaces = 2); + ~String(void); + + // memory management + // return true on success, false on failure (in which case, the string + // is left unchanged). reserve(0), if successful, will validate an + // invalid string (i.e., "if (s)" will be true afterwards) + unsigned char reserve(unsigned int size); + inline unsigned int length(void) const + { + return len; + } + + // creates a copy of the assigned value. if the value is null or + // invalid, or if the memory allocation fails, the string will be + // marked as invalid ("if (s)" will be false). + String & operator = (const String &rhs); + String & operator = (const char *cstr); + String & operator = (const __FlashStringHelper *str); +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + String & operator = (String &&rval); + String & operator = (StringSumHelper &&rval); +#endif + + // concatenate (works w/ built-in types) + + // returns true on success, false on failure (in which case, the string + // is left unchanged). if the argument is null or invalid, the + // concatenation is considered unsuccessful. + unsigned char concat(const String &str); + unsigned char concat(const char *cstr); + unsigned char concat(char c); + unsigned char concat(unsigned char c); + unsigned char concat(int num); + unsigned char concat(unsigned int num); + unsigned char concat(long num); + unsigned char concat(unsigned long num); + unsigned char concat(float num); + unsigned char concat(double num); + unsigned char concat(const __FlashStringHelper * str); + + // if there's not enough memory for the concatenated value, the string + // will be left unchanged (but this isn't signalled in any way) + String & operator += (const String &rhs) + { + concat(rhs); + return (*this); + } + String & operator += (const char *cstr) + { + concat(cstr); + return (*this); + } + String & operator += (char c) + { + concat(c); + return (*this); + } + String & operator += (unsigned char num) + { + concat(num); + return (*this); + } + String & operator += (int num) + { + concat(num); + return (*this); + } + String & operator += (unsigned int num) + { + concat(num); + return (*this); + } + String & operator += (long num) + { + concat(num); + return (*this); + } + String & operator += (unsigned long num) + { + concat(num); + return (*this); + } + String & operator += (float num) + { + concat(num); + return (*this); + } + String & operator += (double num) + { + concat(num); + return (*this); + } + String & operator += (const __FlashStringHelper *str) + { + concat(str); + return (*this); + } + + friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); + friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, float num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, double num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs); + + // comparison (only works w/ Strings and "strings") + operator StringIfHelperType() const + { + return buffer ? &String::StringIfHelper : 0; + } + int compareTo(const String &s) const; + unsigned char equals(const String &s) const; + unsigned char equals(const char *cstr) const; + unsigned char operator == (const String &rhs) const + { + return equals(rhs); + } + unsigned char operator == (const char *cstr) const + { + return equals(cstr); + } + unsigned char operator != (const String &rhs) const + { + return !equals(rhs); + } + unsigned char operator != (const char *cstr) const + { + return !equals(cstr); + } + unsigned char operator < (const String &rhs) const; + unsigned char operator > (const String &rhs) const; + unsigned char operator <= (const String &rhs) const; + unsigned char operator >= (const String &rhs) const; + unsigned char equalsIgnoreCase(const String &s) const; + unsigned char startsWith( const String &prefix) const; + unsigned char startsWith(const String &prefix, unsigned int offset) const; + unsigned char endsWith(const String &suffix) const; + + // character access + char charAt(unsigned int index) const; + void setCharAt(unsigned int index, char c); + char operator [] (unsigned int index) const; + char& operator [] (unsigned int index); + void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index = 0) const; + void toCharArray(char *buf, unsigned int bufsize, unsigned int index = 0) const + { + getBytes((unsigned char *)buf, bufsize, index); + } + const char* c_str() const + { + return buffer; + } + char* begin() + { + return buffer; + } + char* end() + { + return buffer + length(); + } + const char* begin() const + { + return c_str(); + } + const char* end() const + { + return c_str() + length(); + } + + // search + int indexOf( char ch ) const; + int indexOf( char ch, unsigned int fromIndex ) const; + int indexOf( const String &str ) const; + int indexOf( const String &str, unsigned int fromIndex ) const; + int lastIndexOf( char ch ) const; + int lastIndexOf( char ch, unsigned int fromIndex ) const; + int lastIndexOf( const String &str ) const; + int lastIndexOf( const String &str, unsigned int fromIndex ) const; + String substring( unsigned int beginIndex ) const + { + return substring(beginIndex, len); + }; + String substring( unsigned int beginIndex, unsigned int endIndex ) const; + + // modification + void replace(char find, char replace); + void replace(const String& find, const String& replace); + void remove(unsigned int index); + void remove(unsigned int index, unsigned int count); + void toLowerCase(void); + void toUpperCase(void); + void trim(void); + + // parsing/conversion + long toInt(void) const; + float toFloat(void) const; + double toDouble(void) const; + +protected: + char *buffer; // the actual char array + unsigned int capacity; // the array length minus one (for the '\0') + unsigned int len; // the String length (not counting the '\0') +protected: + void init(void); + void invalidate(void); + unsigned char changeBuffer(unsigned int maxStrLen); + unsigned char concat(const char *cstr, unsigned int length); + + // copy and move + String & copy(const char *cstr, unsigned int length); + String & copy(const __FlashStringHelper *pstr, unsigned int length); +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + void move(String &rhs); +#endif +}; + +class StringSumHelper : public String +{ +public: + StringSumHelper(const String &s) : String(s) {} + StringSumHelper(const char *p) : String(p) {} + StringSumHelper(char c) : String(c) {} + StringSumHelper(unsigned char num) : String(num) {} + StringSumHelper(int num) : String(num) {} + StringSumHelper(unsigned int num) : String(num) {} + StringSumHelper(long num) : String(num) {} + StringSumHelper(unsigned long num) : String(num) {} + StringSumHelper(float num) : String(num) {} + StringSumHelper(double num) : String(num) {} +}; + +#endif // __cplusplus +#endif // String_class_h diff --git a/ArduinoCore-AT32F403A/cores/arduino/Wire.cpp b/ArduinoCore-AT32F403A/cores/arduino/Wire.cpp new file mode 100644 index 0000000..a66178d --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/Wire.cpp @@ -0,0 +1,242 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file Wire.cpp + * @author Trystan Jones + * @brief Wire library, uses the WireBase to create the primary interface + * while keeping low level interactions invisible to the user. + */ + +/* + * Library updated by crenn to follow new Wire system. + * Code was derived from the original Wire for maple code by leaflabs and the + * modifications by gke and ala42. + */ +/* + * Updated by Roger Clark. 20141111. Fixed issue when process() returned because of missing ACK (often caused by invalid device address being used), caused SCL to be left + * LOW so that in the next call to process() , the first clock pulse was not sent, because SCL was LOW when it should have been high. + */ + +#include "Wire.h" + +#if WIRE_USE_FULL_SPEED_I2C +# define I2C_DELAY(x) +# define SET_SDA(state) digitalWrite_##state(this->sda_pin) +# define SET_SCL(state) digitalWrite_##state(this->scl_pin) +#else +# define I2C_DELAY(x) delayMicroseconds(x) +# define SET_SDA(state) set_sda(state) +# define SET_SCL(state) set_scl(state) +#endif + +#define I2C_WRITE 0 +#define I2C_READ 1 + +// TODO: Add in Error Handling if pins is out of range for other Maples +// TODO: Make delays more capable +TwoWire::TwoWire(uint8_t scl, uint8_t sda, uint8_t delay) : i2c_delay(delay) +{ + this->scl_pin = scl; + this->sda_pin = sda; +} + +TwoWire::~TwoWire() +{ +} + +bool TwoWire::begin(uint8_t self_addr) +{ + WireBase::begin(self_addr); + pinMode(this->scl_pin, OUTPUT_OPEN_DRAIN); + pinMode(this->sda_pin, OUTPUT_OPEN_DRAIN); + + bool success = set_scl(HIGH, WIRE_BEGIN_TIMEOUT); + set_sda(HIGH); + + return success; +} + +/* low level conventions: + * - SDA/SCL idle high (expected high) + * - always start with i2c_delay rather than end + */ + +void TwoWire::set_scl(bool state) +{ + I2C_DELAY(this->i2c_delay); + digitalWrite(this->scl_pin, state); + //Allow for clock stretching - dangerous currently + if (state == HIGH) + { + while(digitalRead(this->scl_pin) == 0); + } +} + +bool TwoWire::set_scl(bool state, uint32_t timeout) +{ + I2C_DELAY(this->i2c_delay); + digitalWrite(this->scl_pin, state); + + uint32_t start = millis(); + + if (state == HIGH) + { + while(digitalRead(this->scl_pin) == LOW) + { + if(millis() - start >= timeout) + { + return false; + } + } + } + return true; +} + +void TwoWire::set_sda(bool state) +{ + I2C_DELAY(this->i2c_delay); + digitalWrite(this->sda_pin, state); +} + +void TwoWire::i2c_start() +{ + SET_SDA(LOW); + SET_SCL(LOW); +} + +void TwoWire::i2c_stop() +{ + SET_SDA(LOW); + SET_SCL(HIGH); + SET_SDA(HIGH); +} + +bool TwoWire::i2c_get_ack() +{ + SET_SCL(LOW); + SET_SDA(HIGH); + SET_SCL(HIGH); + bool ret = !digitalRead(this->sda_pin); + SET_SCL(LOW); + return ret; +} + +void TwoWire::i2c_send_ack() +{ + SET_SDA(LOW); + SET_SCL(HIGH); + SET_SCL(LOW); +} + +void TwoWire::i2c_send_nack() +{ + SET_SDA(HIGH); + SET_SCL(HIGH); + SET_SCL(LOW); +} + +uint8_t TwoWire::i2c_shift_in() +{ + uint8_t data = 0; + + SET_SDA(HIGH); + + int i; + for (i = 0; i < 8; i++) + { + SET_SCL(HIGH); + data |= digitalRead(this->sda_pin) << (7 - i); + SET_SCL(LOW); + } + + return data; +} + +void TwoWire::i2c_shift_out(uint8_t val) +{ + int i; + for (i = 0; i < 8; i++) + { + set_sda(!!(val & (1 << (7 - i)) ) ); + SET_SCL(HIGH); + SET_SCL(LOW); + } +} + +uint8_t TwoWire::process(void) +{ + itc_msg.xferred = 0; + + uint8_t sla_addr = (itc_msg.addr << 1); + if (itc_msg.flags == I2C_MSG_READ) + { + sla_addr |= I2C_READ; + } + i2c_start(); + // shift out the address we're transmitting to + i2c_shift_out(sla_addr); + if (!i2c_get_ack()) + { + i2c_stop();// Roger Clark. 20141110 added to set clock high again, as it will be left in a low state otherwise + return ENACKADDR; + } + // Recieving + if (itc_msg.flags == I2C_MSG_READ) + { + while (itc_msg.xferred < itc_msg.length) + { + itc_msg.data[itc_msg.xferred++] = i2c_shift_in(); + if (itc_msg.xferred < itc_msg.length) + { + i2c_send_ack(); + } + else + { + i2c_send_nack(); + } + } + } + // Sending + else + { + for (uint8_t i = 0; i < itc_msg.length; i++) + { + i2c_shift_out(itc_msg.data[i]); + if (!i2c_get_ack()) + { + i2c_stop();// Roger Clark. 20141110 added to set clock high again, as it will be left in a low state otherwise + return ENACKTRNS; + } + itc_msg.xferred++; + } + } + i2c_stop(); + return SUCCESS; +} + +// Declare the instance that the users of the library can use +TwoWire Wire(WIRE_SCL_PIN, WIRE_SDA_PIN, WIRE_DELAY); diff --git a/ArduinoCore-AT32F403A/cores/arduino/Wire.h b/ArduinoCore-AT32F403A/cores/arduino/Wire.h new file mode 100644 index 0000000..39a1766 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/Wire.h @@ -0,0 +1,131 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file Wire.h + * @author Trystan Jones + * @brief Wire library, uses the WireBase to create the primary interface + * while keeping low level interactions invisible to the user. + */ + +/* + * Library updated by crenn to follow new Wire system. + * Code was derived from the original Wire for maple code by leaflabs and the + * modifications by gke and ala42. + */ + +#ifndef _WIRE_H_ +#define _WIRE_H_ + +#include "WireBase.h" + +/* + * On the Maple, let the default pins be in the same location as the Arduino + * pins + */ + +class TwoWire : public WireBase +{ +public: + /* + * Accept pin numbers for SCL and SDA lines. Set the delay needed + * to create the timing for I2C's Standard Mode and Fast Mode. + */ + TwoWire(uint8_t scl, uint8_t sda, uint8_t delay); + + /* + * If object is destroyed, set pin numbers to 0. + */ + virtual ~TwoWire(); + + /* + * Sets pins SDA and SCL to OUPTUT_OPEN_DRAIN, joining I2C bus as + * master. This function overwrites the default behaviour of + * .begin(uint8_t) in WireBase + */ + bool begin(uint8_t self_addr = 0x00); +public: + uint8_t i2c_delay; + uint8_t scl_pin; + uint8_t sda_pin; + + /* + * Sets the SCL line to HIGH/LOW and allow for clock stretching by slave + * devices + */ + void set_scl(bool state); + bool set_scl(bool state, uint32_t timeout); + + /* + * Sets the SDA line to HIGH/LOW + */ + void set_sda(bool state); + + /* + * Creates a Start condition on the bus + */ + void i2c_start(); + + /* + * Creates a Stop condition on the bus + */ + void i2c_stop(); + + /* + * Gets an ACK condition from a slave device on the bus + */ + bool i2c_get_ack(); + + /* + * Creates a ACK condition on the bus + */ + void i2c_send_ack(); + + /* + * Creates a NACK condition on the bus + */ + void i2c_send_nack(); + + /* + * Shifts in the data through SDA and clocks SCL for the slave device + */ + uint8_t i2c_shift_in(); + + /* + * Shifts out the data through SDA and clocks SCL for the slave device + */ + void i2c_shift_out(uint8_t val); +protected: + /* + * Processes the incoming I2C message defined by WireBase + */ + + virtual uint8_t process(); +}; + +extern TwoWire Wire; + +#endif // _WIRE_H_ diff --git a/ArduinoCore-AT32F403A/cores/arduino/WireBase.cpp b/ArduinoCore-AT32F403A/cores/arduino/WireBase.cpp new file mode 100644 index 0000000..44a1b58 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/WireBase.cpp @@ -0,0 +1,166 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file WireBase.cpp + * @author Trystan Jones + * @brief Wire library, following the majority of the interface from Arduino. + * Provides a 'standard' interface to I2C (two-wire) communication for + * derived classes. + */ + +/* + * Library created by crenn to allow a system which would provide users the + * 'standardised' Arduino method for interfacing with I2C devices regardless of + * whether it is I2C hardware or emulating software. + */ + +#include "WireBase.h" + +void WireBase::begin(uint8_t self_addr) +{ + tx_buf_idx = 0; + tx_buf_overflow = false; + rx_buf_idx = 0; + rx_buf_len = 0; +} + +void WireBase::setClock(uint32_t clock) +{ + +} + +void WireBase::beginTransmission(uint8_t slave_address) +{ + itc_msg.addr = slave_address; + itc_msg.data = &tx_buf[tx_buf_idx]; + itc_msg.length = 0; + itc_msg.flags = 0; +} + +void WireBase::beginTransmission(int slave_address) +{ + beginTransmission((uint8_t)slave_address); +} + +uint8_t WireBase::endTransmission(void) +{ + uint8_t retVal; + if (tx_buf_overflow) + { + return EDATA; + } + retVal = process();// Changed so that the return value from process is returned by this function see also the return line below + tx_buf_idx = 0; + tx_buf_overflow = false; + return retVal;//SUCCESS; +} + +//TODO: Add the ability to queue messages (adding a boolean to end of function +// call, allows for the Arduino style to stay while also giving the flexibility +// to bulk send +uint8_t WireBase::requestFrom(uint8_t address, int num_bytes) +{ + if (num_bytes > WIRE_BUFF_SIZE) + { + num_bytes = WIRE_BUFF_SIZE; + } + itc_msg.addr = address; + itc_msg.flags = I2C_MSG_READ; + itc_msg.length = num_bytes; + itc_msg.data = &rx_buf[rx_buf_idx]; + process(); + rx_buf_len += itc_msg.xferred; + itc_msg.flags = 0; + return rx_buf_len; +} + +uint8_t WireBase::requestFrom(int address, int numBytes) +{ + return WireBase::requestFrom((uint8_t)address, numBytes); +} + +void WireBase::write(uint8_t value) +{ + if (tx_buf_idx == WIRE_BUFF_SIZE) + { + tx_buf_overflow = true; + return; + } + tx_buf[tx_buf_idx++] = value; + itc_msg.length++; +} + +void WireBase::write(uint8_t* buf, int len) +{ + for (int i = 0; i < len; i++) + { + write(buf[i]); + } +} + +void WireBase::write(int value) +{ + write((uint8_t)value); +} + +void WireBase::write(int* buf, int len) +{ + write((uint8_t*)buf, (uint8_t)len); +} + +void WireBase::write(char* buf) +{ + uint8_t *ptr = (uint8_t*)buf; + while (*ptr) + { + write(*ptr); + ptr++; + } +} + +uint8_t WireBase::available() +{ + return rx_buf_len - rx_buf_idx; +} + +uint8_t WireBase::read() +{ + if (rx_buf_idx == rx_buf_len) + { + rx_buf_idx = 0; + rx_buf_len = 0; + return 0; + } + else if (rx_buf_idx == (rx_buf_len - 1)) + { + uint8_t temp = rx_buf[rx_buf_idx]; + rx_buf_idx = 0; + rx_buf_len = 0; + return temp; + } + return rx_buf[rx_buf_idx++]; +} diff --git a/ArduinoCore-AT32F403A/cores/arduino/WireBase.h b/ArduinoCore-AT32F403A/cores/arduino/WireBase.h new file mode 100644 index 0000000..faa3570 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/WireBase.h @@ -0,0 +1,172 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file WireBase.h + * @author Trystan Jones + * @brief Wire library, following the majority of the interface from Arduino. + * Provides a 'standard' interface to I2C (two-wire) communication for + * derived classes. + */ + +/* + * Library created by crenn to allow a system which would provide users the + * 'standardised' Arduino method for interfacing with I2C devices regardless of + * whether it is I2C hardware or emulating software. + */ + +#ifndef _WIREBASE_H_ +#define _WIREBASE_H_ + + +#include "Arduino.h" + +#ifndef WIRE_BUFF_SIZE +# define WIRE_BUFF_SIZE 32 +#endif + +/* return codes from endTransmission() */ +#define SUCCESS 0 /* transmission was successful */ +#define EDATA 1 /* too much data */ +#define ENACKADDR 2 /* received nack on transmit of address */ +#define ENACKTRNS 3 /* received nack on transmit of data */ +#define EOTHER 4 /* other error */ + +struct i2c_msg; + +typedef struct i2c_msg +{ + uint16_t addr; /**< Address */ + +#define I2C_MSG_READ 0x1 +#define I2C_MSG_10BIT_ADDR 0x2 + /** + * Bitwise OR of: + * - I2C_MSG_READ (write is default) + * - I2C_MSG_10BIT_ADDR (7-bit is default) */ + uint16_t flags; + + uint16_t length; /**< Message length */ + uint16_t xferred; /**< Messages transferred */ + uint8_t *data; /**< Data */ +} i2c_msg; + +class WireBase // Abstraction is awesome! +{ +protected: + i2c_msg itc_msg; + uint8_t rx_buf[WIRE_BUFF_SIZE]; /* receive buffer */ + uint8_t rx_buf_idx; /* first unread idx in rx_buf */ + uint8_t rx_buf_len; /* number of bytes read */ + + uint8_t tx_buf[WIRE_BUFF_SIZE]; /* transmit buffer */ + uint8_t tx_buf_idx; // next idx available in tx_buf, -1 overflow + boolean tx_buf_overflow; + + // Force derived classes to define process function + virtual uint8_t process() = 0; +public: + WireBase() {} + virtual ~WireBase() {} + + /* + * Initialises the class interface + */ + // Allow derived classes to overwrite begin function + void begin(uint8_t = 0x00); + + void setClock(uint32_t); + + /* + * Sets up the transmission message to be processed + */ + void beginTransmission(uint8_t); + + /* + * Allow only 8 bit addresses to be used + */ + void beginTransmission(int); + + /* + * Call the process function to process the message if the TX + * buffer has not overflowed. + */ + uint8_t endTransmission(void); + + inline uint8_t endTransmission(uint8_t) + { + return endTransmission(); + } + + /* + * Request bytes from a slave device and process the request, + * storing into the receiving buffer. + */ + uint8_t requestFrom(uint8_t, int); + + /* + * Allow only 8 bit addresses to be used when requesting bytes + */ + uint8_t requestFrom(int, int); + + /* + * Stack up bytes to be sent when transmitting + */ + void write(uint8_t); + + /* + * Stack up bytes from the array to be sent when transmitting + */ + void write(uint8_t*, int); + + /* + * Ensure that a sending data will only be 8-bit bytes + */ + void write(int); + + /* + * Ensure that an array sending data will only be 8-bit bytes + */ + void write(int*, int); + + /* + * Stack up bytes from a string to be sent when transmitting + */ + void write(char*); + + /* + * Return the amount of bytes that is currently in the receiving buffer + */ + uint8_t available(); + + /* + * Return the value of byte in the receiving buffer that is currently being + * pointed to + */ + uint8_t read(); +}; + +#endif // _WIREBASE_H_ diff --git a/ArduinoCore-AT32F403A/cores/arduino/avr/interrupt.h b/ArduinoCore-AT32F403A/cores/arduino/avr/interrupt.h new file mode 100644 index 0000000..e69de29 diff --git a/ArduinoCore-AT32F403A/cores/arduino/avr/pgmspace.h b/ArduinoCore-AT32F403A/cores/arduino/avr/pgmspace.h new file mode 100644 index 0000000..9b344c9 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/avr/pgmspace.h @@ -0,0 +1,44 @@ +#ifndef __PGMSPACE_H_ +#define __PGMSPACE_H_ 1 + +#include + +#define PROGMEM +#define PGM_P const char * +#define PSTR(str) (str) + +#define _SFR_BYTE(n) (n) + +typedef void prog_void; +typedef char prog_char; +typedef unsigned char prog_uchar; +typedef int8_t prog_int8_t; +typedef uint8_t prog_uint8_t; +typedef int16_t prog_int16_t; +typedef uint16_t prog_uint16_t; +typedef int32_t prog_int32_t; +typedef uint32_t prog_uint32_t; + +#define memcpy_P(dest, src, num) memcpy((dest), (src), (num)) +#define strcpy_P(dest, src) strcpy((dest), (src)) +#define strcat_P(dest, src) strcat((dest), (src)) +#define strcmp_P(a, b) strcmp((a), (b)) +#define strstr_P(a, b) strstr((a), (b)) +#define strlen_P(a) strlen((a)) +#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) + +#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) +#define pgm_read_word(addr) (*(const unsigned short *)(addr)) +#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) +#define pgm_read_float(addr) (*(const float *)(addr)) + +#define pgm_read_byte_near(addr) pgm_read_byte(addr) +#define pgm_read_word_near(addr) pgm_read_word(addr) +#define pgm_read_dword_near(addr) pgm_read_dword(addr) +#define pgm_read_float_near(addr) pgm_read_float(addr) +#define pgm_read_byte_far(addr) pgm_read_byte(addr) +#define pgm_read_word_far(addr) pgm_read_word(addr) +#define pgm_read_dword_far(addr) pgm_read_dword(addr) +#define pgm_read_float_far(addr) pgm_read_float(addr) + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/binary.h b/ArduinoCore-AT32F403A/cores/arduino/binary.h new file mode 100644 index 0000000..aec4c73 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/binary.h @@ -0,0 +1,534 @@ +/* + binary.h - Definitions for binary constants + Copyright (c) 2006 David A. Mellis. All right reserved. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Binary_h +#define Binary_h + +#define B0 0 +#define B00 0 +#define B000 0 +#define B0000 0 +#define B00000 0 +#define B000000 0 +#define B0000000 0 +#define B00000000 0 +#define B1 1 +#define B01 1 +#define B001 1 +#define B0001 1 +#define B00001 1 +#define B000001 1 +#define B0000001 1 +#define B00000001 1 +#define B10 2 +#define B010 2 +#define B0010 2 +#define B00010 2 +#define B000010 2 +#define B0000010 2 +#define B00000010 2 +#define B11 3 +#define B011 3 +#define B0011 3 +#define B00011 3 +#define B000011 3 +#define B0000011 3 +#define B00000011 3 +#define B100 4 +#define B0100 4 +#define B00100 4 +#define B000100 4 +#define B0000100 4 +#define B00000100 4 +#define B101 5 +#define B0101 5 +#define B00101 5 +#define B000101 5 +#define B0000101 5 +#define B00000101 5 +#define B110 6 +#define B0110 6 +#define B00110 6 +#define B000110 6 +#define B0000110 6 +#define B00000110 6 +#define B111 7 +#define B0111 7 +#define B00111 7 +#define B000111 7 +#define B0000111 7 +#define B00000111 7 +#define B1000 8 +#define B01000 8 +#define B001000 8 +#define B0001000 8 +#define B00001000 8 +#define B1001 9 +#define B01001 9 +#define B001001 9 +#define B0001001 9 +#define B00001001 9 +#define B1010 10 +#define B01010 10 +#define B001010 10 +#define B0001010 10 +#define B00001010 10 +#define B1011 11 +#define B01011 11 +#define B001011 11 +#define B0001011 11 +#define B00001011 11 +#define B1100 12 +#define B01100 12 +#define B001100 12 +#define B0001100 12 +#define B00001100 12 +#define B1101 13 +#define B01101 13 +#define B001101 13 +#define B0001101 13 +#define B00001101 13 +#define B1110 14 +#define B01110 14 +#define B001110 14 +#define B0001110 14 +#define B00001110 14 +#define B1111 15 +#define B01111 15 +#define B001111 15 +#define B0001111 15 +#define B00001111 15 +#define B10000 16 +#define B010000 16 +#define B0010000 16 +#define B00010000 16 +#define B10001 17 +#define B010001 17 +#define B0010001 17 +#define B00010001 17 +#define B10010 18 +#define B010010 18 +#define B0010010 18 +#define B00010010 18 +#define B10011 19 +#define B010011 19 +#define B0010011 19 +#define B00010011 19 +#define B10100 20 +#define B010100 20 +#define B0010100 20 +#define B00010100 20 +#define B10101 21 +#define B010101 21 +#define B0010101 21 +#define B00010101 21 +#define B10110 22 +#define B010110 22 +#define B0010110 22 +#define B00010110 22 +#define B10111 23 +#define B010111 23 +#define B0010111 23 +#define B00010111 23 +#define B11000 24 +#define B011000 24 +#define B0011000 24 +#define B00011000 24 +#define B11001 25 +#define B011001 25 +#define B0011001 25 +#define B00011001 25 +#define B11010 26 +#define B011010 26 +#define B0011010 26 +#define B00011010 26 +#define B11011 27 +#define B011011 27 +#define B0011011 27 +#define B00011011 27 +#define B11100 28 +#define B011100 28 +#define B0011100 28 +#define B00011100 28 +#define B11101 29 +#define B011101 29 +#define B0011101 29 +#define B00011101 29 +#define B11110 30 +#define B011110 30 +#define B0011110 30 +#define B00011110 30 +#define B11111 31 +#define B011111 31 +#define B0011111 31 +#define B00011111 31 +#define B100000 32 +#define B0100000 32 +#define B00100000 32 +#define B100001 33 +#define B0100001 33 +#define B00100001 33 +#define B100010 34 +#define B0100010 34 +#define B00100010 34 +#define B100011 35 +#define B0100011 35 +#define B00100011 35 +#define B100100 36 +#define B0100100 36 +#define B00100100 36 +#define B100101 37 +#define B0100101 37 +#define B00100101 37 +#define B100110 38 +#define B0100110 38 +#define B00100110 38 +#define B100111 39 +#define B0100111 39 +#define B00100111 39 +#define B101000 40 +#define B0101000 40 +#define B00101000 40 +#define B101001 41 +#define B0101001 41 +#define B00101001 41 +#define B101010 42 +#define B0101010 42 +#define B00101010 42 +#define B101011 43 +#define B0101011 43 +#define B00101011 43 +#define B101100 44 +#define B0101100 44 +#define B00101100 44 +#define B101101 45 +#define B0101101 45 +#define B00101101 45 +#define B101110 46 +#define B0101110 46 +#define B00101110 46 +#define B101111 47 +#define B0101111 47 +#define B00101111 47 +#define B110000 48 +#define B0110000 48 +#define B00110000 48 +#define B110001 49 +#define B0110001 49 +#define B00110001 49 +#define B110010 50 +#define B0110010 50 +#define B00110010 50 +#define B110011 51 +#define B0110011 51 +#define B00110011 51 +#define B110100 52 +#define B0110100 52 +#define B00110100 52 +#define B110101 53 +#define B0110101 53 +#define B00110101 53 +#define B110110 54 +#define B0110110 54 +#define B00110110 54 +#define B110111 55 +#define B0110111 55 +#define B00110111 55 +#define B111000 56 +#define B0111000 56 +#define B00111000 56 +#define B111001 57 +#define B0111001 57 +#define B00111001 57 +#define B111010 58 +#define B0111010 58 +#define B00111010 58 +#define B111011 59 +#define B0111011 59 +#define B00111011 59 +#define B111100 60 +#define B0111100 60 +#define B00111100 60 +#define B111101 61 +#define B0111101 61 +#define B00111101 61 +#define B111110 62 +#define B0111110 62 +#define B00111110 62 +#define B111111 63 +#define B0111111 63 +#define B00111111 63 +#define B1000000 64 +#define B01000000 64 +#define B1000001 65 +#define B01000001 65 +#define B1000010 66 +#define B01000010 66 +#define B1000011 67 +#define B01000011 67 +#define B1000100 68 +#define B01000100 68 +#define B1000101 69 +#define B01000101 69 +#define B1000110 70 +#define B01000110 70 +#define B1000111 71 +#define B01000111 71 +#define B1001000 72 +#define B01001000 72 +#define B1001001 73 +#define B01001001 73 +#define B1001010 74 +#define B01001010 74 +#define B1001011 75 +#define B01001011 75 +#define B1001100 76 +#define B01001100 76 +#define B1001101 77 +#define B01001101 77 +#define B1001110 78 +#define B01001110 78 +#define B1001111 79 +#define B01001111 79 +#define B1010000 80 +#define B01010000 80 +#define B1010001 81 +#define B01010001 81 +#define B1010010 82 +#define B01010010 82 +#define B1010011 83 +#define B01010011 83 +#define B1010100 84 +#define B01010100 84 +#define B1010101 85 +#define B01010101 85 +#define B1010110 86 +#define B01010110 86 +#define B1010111 87 +#define B01010111 87 +#define B1011000 88 +#define B01011000 88 +#define B1011001 89 +#define B01011001 89 +#define B1011010 90 +#define B01011010 90 +#define B1011011 91 +#define B01011011 91 +#define B1011100 92 +#define B01011100 92 +#define B1011101 93 +#define B01011101 93 +#define B1011110 94 +#define B01011110 94 +#define B1011111 95 +#define B01011111 95 +#define B1100000 96 +#define B01100000 96 +#define B1100001 97 +#define B01100001 97 +#define B1100010 98 +#define B01100010 98 +#define B1100011 99 +#define B01100011 99 +#define B1100100 100 +#define B01100100 100 +#define B1100101 101 +#define B01100101 101 +#define B1100110 102 +#define B01100110 102 +#define B1100111 103 +#define B01100111 103 +#define B1101000 104 +#define B01101000 104 +#define B1101001 105 +#define B01101001 105 +#define B1101010 106 +#define B01101010 106 +#define B1101011 107 +#define B01101011 107 +#define B1101100 108 +#define B01101100 108 +#define B1101101 109 +#define B01101101 109 +#define B1101110 110 +#define B01101110 110 +#define B1101111 111 +#define B01101111 111 +#define B1110000 112 +#define B01110000 112 +#define B1110001 113 +#define B01110001 113 +#define B1110010 114 +#define B01110010 114 +#define B1110011 115 +#define B01110011 115 +#define B1110100 116 +#define B01110100 116 +#define B1110101 117 +#define B01110101 117 +#define B1110110 118 +#define B01110110 118 +#define B1110111 119 +#define B01110111 119 +#define B1111000 120 +#define B01111000 120 +#define B1111001 121 +#define B01111001 121 +#define B1111010 122 +#define B01111010 122 +#define B1111011 123 +#define B01111011 123 +#define B1111100 124 +#define B01111100 124 +#define B1111101 125 +#define B01111101 125 +#define B1111110 126 +#define B01111110 126 +#define B1111111 127 +#define B01111111 127 +#define B10000000 128 +#define B10000001 129 +#define B10000010 130 +#define B10000011 131 +#define B10000100 132 +#define B10000101 133 +#define B10000110 134 +#define B10000111 135 +#define B10001000 136 +#define B10001001 137 +#define B10001010 138 +#define B10001011 139 +#define B10001100 140 +#define B10001101 141 +#define B10001110 142 +#define B10001111 143 +#define B10010000 144 +#define B10010001 145 +#define B10010010 146 +#define B10010011 147 +#define B10010100 148 +#define B10010101 149 +#define B10010110 150 +#define B10010111 151 +#define B10011000 152 +#define B10011001 153 +#define B10011010 154 +#define B10011011 155 +#define B10011100 156 +#define B10011101 157 +#define B10011110 158 +#define B10011111 159 +#define B10100000 160 +#define B10100001 161 +#define B10100010 162 +#define B10100011 163 +#define B10100100 164 +#define B10100101 165 +#define B10100110 166 +#define B10100111 167 +#define B10101000 168 +#define B10101001 169 +#define B10101010 170 +#define B10101011 171 +#define B10101100 172 +#define B10101101 173 +#define B10101110 174 +#define B10101111 175 +#define B10110000 176 +#define B10110001 177 +#define B10110010 178 +#define B10110011 179 +#define B10110100 180 +#define B10110101 181 +#define B10110110 182 +#define B10110111 183 +#define B10111000 184 +#define B10111001 185 +#define B10111010 186 +#define B10111011 187 +#define B10111100 188 +#define B10111101 189 +#define B10111110 190 +#define B10111111 191 +#define B11000000 192 +#define B11000001 193 +#define B11000010 194 +#define B11000011 195 +#define B11000100 196 +#define B11000101 197 +#define B11000110 198 +#define B11000111 199 +#define B11001000 200 +#define B11001001 201 +#define B11001010 202 +#define B11001011 203 +#define B11001100 204 +#define B11001101 205 +#define B11001110 206 +#define B11001111 207 +#define B11010000 208 +#define B11010001 209 +#define B11010010 210 +#define B11010011 211 +#define B11010100 212 +#define B11010101 213 +#define B11010110 214 +#define B11010111 215 +#define B11011000 216 +#define B11011001 217 +#define B11011010 218 +#define B11011011 219 +#define B11011100 220 +#define B11011101 221 +#define B11011110 222 +#define B11011111 223 +#define B11100000 224 +#define B11100001 225 +#define B11100010 226 +#define B11100011 227 +#define B11100100 228 +#define B11100101 229 +#define B11100110 230 +#define B11100111 231 +#define B11101000 232 +#define B11101001 233 +#define B11101010 234 +#define B11101011 235 +#define B11101100 236 +#define B11101101 237 +#define B11101110 238 +#define B11101111 239 +#define B11110000 240 +#define B11110001 241 +#define B11110010 242 +#define B11110011 243 +#define B11110100 244 +#define B11110101 245 +#define B11110110 246 +#define B11110111 247 +#define B11111000 248 +#define B11111001 249 +#define B11111010 250 +#define B11111011 251 +#define B11111100 252 +#define B11111101 253 +#define B11111110 254 +#define B11111111 255 + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/dtostrf.c b/ArduinoCore-AT32F403A/cores/arduino/dtostrf.c new file mode 100644 index 0000000..6504ba6 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/dtostrf.c @@ -0,0 +1,37 @@ +/* + dtostrf - Emulation for dtostrf function from avr-libc + Copyright (c) 2013 Arduino. All rights reserved. + Written by Cristian Maglie + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "dtostrf.h" + +char *dtostrf(double val, signed char width, unsigned char prec, char *sout) +{ + char fmt[20]; + snprintf(fmt, sizeof(fmt), "%%%d.%df", width, prec); + sprintf(sout, fmt, val); + return sout; +} + +char *dtostrnf(double val, signed char width, unsigned char prec, char *sout, size_t sout_size) +{ + char fmt[20]; + snprintf(fmt, sizeof(fmt), "%%%d.%df", width, prec); + snprintf(sout, sout_size, fmt, val); + return sout; +} diff --git a/ArduinoCore-AT32F403A/cores/arduino/dtostrf.h b/ArduinoCore-AT32F403A/cores/arduino/dtostrf.h new file mode 100644 index 0000000..2e337f0 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/dtostrf.h @@ -0,0 +1,37 @@ +/* + dtostrf - Emulation for dtostrf function from avr-libc + Copyright (c) 2013 Arduino. All rights reserved. + Written by Cristian Maglie + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef __DTOSTRF_H +#define __DTOSTRF_H + +#include "stdio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +char *dtostrf(double val, signed char width, unsigned char prec, char *sout); +char *dtostrnf(double val, signed char width, unsigned char prec, char *sout, size_t sout_size); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/itoa.c b/ArduinoCore-AT32F403A/cores/arduino/itoa.c new file mode 100644 index 0000000..0d06d4f --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/itoa.c @@ -0,0 +1,164 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "itoa.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#if 0 +/* reverse: reverse string s in place */ +static void reverse(char s[]) +{ + int i, j ; + char c ; + + for (i = 0, j = strlen(s) - 1 ; i < j ; i++, j--) { + c = s[i] ; + s[i] = s[j] ; + s[j] = c ; + } +} + +/* itoa: convert n to characters in s */ +extern void itoa(int n, char s[]) +{ + int i, sign ; + + if ((sign = n) < 0) { /* record sign */ + n = -n; /* make n positive */ + } + + i = 0; + do { + /* generate digits in reverse order */ + s[i++] = n % 10 + '0'; /* get next digit */ + } while ((n /= 10) > 0) ; /* delete it */ + + if (sign < 0) { + s[i++] = '-'; + } + + s[i] = '\0'; + + reverse(s) ; +} + +#else + +extern char *itoa(int value, char *string, int radix) +{ + return ltoa(value, string, radix) ; +} + +extern char *ltoa(long value, char *string, int radix) +{ + char tmp[33]; + char *tp = tmp; + long i; + unsigned long v; + int sign; + char *sp; + + if (string == NULL) { + return 0 ; + } + + if (radix > 36 || radix <= 1) { + return 0 ; + } + + sign = (radix == 10 && value < 0); + if (sign) { + v = -value; + } else { + v = (unsigned long)value; + } + + while (v || tp == tmp) { + i = v % radix; + v = v / radix; + if (i < 10) { + *tp++ = i + '0'; + } else { + *tp++ = i + 'a' - 10; + } + } + + sp = string; + + if (sign) { + *sp++ = '-'; + } + while (tp > tmp) { + *sp++ = *--tp; + } + *sp = 0; + + return string; +} +#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 9 || \ + (__GNUC_MINOR__ == 9 && __GNUC_PATCHLEVEL__ > 2))) +extern char *utoa(unsigned value, char *string, int radix) +#else +extern char *utoa(unsigned long value, char *string, int radix) +#endif +{ + return ultoa(value, string, radix) ; +} + +extern char *ultoa(unsigned long value, char *string, int radix) +{ + char tmp[33]; + char *tp = tmp; + long i; + unsigned long v = value; + char *sp; + + if (string == NULL) { + return 0; + } + + if (radix > 36 || radix <= 1) { + return 0; + } + + while (v || tp == tmp) { + i = v % radix; + v = v / radix; + if (i < 10) { + *tp++ = i + '0'; + } else { + *tp++ = i + 'a' - 10; + } + } + + sp = string; + + + while (tp > tmp) { + *sp++ = *--tp; + } + *sp = 0; + + return string; +} +#endif /* 0 */ + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus \ No newline at end of file diff --git a/ArduinoCore-AT32F403A/cores/arduino/itoa.h b/ArduinoCore-AT32F403A/cores/arduino/itoa.h new file mode 100644 index 0000000..77a0a88 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/itoa.h @@ -0,0 +1,44 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _ITOA_ +#define _ITOA_ + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#if 0 + +extern void itoa(int n, char s[]) ; + +#else + +extern char *itoa(int value, char *string, int radix) ; +extern char *ltoa(long value, char *string, int radix) ; +#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 9 || \ + (__GNUC_MINOR__ == 9 && __GNUC_PATCHLEVEL__ > 2))) +extern char *utoa(unsigned value, char *string, int radix) ; +#else +extern char *utoa(unsigned long value, char *string, int radix) ; +#endif +extern char *ultoa(unsigned long value, char *string, int radix) ; +#endif /* 0 */ + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif // _ITOA_ \ No newline at end of file diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/Arduino.c b/ArduinoCore-AT32F403A/cores/arduino/libcore/Arduino.c new file mode 100644 index 0000000..be86b0f --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/Arduino.c @@ -0,0 +1,294 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Arduino.h" + +/** + * @brief 配置引脚输入输出模式 + * @param pin: 引脚编号 + * @param PinMode_x: 模式 + * @retval 无 + */ +void pinMode(uint8_t pin, PinMode_TypeDef mode) +{ + if(!IS_PIN(pin)) + { + return; + } + + if(mode == INPUT_ANALOG_DMA) + { + if(!IS_ADC_PIN(pin)) + { + return; + } + + pinMode(pin, INPUT_ANALOG); + ADC_DMA_Register(PIN_MAP[pin].ADC_Channel); + } + else if(mode == PWM) + { + PWM_Init(pin, PWM_RESOLUTION_DEFAULT, PWM_FREQUENCY_DEFAULT); + } + else + { + GPIOx_Init( + PIN_MAP[pin].GPIOx, + PIN_MAP[pin].GPIO_Pin_x, + mode, + GPIO_DRIVE_DEFAULT + ); + } +} + +/** + * @brief 将数字HIGH(1)或LOW(0)值写入数字引脚 + * @param pin:引脚编号 + * @param value: 写入值 + * @retval 无 + */ +void digitalWrite(uint8_t pin, uint8_t value) +{ + if(!IS_PIN(pin)) + { + return; + } + + value ? digitalWrite_HIGH(pin) : digitalWrite_LOW(pin); +} + +/** + * @brief 读取引脚电平 + * @param pin: 引脚编号 + * @retval 引脚电平 + */ +uint8_t digitalRead(uint8_t pin) +{ + if(!IS_PIN(pin)) + { + return 0; + } + + return digitalRead_FAST(pin); +} + +/** + * @brief 将模拟值(PWM占空比)写入引脚 + * @param pin: 引脚编号 + * @param value: PWM占空比 + * @retval 无 + */ +void analogWrite(uint8_t pin, uint16_t value) +{ + if(!IS_PWM_PIN(pin)) + { + return; + } + + PWM_Write(pin, value); +} + +/** + * @brief 从指定的模拟引脚读取值 + * @param pin: 引脚编号 + * @retval ADC值:0~4095 + */ +uint16_t analogRead(uint8_t pin) +{ + if(!IS_ADC_PIN(pin)) + { + return 0; + } + + return ADCx_GetValue(PIN_MAP[pin].ADCx, PIN_MAP[pin].ADC_Channel); +} + +/** + * @brief 从指定的引脚读取值(DMA方式) + * @param pin: 引脚编号 + * @retval ADC值:0~4095 + */ +uint16_t analogRead_DMA(uint8_t pin) +{ + if(!IS_ADC_PIN(pin)) + { + return 0; + } + + return ADC_DMA_GetValue(PIN_MAP[pin].ADC_Channel); +} + +/** + * @brief 一次移出一个字节的数据,从最左端或最小(最右边)开始 + * @param dataPin: 输出每个位的 pin + * @param clockPin: 将 dataPin 设置为正确值后要切换的 pin (int) + * @param bitOrder: MSBFIRST / LSBFIRST + * @param value: 要移出的数据(字节) + * @retval 无 + */ +void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t value) +{ + uint8_t i; + if(!(IS_PIN(dataPin) && IS_PIN(clockPin))) + { + return; + } + + digitalWrite_LOW(clockPin); + for (i = 0; i < 8; i++) + { + int bit = bitOrder == LSBFIRST ? i : (7 - i); + digitalWrite(dataPin, (value >> bit) & 0x1); + togglePin(clockPin); + togglePin(clockPin); + } +} + +/** + * @brief 一次将一个字节的数据移位,从最左端或最小 (最右边) 开始 + * @param dataPin: 输入每个位的 pin + * @param clockPin: 要切换到的 pin 信号从dataPin读取 + * @param bitOrder: MSBFIRST/LSBFIRST + * @retval 读取的值 (字节) + */ +uint32_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint32_t bitOrder) +{ + uint8_t value = 0; + uint8_t i; + + if(!(IS_PIN(dataPin) && IS_PIN(clockPin))) + { + return 0; + } + + for (i = 0; i < 8; ++i) + { + digitalWrite_HIGH(clockPin); + if (bitOrder == LSBFIRST ) + { + value |= digitalRead(dataPin) << i; + } + else + { + value |= digitalRead(dataPin) << (7 - i); + } + digitalWrite_LOW(clockPin); + } + + return value; +} + +/** + * @brief 在引脚上读取脉冲 + * @param pin: 要读取脉冲的引脚编号 + * @param value: 脉冲类型:高或低 + * @param timeout: 等待脉冲开始的微秒数 + * @retval 脉冲的长度(以微秒计)或0, 如果没有脉冲在超时之前开始 + */ +uint32_t pulseIn(uint32_t pin, uint32_t state, uint32_t timeout) +{ + // cache the IDR address and bit of the pin in order to speed up the + // pulse width measuring loop and achieve finer resolution. calling + // digitalRead() instead yields much coarser resolution. + + volatile uint32_t *idr = portInputRegister(digitalPinToPort(pin)); + const uint32_t bit = digitalPinToBitMask(pin); + const uint32_t stateMask = (state ? bit : 0); + + uint32_t width = 0; // keep initialization out of time critical area + + // convert the timeout from microseconds to a number of times through + // the initial loop; it takes 16 clock cycles per iteration. + uint32_t numloops = 0; + uint32_t maxloops = timeout * ( F_CPU / 16000000); + volatile uint32_t dummyWidth = 0; + + if(!IS_PIN(pin)) + return 0; + + // wait for any previous pulse to end + while ((*idr & bit) == stateMask) + { + if (numloops++ == maxloops) + { + return 0; + } + dummyWidth++; + } + + // wait for the pulse to start + while ((*idr & bit) != stateMask) + { + if (numloops++ == maxloops) + { + return 0; + } + dummyWidth++; + } + + // wait for the pulse to stop + while ((*idr & bit) == stateMask) + { + if (numloops++ == maxloops) + { + return 0; + } + width++; + } + + // Excluding time taking up by the interrupts, it needs 16 clock cycles to look through the last while loop + // 5 is added as a fiddle factor to correct for interrupts etc. But ultimately this would only be accurate if it was done ona hardware timer + + return (uint32_t)( ( (unsigned long long)(width + 5) * (unsigned long long) 16000000.0) / (unsigned long long)F_CPU ); +} + +/** + * @brief 将一个数字(整形)从一个范围重新映射到另一个区域 + * @param x: 要映射的数字 + * @param in_min: 值的当前范围的下界 + * @param in_max: 值的当前范围的上界 + * @param out_min: 值的目标范围的下界 + * @param out_max: 值目标范围的上界 + * @retval 映射的值(long) + */ +long map(long x, long in_min, long in_max, long out_min, long out_max) +{ + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + +/** + * @brief 将一个数字(浮点型)从一个范围重新映射到另一个区域 + * @param x: 要映射的数字 + * @param in_min: 值的当前范围的下界 + * @param in_max: 值的当前范围的上界 + * @param out_min: 值的目标范围的下界 + * @param out_max: 值目标范围的上界 + * @retval 映射的值(double) + */ +float fmap(float x, float in_min, float in_max, float out_min, float out_max) +{ + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + +void yield(void) +{ +} diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/HardwareSerial.cpp b/ArduinoCore-AT32F403A/cores/arduino/libcore/HardwareSerial.cpp new file mode 100644 index 0000000..6fba901 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/HardwareSerial.cpp @@ -0,0 +1,292 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "HardwareSerial.h" + +#define SERIAL_GET_WORDLENGTH(SERIAL_x) ((uint16_t)(SERIAL_x&0xF000)) +#define SERIAL_GET_PARITY(SERIAL_x) ((uint16_t)(SERIAL_x&0x0F00)) +#define SERIAL_GET_STOPBITS(SERIAL_x) ((uint16_t)((SERIAL_x&0x00F0) << 8)) +typedef struct +{ + usart_data_bit_num_type data_bit; + usart_parity_selection_type parity_selection; + usart_stop_bit_num_type stop_bit; +} SERIAL_ConfigGrp_t; + +static const SERIAL_ConfigGrp_t SERIAL_ConfigGrp[] = +{ + {USART_DATA_8BITS, USART_PARITY_NONE, USART_STOP_1_BIT}, // SERIAL_8N1 + {USART_DATA_8BITS, USART_PARITY_NONE, USART_STOP_2_BIT}, // SERIAL_8N2 + {USART_DATA_8BITS, USART_PARITY_EVEN, USART_STOP_1_BIT}, // SERIAL_8E1 + {USART_DATA_8BITS, USART_PARITY_EVEN, USART_STOP_2_BIT}, // SERIAL_8E2 + {USART_DATA_8BITS, USART_PARITY_ODD, USART_STOP_1_BIT}, // SERIAL_8O1 + {USART_DATA_8BITS, USART_PARITY_ODD, USART_STOP_2_BIT}, // SERIAL_8O2 + {USART_DATA_8BITS, USART_PARITY_NONE, USART_STOP_0_5_BIT}, // SERIAL_8N0_5 + {USART_DATA_8BITS, USART_PARITY_NONE, USART_STOP_1_5_BIT}, // SERIAL_8N1_5 + {USART_DATA_8BITS, USART_PARITY_EVEN, USART_STOP_0_5_BIT}, // SERIAL_8E0_5 + {USART_DATA_8BITS, USART_PARITY_EVEN, USART_STOP_1_5_BIT}, // SERIAL_8E1_5 + {USART_DATA_8BITS, USART_PARITY_ODD, USART_STOP_0_5_BIT}, // SERIAL_8O0_5 + {USART_DATA_8BITS, USART_PARITY_ODD, USART_STOP_1_5_BIT}, // SERIAL_8O1_5 + + {USART_DATA_9BITS, USART_PARITY_NONE, USART_STOP_1_BIT}, // SERIAL_9N1 + {USART_DATA_9BITS, USART_PARITY_NONE, USART_STOP_2_BIT}, // SERIAL_9N2 + {USART_DATA_9BITS, USART_PARITY_EVEN, USART_STOP_1_BIT}, // SERIAL_9E1 + {USART_DATA_9BITS, USART_PARITY_EVEN, USART_STOP_2_BIT}, // SERIAL_9E2 + {USART_DATA_9BITS, USART_PARITY_ODD, USART_STOP_1_BIT}, // SERIAL_9O1 + {USART_DATA_9BITS, USART_PARITY_ODD, USART_STOP_2_BIT}, // SERIAL_9O2 + {USART_DATA_9BITS, USART_PARITY_NONE, USART_STOP_0_5_BIT}, // SERIAL_9N0_5 + {USART_DATA_9BITS, USART_PARITY_NONE, USART_STOP_1_5_BIT}, // SERIAL_9N1_5 + {USART_DATA_9BITS, USART_PARITY_EVEN, USART_STOP_0_5_BIT}, // SERIAL_9E0_5 + {USART_DATA_9BITS, USART_PARITY_EVEN, USART_STOP_1_5_BIT}, // SERIAL_9E1_5 + {USART_DATA_9BITS, USART_PARITY_ODD, USART_STOP_0_5_BIT}, // SERIAL_9O0_5 + {USART_DATA_9BITS, USART_PARITY_ODD, USART_STOP_1_5_BIT}, // SERIAL_9O1_5 +}; +/** + * @brief 串口对象构造函数 + * @param 串口外设地址 + * @retval 无 + */ +HardwareSerial::HardwareSerial(usart_type* usart) + : _USARTx(usart) + , _callbackFunction(NULL) + , _rxBufferHead(0) + , _rxBufferTail(0) +{ + memset(_rxBuffer, 0, sizeof(_rxBuffer)); +} + +/** + * @brief 串口中断入口 + * @param 无 + * @retval 无 + */ +void HardwareSerial::IRQHandler() +{ + if(usart_flag_get(_USARTx, USART_RDBF_FLAG) != RESET) + { + uint8_t c = usart_data_receive(_USARTx); + uint16_t i = (uint16_t)(_rxBufferHead + 1) % SERIAL_RX_BUFFER_SIZE; + if (i != _rxBufferTail) + { + _rxBuffer[_rxBufferHead] = c; + _rxBufferHead = i; + } + + if(_callbackFunction) + { + _callbackFunction(this); + } + + usart_flag_clear(_USARTx, USART_RDBF_FLAG); + } +} + +/** + * @brief 串口初始化 + * @param BaudRate: 波特率 + * @param Config: 配置参数 + * @param PreemptionPriority: 抢占优先级 + * @param SubPriority: 从优先级 + * @retval 无 + */ +void HardwareSerial::begin( + uint32_t baudRate, + SERIAL_Config_t config, + uint8_t preemptionPriority, + uint8_t subPriority +) +{ + gpio_type *GPIOx; + gpio_init_type gpio_init_struct; + uint16_t Tx_Pin, Rx_Pin; + IRQn_Type USARTx_IRQn; + + if(_USARTx == USART1) + { + GPIOx = GPIOA; + Tx_Pin = GPIO_Pin_9; + Rx_Pin = GPIO_Pin_10; + USARTx_IRQn = USART1_IRQn; + + crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE); + crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE); + } + else if(_USARTx == USART2) + { + GPIOx = GPIOA; + Tx_Pin = GPIO_Pin_2; + Rx_Pin = GPIO_Pin_3; + USARTx_IRQn = USART2_IRQn; + + crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE); + crm_periph_clock_enable(CRM_USART2_PERIPH_CLOCK, TRUE); + } + else if(_USARTx == USART3) + { + GPIOx = GPIOB; + Tx_Pin = GPIO_Pin_10; + Rx_Pin = GPIO_Pin_11; + USARTx_IRQn = USART3_IRQn; + + crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE); + crm_periph_clock_enable(CRM_USART3_PERIPH_CLOCK, TRUE); + } + else + { + return; + } + + gpio_default_para_init(&gpio_init_struct); + gpio_init_struct.gpio_pins = Tx_Pin | Rx_Pin; + gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init(GPIOx, &gpio_init_struct); + + usart_init(_USARTx, baudRate, SERIAL_ConfigGrp[config].data_bit, SERIAL_ConfigGrp[config].stop_bit); + usart_parity_selection_config(_USARTx, SERIAL_ConfigGrp[config].parity_selection); + usart_transmitter_enable(_USARTx, TRUE); + usart_receiver_enable(_USARTx, TRUE); + + nvic_irq_enable(USARTx_IRQn, preemptionPriority, subPriority); + usart_interrupt_enable(_USARTx, USART_RDBF_INT, TRUE); + + usart_enable(_USARTx, TRUE); +} + +/** + * @brief 关闭串口 + * @param 无 + * @retval 无 + */ +void HardwareSerial::end(void) +{ + usart_interrupt_enable(_USARTx, USART_RDBF_INT, FALSE); + usart_enable(_USARTx, FALSE); +} + +/** + * @brief 串口中断回调 + * @param Function: 回调函数 + * @retval 无 + */ +void HardwareSerial::attachInterrupt(CallbackFunction_t func) +{ + _callbackFunction = func; +} + +/** + * @brief 获取可从串行端口读取的字节数 + * @param 无 + * @retval 可读取的字节数 + */ +int HardwareSerial::available(void) +{ + return ((unsigned int)(SERIAL_RX_BUFFER_SIZE + _rxBufferHead - _rxBufferTail)) % SERIAL_RX_BUFFER_SIZE; +} + +/** + * @brief 读取传入的串行数据(字符) + * @param 无 + * @retval 可用的传入串行数据的第一个字节 (如果没有可用的数据, 则为-1) + */ +int HardwareSerial::read(void) +{ + // if the head isn't ahead of the tail, we don't have any characters + if (_rxBufferHead == _rxBufferTail) + { + return -1; + } + else + { + uint8_t c = _rxBuffer[_rxBufferTail]; + _rxBufferTail = (uint16_t)(_rxBufferTail + 1) % SERIAL_RX_BUFFER_SIZE; + return c; + } +} + +/** + * @brief 返回传入串行数据的下一个字节(字符), 而不将其从内部串行缓冲区中删除 + * @param 无 + * @retval 可用的传入串行数据的第一个字节 (如果没有可用的数据, 则为-1) + */ +int HardwareSerial::peek(void) +{ + if (_rxBufferHead == _rxBufferTail) + { + return -1; + } + else + { + return _rxBuffer[_rxBufferTail]; + } +} + +/** + * @brief 清空串口缓存 + * @param 无 + * @retval 无 + */ +void HardwareSerial::flush(void) +{ + _rxBufferHead = _rxBufferTail; +} + +/** + * @brief 串口写入一个字节 + * @param 写入的字节 + * @retval 字节 + */ +size_t HardwareSerial::write(uint8_t n) +{ + while(!usart_flag_get(_USARTx, USART_TDBE_FLAG)) {}; + usart_data_transmit(_USARTx, n); + return 1; +} + +#if SERIAL_1_ENABLE +HardwareSerial Serial(SERIAL_1_USART); + +extern "C" SERIAL_1_IRQ_HANDLER_DEF() +{ + Serial.IRQHandler(); +} +#endif + +#if SERIAL_2_ENABLE +HardwareSerial Serial2(SERIAL_2_USART); + +extern "C" SERIAL_2_IRQ_HANDLER_DEF() +{ + Serial2.IRQHandler(); +} +#endif + +#if SERIAL_3_ENABLE +HardwareSerial Serial3(SERIAL_3_USART); + +extern "C" SERIAL_3_IRQ_HANDLER_DEF() +{ + Serial3.IRQHandler(); +} +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/HardwareSerial.h b/ArduinoCore-AT32F403A/cores/arduino/libcore/HardwareSerial.h new file mode 100644 index 0000000..1790f37 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/HardwareSerial.h @@ -0,0 +1,142 @@ +/* + * MIT License + * Copyright (c) 2019 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __HardwareSerial_h +#define __HardwareSerial_h + +#include "Arduino.h" +#include "Print.h" +#include "Stream.h" + +typedef enum +{ + SERIAL_7N1, + SERIAL_7N2, + SERIAL_7E1, + SERIAL_7E2, + SERIAL_7O1, + SERIAL_7O2, + SERIAL_7N0_5, + SERIAL_7N1_5, + SERIAL_7E0_5, + SERIAL_7E1_5, + SERIAL_7O0_5, + SERIAL_7O1_5, + + SERIAL_8N1, + SERIAL_8N2, + SERIAL_8E1, + SERIAL_8E2, + SERIAL_8O1, + SERIAL_8O2, + SERIAL_8N0_5, + SERIAL_8N1_5, + SERIAL_8E0_5, + SERIAL_8E1_5, + SERIAL_8O0_5, + SERIAL_8O1_5, + + SERIAL_9N1, + SERIAL_9N2, + SERIAL_9E1, + SERIAL_9E2, + SERIAL_9O1, + SERIAL_9O2, + SERIAL_9N0_5, + SERIAL_9N1_5, + SERIAL_9E0_5, + SERIAL_9E1_5, + SERIAL_9O0_5, + SERIAL_9O1_5, +} SERIAL_Config_t; + +class HardwareSerial : public Stream +{ + typedef void(*CallbackFunction_t)(HardwareSerial* serial); + +public: + HardwareSerial(usart_type* usart); + + usart_type* getUSART() + { + return _USARTx; + } + + void begin( + uint32_t baudRate, + SERIAL_Config_t config = SERIAL_CONFIG_DEFAULT, + uint8_t preemptionPriority = SERIAL_PREEMPTIONPRIORITY_DEFAULT, + uint8_t subPriority = SERIAL_SUBPRIORITY_DEFAULT + ); + void end(void); + void attachInterrupt(CallbackFunction_t func); + virtual int available(void); + virtual int peek(void); + virtual int read(void); + virtual void flush(void); + + virtual size_t write(uint8_t n); + inline size_t write(unsigned long n) + { + return write((uint8_t)n); + } + inline size_t write(long n) + { + return write((uint8_t)n); + } + inline size_t write(unsigned int n) + { + return write((uint8_t)n); + } + inline size_t write(int n) + { + return write((uint8_t)n); + } + using Print::write; // pull in write(str) and write(buf, size) from Print + operator bool() + { + return true; + } + + void IRQHandler(); + +private: + usart_type* _USARTx; + CallbackFunction_t _callbackFunction; + volatile uint16_t _rxBufferHead; + volatile uint16_t _rxBufferTail; + uint8_t _rxBuffer[SERIAL_RX_BUFFER_SIZE]; +}; + +#if SERIAL_1_ENABLE +extern HardwareSerial Serial; +#endif + +#if SERIAL_2_ENABLE +extern HardwareSerial Serial2; +#endif + +#if SERIAL_3_ENABLE +extern HardwareSerial Serial3; +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/SPI.cpp b/ArduinoCore-AT32F403A/cores/arduino/libcore/SPI.cpp new file mode 100644 index 0000000..c4e5e55 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/SPI.cpp @@ -0,0 +1,430 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "SPI.h" + +#define SPI1_CLOCK (F_CPU) +#define SPI2_CLOCK (F_CPU) +#define SPI3_CLOCK (F_CPU) + +SPIClass::SPIClass(spi_type* spix) + : SPIx(spix) + , SPI_Clock(0) +{ + memset(&spi_init_struct, 0, sizeof(spi_init_struct)); +} + +void SPIClass::SPI_Settings( + spi_master_slave_mode_type master_slave_mode, + spi_frame_bit_num_type frame_bit_num, + uint16_t SPI_MODEx, + spi_cs_mode_type cs_mode, + spi_mclk_freq_div_type mclk_freq_div, + spi_first_bit_type first_bit) +{ + spi_clock_polarity_type clock_polarity; + spi_clock_phase_type clock_phase; + spi_enable(SPIx, FALSE); + + switch(SPI_MODEx) + { + case 0: + clock_polarity = SPI_CLOCK_POLARITY_LOW; + clock_phase = SPI_CLOCK_PHASE_1EDGE; + break; + case 1: + clock_polarity = SPI_CLOCK_POLARITY_LOW; + clock_phase = SPI_CLOCK_PHASE_2EDGE; + break; + case 2: + clock_polarity = SPI_CLOCK_POLARITY_HIGH; + clock_phase = SPI_CLOCK_PHASE_1EDGE; + break; + case 3: + clock_polarity = SPI_CLOCK_POLARITY_HIGH; + clock_phase = SPI_CLOCK_PHASE_2EDGE; + break; + default: + return; + } + + spi_default_para_init(&spi_init_struct); + spi_init_struct.transmission_mode = SPI_TRANSMIT_FULL_DUPLEX; + spi_init_struct.master_slave_mode = master_slave_mode; + spi_init_struct.frame_bit_num = frame_bit_num; + spi_init_struct.clock_polarity = clock_polarity; + spi_init_struct.clock_phase = clock_phase; + spi_init_struct.cs_mode_selection = cs_mode; + spi_init_struct.mclk_freq_division = mclk_freq_div; + spi_init_struct.first_bit_transmission = first_bit; + spi_init(SPIx, &spi_init_struct); + + spi_enable(SPIx, TRUE); +} + +void SPIClass::begin(void) +{ + spi_i2s_reset(SPIx); + if(SPIx == SPI1) + { + SPI_Clock = SPI1_CLOCK; + crm_periph_clock_enable(CRM_SPI1_PERIPH_CLOCK, TRUE); + pinMode(PA5, OUTPUT_AF_PP); + pinMode(PA6, OUTPUT_AF_PP); + pinMode(PA7, OUTPUT_AF_PP); + } + else if(SPIx == SPI2) + { + SPI_Clock = SPI2_CLOCK; + crm_periph_clock_enable(CRM_SPI2_PERIPH_CLOCK, TRUE); + pinMode(PB13, OUTPUT_AF_PP); + pinMode(PB14, OUTPUT_AF_PP); + pinMode(PB15, OUTPUT_AF_PP); + + } + else if(SPIx == SPI3) + { + SPI_Clock = SPI3_CLOCK; + crm_periph_clock_enable(CRM_SPI3_PERIPH_CLOCK, TRUE); + pinMode(PB3, OUTPUT_AF_PP); + pinMode(PB4, OUTPUT_AF_PP); + pinMode(PB5, OUTPUT_AF_PP); + + } + else + { + return; + } + + SPI_Settings( + SPI_MODE_MASTER, + SPI_FRAME_8BIT, + SPI_MODE0, + SPI_CS_SOFTWARE_MODE, + SPI_MCLK_DIV_8, + SPI_FIRST_BIT_MSB + ); +} + +void SPIClass::begin(uint32_t clock, uint16_t dataOrder, uint16_t dataMode) +{ + begin(); + setClock(clock); + setBitOrder(dataOrder); + setDataMode(dataMode); + spi_enable(SPIx, TRUE); +} + +void SPIClass::begin(SPISettings settings) +{ + begin(); + setClock(settings.clock); + setBitOrder(settings.bitOrder); + setDataMode(settings.dataMode); + spi_enable(SPIx, TRUE); +} + +void SPIClass::beginSlave(void) +{ + begin(); + SPI_Settings( + SPI_MODE_SLAVE, + SPI_FRAME_8BIT, + SPI_MODE0, + SPI_CS_SOFTWARE_MODE, + SPI_MCLK_DIV_16, + SPI_FIRST_BIT_MSB + ); + spi_enable(SPIx, TRUE); +} + +void SPIClass::end(void) +{ + spi_enable(SPIx, FALSE); +} + +void SPIClass::setClock(uint32_t clock) +{ + if(clock == 0) + { + return; + } + + static const spi_mclk_freq_div_type mclk_freq_div_map[] = + { + SPI_MCLK_DIV_2, + SPI_MCLK_DIV_2, + SPI_MCLK_DIV_4, + SPI_MCLK_DIV_8, + SPI_MCLK_DIV_16, + SPI_MCLK_DIV_32, + SPI_MCLK_DIV_64, + SPI_MCLK_DIV_128, + SPI_MCLK_DIV_256, + SPI_MCLK_DIV_512, + SPI_MCLK_DIV_1024, + }; + const uint8_t mapSize = sizeof(mclk_freq_div_map) / sizeof(mclk_freq_div_map[0]); + uint32_t clockDiv = SPI_Clock / clock; + uint8_t mapIndex = 0; + + while(clockDiv > 1) + { + clockDiv = clockDiv >> 1; + mapIndex++; + } + + if(mapIndex >= mapSize) + { + mapIndex = mapSize - 1; + } + + spi_init_struct.mclk_freq_division = mclk_freq_div_map[mapIndex]; + spi_init(SPIx, &spi_init_struct); + spi_enable(SPIx, TRUE); +} + +void SPIClass::setClockDivider(uint32_t Div) +{ + if(Div == 0) + { + Div = 1; + } +#if SPI_CLASS_AVR_COMPATIBILITY_MODE + setClock(16000000 / Div); // AVR:16MHz +#else + setClock(SPI_Clock / Div); +#endif +} + +void SPIClass::setBitOrder(uint16_t bitOrder) +{ + spi_init_struct.first_bit_transmission = (bitOrder == MSBFIRST) ? SPI_FIRST_BIT_MSB : SPI_FIRST_BIT_LSB; + spi_init(SPIx, &spi_init_struct); + spi_enable(SPIx, TRUE); +} + +/* Victor Perez. Added to test changing datasize from 8 to 16 bit modes on the fly. +* Input parameter should be SPI_CR1_DFF set to 0 or 1 on a 32bit word. +* +*/ +void SPIClass::setDataSize(uint32_t datasize) +{ + spi_init_struct.frame_bit_num = (spi_frame_bit_num_type)datasize; + spi_init(SPIx, &spi_init_struct); + spi_enable(SPIx, TRUE); +} + +void SPIClass::setDataMode(uint8_t dataMode) +{ + /* Notes. As far as I can tell, the AVR numbers for dataMode appear to match the numbers required by the STM32 + + From the AVR doc http://www.atmel.com/images/doc2585.pdf section 2.4 + + SPI Mode CPOL CPHA Shift SCK-edge Capture SCK-edge + 0 0 0 Falling Rising + 1 0 1 Rising Falling + 2 1 0 Rising Falling + 3 1 1 Falling Rising + + + On the STM32 it appears to be + + bit 1 - CPOL : Clock polarity + (This bit should not be changed when communication is ongoing) + 0 : CLK to 0 when idle + 1 : CLK to 1 when idle + + bit 0 - CPHA : Clock phase + (This bit should not be changed when communication is ongoing) + 0 : The first clock transition is the first data capture edge + 1 : The second clock transition is the first data capture edge + + If someone finds this is not the case or sees a logic error with this let me know ;-) + */ + spi_clock_polarity_type clock_polarity; + spi_clock_phase_type clock_phase; + spi_enable(SPIx, FALSE); + + switch(dataMode) + { + case 0: + clock_polarity = SPI_CLOCK_POLARITY_LOW; + clock_phase = SPI_CLOCK_PHASE_1EDGE; + break; + case 1: + clock_polarity = SPI_CLOCK_POLARITY_LOW; + clock_phase = SPI_CLOCK_PHASE_2EDGE; + break; + case 2: + clock_polarity = SPI_CLOCK_POLARITY_HIGH; + clock_phase = SPI_CLOCK_PHASE_1EDGE; + break; + case 3: + clock_polarity = SPI_CLOCK_POLARITY_HIGH; + clock_phase = SPI_CLOCK_PHASE_2EDGE; + break; + default: + return; + } + + spi_init_struct.clock_polarity = clock_polarity; + spi_init_struct.clock_phase = clock_phase; + spi_init(SPIx, &spi_init_struct); + spi_enable(SPIx, TRUE); +} + +void SPIClass::beginTransaction(SPISettings settings) +{ + SPISettings(settings.clock, settings.bitOrder, settings.dataMode); + + setClock(settings.clock); + setBitOrder(settings.bitOrder); + setDataMode(settings.dataMode); + setDataSize(settings.dataSize); + + spi_enable(SPIx, TRUE); +} + +void SPIClass::beginTransactionSlave(void) +{ + beginSlave(); +} + +void SPIClass::endTransaction(void) +{ + spi_enable(SPIx, FALSE); +} + +uint16_t SPIClass::read(void) +{ + SPI_I2S_WAIT_RX(SPIx); + return (uint16_t)(SPI_I2S_RXDATA(SPIx)); +} + +void SPIClass::read(uint8_t *buf, uint32_t len) +{ + if (len == 0) + return; + + SPI_I2S_RXDATA_VOLATILE(SPIx); + SPI_I2S_TXDATA(SPIx, 0x00FF); + + while((--len)) + { + SPI_I2S_WAIT_TX(SPIx); + noInterrupts(); + SPI_I2S_TXDATA(SPIx, 0x00FF); + SPI_I2S_WAIT_RX(SPIx); + *buf++ = (uint8_t)SPI_I2S_RXDATA(SPIx); + interrupts(); + } + SPI_I2S_WAIT_RX(SPIx); + *buf++ = (uint8_t)SPI_I2S_RXDATA(SPIx); +} + +void SPIClass::write(uint16_t data) +{ + SPI_I2S_TXDATA(SPIx, data); + SPI_I2S_WAIT_TX(SPIx); + SPI_I2S_WAIT_BUSY(SPIx); +} + +void SPIClass::write(uint16_t data, uint32_t n) +{ + while ((n--) > 0) + { + SPI_I2S_TXDATA(SPIx, data); // write the data to be transmitted into the SPI_DR register (this clears the TXE flag) + SPI_I2S_WAIT_TX(SPIx); // wait till Tx empty + } + + SPI_I2S_WAIT_BUSY(SPIx); // wait until BSY=0 before returning +} + +void SPIClass::write(const uint8_t *data, uint32_t length) +{ + while (length--) + { + SPI_I2S_WAIT_TX(SPIx); + SPI_I2S_TXDATA(SPIx, *data++); + } + SPI_I2S_WAIT_TX(SPIx); + SPI_I2S_WAIT_BUSY(SPIx); +} + +void SPIClass::write(const uint16_t *data, uint32_t length) +{ + while (length--) + { + SPI_I2S_WAIT_TX(SPIx); + SPI_I2S_TXDATA(SPIx, *data++); + } + SPI_I2S_WAIT_TX(SPIx); + SPI_I2S_WAIT_BUSY(SPIx); +} + +uint8_t SPIClass::transfer(uint8_t wr_data) const +{ + SPI_I2S_RXDATA_VOLATILE(SPIx); + SPI_I2S_TXDATA(SPIx, wr_data); + SPI_I2S_WAIT_TX(SPIx); + SPI_I2S_WAIT_BUSY(SPIx); + return (uint8_t)SPI_I2S_RXDATA(SPIx); +} + +uint16_t SPIClass::transfer16(uint16_t wr_data) const +{ + SPI_I2S_RXDATA_VOLATILE(SPIx); + SPI_I2S_TXDATA(SPIx, wr_data); + SPI_I2S_WAIT_TX(SPIx); + SPI_I2S_WAIT_BUSY(SPIx); + return (uint16_t)SPI_I2S_RXDATA(SPIx); +} + +uint8_t SPIClass::send(uint8_t data) +{ + this->write(data); + return 1; +} + +uint8_t SPIClass::send(uint8_t *buf, uint32_t len) +{ + this->write(buf, len); + return len; +} + +uint8_t SPIClass::recv(void) +{ + return this->read(); +} + +#if SPI_CLASS_1_ENABLE +SPIClass SPI(SPI_CLASS_1_SPI); +#endif + +#if SPI_CLASS_2_ENABLE +SPIClass SPI_2(SPI_CLASS_2_SPI); +#endif + +#if SPI_CLASS_3_ENABLE +SPIClass SPI_3(SPI_CLASS_3_SPI); +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/SPI.h b/ArduinoCore-AT32F403A/cores/arduino/libcore/SPI.h new file mode 100644 index 0000000..11613fe --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/SPI.h @@ -0,0 +1,173 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __SPI_H +#define __SPI_H + +#include "Arduino.h" + +#ifndef LSBFIRST +# define LSBFIRST 0 +#endif +#ifndef MSBFIRST +# define MSBFIRST 1 +#endif + +#if SPI_CLASS_PIN_DEFINE_ENABLE +# define SS PA4 +# define SCK PA5 +# define MISO PA6 +# define MOSI PA7 +#endif + +#define DATA_SIZE_8BIT SPI_FRAME_8BIT +#define DATA_SIZE_16BIT SPI_FRAME_16BIT + +#define SPI_I2S_GET_FLAG(spix, SPI_I2S_FLAG) (spix->sts & SPI_I2S_FLAG) +#define SPI_I2S_RXDATA(spix) (spix->dt) +#define SPI_I2S_RXDATA_VOLATILE(spix) volatile uint16_t vn = SPI_I2S_RXDATA(spix) +#define SPI_I2S_TXDATA(spix, data) (spix->dt = (data)) +#define SPI_I2S_WAIT_RX(spix) do{ while (!SPI_I2S_GET_FLAG(spix, SPI_I2S_RDBF_FLAG)); } while(0) +#define SPI_I2S_WAIT_TX(spix) do{ while (!SPI_I2S_GET_FLAG(spix, SPI_I2S_TDBE_FLAG)); } while(0) +#define SPI_I2S_WAIT_BUSY(spix) do{ while (SPI_I2S_GET_FLAG(spix, SPI_I2S_BF_FLAG)); } while(0) + +typedef enum +{ + SPI_MODE0, + SPI_MODE1, + SPI_MODE2, + SPI_MODE3 +} SPI_MODE_TypeDef; + +typedef enum +{ + SPI_STATE_IDLE, + SPI_STATE_READY, + SPI_STATE_RECEIVE, + SPI_STATE_TRANSMIT, + SPI_STATE_TRANSFER +} spi_mode_t; + +class SPISettings +{ +public: + SPISettings(uint32_t clock, uint16_t bitOrder, uint8_t dataMode) + { + init_AlwaysInline(clock, bitOrder, dataMode, DATA_SIZE_8BIT); + } + SPISettings(uint32_t clock, uint16_t bitOrder, uint8_t dataMode, uint32_t dataSize) + { + init_AlwaysInline(clock, bitOrder, dataMode, dataSize); + } + SPISettings(uint32_t clock) + { + init_AlwaysInline(clock, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT); + } + SPISettings() + { + init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT); + } +private: + void init_MightInline(uint32_t clock, uint16_t bitOrder, uint8_t dataMode, uint32_t dataSize) + { + init_AlwaysInline(clock, bitOrder, dataMode, dataSize); + } + void init_AlwaysInline(uint32_t clock, uint16_t bitOrder, uint8_t dataMode, uint32_t dataSize) __attribute__((__always_inline__)) + { + this->clock = clock; + this->bitOrder = bitOrder; + this->dataMode = dataMode; + this->dataSize = dataSize; + } + uint32_t clock; + uint16_t bitOrder; + uint8_t dataMode; + uint32_t dataSize; + + friend class SPIClass; +}; + +class SPIClass +{ +public: + SPIClass(spi_type* spix); + void SPI_Settings( + spi_master_slave_mode_type master_slave_mode, + spi_frame_bit_num_type frame_bit_num, + uint16_t SPI_MODEx, + spi_cs_mode_type cs_mode, + spi_mclk_freq_div_type mclk_freq_div, + spi_first_bit_type first_bit + ); + void begin(void); + void begin(uint32_t clock, uint16_t dataOrder, uint16_t dataMode); + void begin(SPISettings settings); + void beginSlave(uint32_t bitOrder, uint32_t mode); + void beginSlave(void); + void beginTransactionSlave(void); + void beginTransaction(SPISettings settings); + + void endTransaction(void); + void end(void); + + void setClock(uint32_t clock); + void setClockDivider(uint32_t Div); + void setBitOrder(uint16_t bitOrder); + void setDataMode(uint8_t dataMode); + void setDataSize(uint32_t datasize); + + uint16_t read(void); + void read(uint8_t *buffer, uint32_t length); + void write(uint16_t data); + void write(uint16_t data, uint32_t n); + void write(const uint8_t *data, uint32_t length); + void write(const uint16_t *data, uint32_t length); + uint8_t transfer(uint8_t data) const; + uint16_t transfer16(uint16_t data) const; + uint8_t send(uint8_t data); + uint8_t send(uint8_t *data, uint32_t length); + uint8_t recv(void); + + spi_type* getSPI() + { + return SPIx; + } + +private: + spi_type* SPIx; + spi_init_type spi_init_struct; + uint32_t SPI_Clock; +}; + +#if SPI_CLASS_1_ENABLE +extern SPIClass SPI; +#endif + +#if SPI_CLASS_2_ENABLE +extern SPIClass SPI_2; +#endif + +#if SPI_CLASS_3_ENABLE +extern SPIClass SPI_3; +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/Tone.cpp b/ArduinoCore-AT32F403A/cores/arduino/libcore/Tone.cpp new file mode 100644 index 0000000..20b9b33 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/Tone.cpp @@ -0,0 +1,128 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Tone.h" +#include "Arduino.h" + +#define TONE_FREQ_MAX 500000U + +static tmr_type* Tone_Timer = NULL; +static bool Tone_IsContinuousModeEnable = false; +static uint8_t Tone_Pin = NOT_A_PIN; +static uint32_t Tone_ToggleCounter = 0; + +/** + * @brief tone中断入口,被定时中断调用 + * @param 无 + * @retval 无 + */ +static void Tone_TimerHandler() +{ + if(!Tone_IsContinuousModeEnable) + { + if(Tone_ToggleCounter == 0) + { + noTone(Tone_Pin); + return; + } + + Tone_ToggleCounter--; + } + + togglePin(Tone_Pin); +} + +/** + * @brief 改变tone所使用的定时器 + * @param TIMx: 定时器地址 + * @retval 无 + */ +void toneSetTimer(tmr_type* TIMx) +{ + Timer_SetInterruptBase( + TIMx, + 0xFF, + 0xFF, + Tone_TimerHandler, + TONE_PREEMPTIONPRIORITY_DEFAULT, + TONE_SUBPRIORITY_DEFAULT + ); + Tone_Timer = TIMx; +} + +/** + * @brief 在Pin上生成指定频率 (50%占空比的方波) + * @param pin: 产生音调的 Pin + * @param freq: 频率(Hz) + * @param duration: 音调的持续时间 (以毫秒为单位) + * @retval 无 + */ +void tone(uint8_t pin, uint32_t freq, uint32_t duration) +{ + noTone(pin); + + if(duration == 0 || freq == 0 || freq > TONE_FREQ_MAX) + { + return; + } + + Tone_Pin = pin; + Tone_IsContinuousModeEnable = (duration == TONE_DURATION_INFINITE) ? true : false; + + if(!Tone_IsContinuousModeEnable) + { + Tone_ToggleCounter = freq * duration / 1000 * 2; + + if(Tone_ToggleCounter == 0) + { + return; + } + + Tone_ToggleCounter--; + } + + if(Tone_Timer == NULL) + { + toneSetTimer(TONE_TIMER_DEFAULT); + } + + Timer_SetInterruptTimeUpdate(Tone_Timer, TONE_FREQ_MAX / freq); + Timer_SetEnable(Tone_Timer, true); +} + +/** + * @brief 关闭声音 + * @param Pin: 产生音调的引脚编号 + * @retval 无 + */ +void noTone(uint8_t pin) +{ + if(Tone_Timer) + { + Timer_SetEnable(Tone_Timer, false); + } + + digitalWrite(pin, LOW); + Tone_IsContinuousModeEnable = false; + Tone_Pin = NOT_A_PIN; + Tone_ToggleCounter = 0; +} diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/Tone.h b/ArduinoCore-AT32F403A/cores/arduino/libcore/Tone.h new file mode 100644 index 0000000..ca4f246 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/Tone.h @@ -0,0 +1,34 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __TONE_H +#define __TONE_H + +#include "timer.h" + +#define TONE_DURATION_INFINITE 0xFFFFFFFFU + +void toneSetTimer(tmr_type* TIMx); +void tone(uint8_t pin, uint32_t freq, uint32_t duration = TONE_DURATION_INFINITE); +void noTone(uint8_t pin); + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/adc.c b/ArduinoCore-AT32F403A/cores/arduino/libcore/adc.c new file mode 100644 index 0000000..6169894 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/adc.c @@ -0,0 +1,255 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "adc.h" +#include + +#define ADC_DMA_REGMAX 18 + +#define IS_ADC_CHANNEL(channel) (channel <= ADC_CHANNEL_17) + +/*引脚注册个数*/ +static uint8_t ADC_DMA_RegCnt = 0; + +/*ADC通道注册列表*/ +static uint8_t ADC_DMA_RegChannelList[ADC_DMA_REGMAX] = {0}; + +/*ADC DMA缓存数组*/ +static uint16_t ADC_DMA_ConvertedValue[ADC_DMA_REGMAX] = {0}; + +/** + * @brief 搜索注册列表,找出ADC通道对应的索引号 + * @param ADC_Channel:ADC通道号 + * @retval ADC通道注册列表对应索引号,-1:未找到对应通道号 + */ +static int16_t ADC_DMA_SearchChannel(uint16_t ADC_Channel) +{ + uint8_t index; + + for(index = 0; index < ADC_DMA_RegCnt; index++) + { + if(ADC_Channel == ADC_DMA_RegChannelList[index]) + { + return index; + } + } + return -1; +} + +/** + * @brief ADC 配置 + * @param ADCx: ADC地址 + * @retval 无 + */ +void ADCx_Init(adc_type* ADCx) +{ + adc_base_config_type adc_base_struct; + + if(ADCx == ADC1) + { + crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE); + } + else if(ADCx == ADC2) + { + crm_periph_clock_enable(CRM_ADC2_PERIPH_CLOCK, TRUE); + } +#ifdef ADC3 + else if(ADCx == ADC3) + { + crm_periph_clock_enable(CRM_ADC3_PERIPH_CLOCK, TRUE); + } +#endif + else + { + return; + } + crm_adc_clock_div_set(CRM_ADC_DIV_8); + adc_combine_mode_select(ADC_INDEPENDENT_MODE); + adc_base_default_para_init(&adc_base_struct); + adc_base_struct.sequence_mode = FALSE; + adc_base_struct.repeat_mode = FALSE; + adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT; + adc_base_struct.ordinary_channel_length = 1; + adc_base_config(ADCx, &adc_base_struct); + if (ADCx != ADC3) + adc_ordinary_conversion_trigger_set(ADCx, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE); + else + adc_ordinary_conversion_trigger_set(ADCx, ADC3_ORDINARY_TRIG_SOFTWARE, TRUE); + + adc_enable(ADCx, TRUE); + adc_calibration_init(ADCx); + while(adc_calibration_init_status_get(ADCx)); + adc_calibration_start(ADCx); + while(adc_calibration_status_get(ADCx)); +} + +/** + * @brief 获取 ADC 值 + * @param ADCx: ADC地址 + * @param ADC_Channel: ADC通道 + * @retval 无 + */ +uint16_t ADCx_GetValue(adc_type* ADCx, uint16_t ADC_Channel) +{ + adc_ordinary_channel_set(ADCx, (adc_channel_select_type)ADC_Channel, 1, ADC_SAMPLETIME_41_5); + + adc_ordinary_software_trigger_enable(ADCx, TRUE); + while(!adc_flag_get(ADCx, ADC_CCE_FLAG)); + + return adc_ordinary_conversion_data_get(ADCx); +} + +/** + * @brief 注册需要DMA搬运的ADC通道 + * @param ADC_Channel:ADC通道号 + * @retval 见ADC_DMA_Res_Type + */ +ADC_DMA_Res_Type ADC_DMA_Register(uint8_t ADC_Channel) +{ + /*初始化ADC通道列表*/ + static bool isInit = false; + if(!isInit) + { + uint8_t i; + for(i = 0; i < ADC_DMA_REGMAX; i++) + { + ADC_DMA_RegChannelList[i] = 0xFF; + } + isInit = true; + } + + /*是否是合法ADC通道*/ + if(!IS_ADC_CHANNEL(ADC_Channel)) + return ADC_DMA_RES_NOT_ADC_CHANNEL; + + /*是否已在引脚列表重复注册*/ + if(ADC_DMA_SearchChannel(ADC_Channel) != -1) + return ADC_DMA_RES_DUPLICATE_REGISTRATION; + + /*是否超出最大注册个数*/ + if(ADC_DMA_RegCnt >= ADC_DMA_REGMAX) + return ADC_DMA_RES_MAX_NUM_OF_REGISTRATIONS_EXCEEDED; + + /*写入注册列表*/ + ADC_DMA_RegChannelList[ADC_DMA_RegCnt] = ADC_Channel; + + /*注册个数+1*/ + ADC_DMA_RegCnt++; + + return ADC_DMA_RES_OK; +} + +/** + * @brief 获取已注册的ADC DMA通道数量 + * @param 无 + * @retval ADC DMA通道数量 + */ +uint8_t ADC_DMA_GetRegisterCount(void) +{ + return ADC_DMA_RegCnt; +} + +/** + * @brief ADC DMA 配置 + * @param 无 + * @retval 无 + */ +void ADC_DMA_Init(void) +{ + dma_init_type dma_init_structure; + adc_base_config_type adc_base_struct; + uint8_t index; + + crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE); + crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE); + + dma_reset(DMA1_CHANNEL1); + + dma_default_para_init(&dma_init_structure); + dma_init_structure.buffer_size = ADC_DMA_RegCnt; + dma_init_structure.direction = DMA_DIR_PERIPHERAL_TO_MEMORY; + dma_init_structure.memory_base_addr = (uint32_t)ADC_DMA_ConvertedValue; + dma_init_structure.memory_data_width = DMA_MEMORY_DATA_WIDTH_HALFWORD; + dma_init_structure.memory_inc_enable = TRUE; + dma_init_structure.peripheral_base_addr = (uint32_t) (&(ADC1->odt)); + dma_init_structure.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_HALFWORD; + dma_init_structure.peripheral_inc_enable = FALSE; + dma_init_structure.priority = DMA_PRIORITY_HIGH; + dma_init_structure.loop_mode_enable = TRUE; + + dma_init(DMA1_CHANNEL1, &dma_init_structure); + + + adc_combine_mode_select(ADC_INDEPENDENT_MODE); + adc_base_default_para_init(&adc_base_struct); + adc_base_struct.sequence_mode = FALSE; + adc_base_struct.repeat_mode = FALSE; + adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT; + adc_base_struct.ordinary_channel_length = 1; + adc_base_config(ADC1, &adc_base_struct); + adc_ordinary_conversion_trigger_set(ADC1, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE); + + crm_adc_clock_div_set(CRM_ADC_DIV_8); + + for(index = 0; index < ADC_DMA_RegCnt; index++) + { + adc_ordinary_channel_set( + ADC1, + ADC_DMA_RegChannelList[index], + index + 1, + ADC_SAMPLETIME_41_5 + ); + + if(ADC_DMA_RegChannelList[index] == ADC_CHANNEL_16) + { + adc_tempersensor_vintrv_enable(true); + } + } + + adc_dma_mode_enable(ADC1, TRUE); + + adc_enable(ADC1, TRUE); + + adc_calibration_init(ADC1); + while(adc_calibration_init_status_get(ADC1)); + adc_calibration_start(ADC1); + while(adc_calibration_status_get(ADC1)); +} + +/** + * @brief 获取DMA搬运的ADC值 + * @param ADC_Channel:ADC通道号 + * @retval ADC值 + */ +uint16_t ADC_DMA_GetValue(uint8_t ADC_Channel) +{ + int16_t index; + + if(!IS_ADC_CHANNEL(ADC_Channel)) + return 0; + + index = ADC_DMA_SearchChannel(ADC_Channel); + if(index == -1) + return 0; + + return ADC_DMA_ConvertedValue[index]; +} diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/adc.h b/ArduinoCore-AT32F403A/cores/arduino/libcore/adc.h new file mode 100644 index 0000000..499d811 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/adc.h @@ -0,0 +1,51 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ADC_H +#define __ADC_H + +#include "mcu_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + ADC_DMA_RES_OK = 0, + ADC_DMA_RES_NOT_ADC_CHANNEL = -1, + ADC_DMA_RES_DUPLICATE_REGISTRATION = -2, + ADC_DMA_RES_MAX_NUM_OF_REGISTRATIONS_EXCEEDED = -3, +} ADC_DMA_Res_Type; + +void ADCx_Init(adc_type* ADCx); +uint16_t ADCx_GetValue(adc_type* ADCx, uint16_t ADC_Channel); +void ADC_DMA_Init(void); +ADC_DMA_Res_Type ADC_DMA_Register(uint8_t ADC_Channel); +uint16_t ADC_DMA_GetValue(uint8_t ADC_Channel); +uint8_t ADC_DMA_GetRegisterCount(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __ADC_H */ diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/at32f403a_407_clock.c b/ArduinoCore-AT32F403A/cores/arduino/libcore/at32f403a_407_clock.c new file mode 100644 index 0000000..512caf7 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/at32f403a_407_clock.c @@ -0,0 +1,105 @@ +/** + ************************************************************************** + * @file at32f403a_407_clock.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief system clock config program + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* includes ------------------------------------------------------------------*/ +#include "at32f403a_407_clock.h" + +/** + * @brief system clock config program + * @note the system clock is configured as follow: + * - system clock = hext / 2 * pll_mult + * - system clock source = pll (hext) + * - hext = 8000000 + * - sclk = 240000000 + * - ahbdiv = 1 + * - ahbclk = 240000000 + * - apb2div = 2 + * - apb2clk = 120000000 + * - apb1div = 2 + * - apb1clk = 120000000 + * - pll_mult = 60 + * - pll_range = GT72MHZ (greater than 72 mhz) + * @param none + * @retval none + */ +void system_clock_config(void) +{ + /* reset crm */ + crm_reset(); + + #if F_PLL_CLOCK_SOURCE != 0 + crm_clock_source_enable(CRM_CLOCK_SOURCE_HEXT, TRUE); + + /* wait till hext is ready */ + while(crm_hext_stable_wait() == ERROR) + { + } + #endif + + /* config pll clock resource */ + crm_pll_config(F_PLL_CLOCK_SOURCE, F_PLL_MULT, F_PLL_OUTPUT_RANGE); + + #if F_PLL_CLOCK_SOURCE == 2 + /* config hext division */ + crm_hext_clock_div_set(F_HEXT_DIV); + #elif F_PLL_CLOCK_SOURCE == 1 + crm_hick_divider_select(F_HSI_DIV); + #endif + + /* enable pll */ + crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE); + + /* wait till pll is ready */ + while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET) + { + } + + /* config ahbclk */ + crm_ahb_div_set(CRM_AHB_DIV_1); + + /* config apb2clk */ + crm_apb2_div_set(CRM_APB2_DIV_2); + + /* config apb1clk */ + crm_apb1_div_set(CRM_APB1_DIV_2); + + /* enable auto step mode */ + crm_auto_step_mode_enable(TRUE); + + /* select pll as system clock source */ + crm_sysclk_switch(CRM_SCLK_PLL); + + /* wait till pll is used as system clock source */ + while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL) + { + } + + /* disable auto step mode */ + crm_auto_step_mode_enable(FALSE); + + /* update system_core_clock global variable */ + system_core_clock_update(); +} diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/at32f403a_407_clock.h b/ArduinoCore-AT32F403A/cores/arduino/libcore/at32f403a_407_clock.h new file mode 100644 index 0000000..5f44bc4 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/at32f403a_407_clock.h @@ -0,0 +1,46 @@ +/** + ************************************************************************** + * @file at32f403a_407_clock.h + * @version v2.0.9 + * @date 2022-04-25 + * @brief header file of clock program + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_CLOCK_H +#define __AT32F403A_407_CLOCK_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* includes ------------------------------------------------------------------*/ +#include "at32f403a_407.h" + +/* exported functions ------------------------------------------------------- */ +void system_clock_config(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __AT32F403A_407_CLOCK_H */ + diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/config/mcu_config.h b/ArduinoCore-AT32F403A/cores/arduino/libcore/config/mcu_config.h new file mode 100644 index 0000000..e0e5d49 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/config/mcu_config.h @@ -0,0 +1,112 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __MCU_CONFIG_H +#define __MCU_CONFIG_H + +/*========================= + MCU configuration + *=========================*/ +/* System tick */ +#define SYSTICK_TICK_FREQ 1000 // Hz +#define SYSTICK_PRIORITY 0 + +/* Hardware Serial */ +#define SERIAL_RX_BUFFER_SIZE 128 +#define SERIAL_PREEMPTIONPRIORITY_DEFAULT 1 +#define SERIAL_SUBPRIORITY_DEFAULT 3 +#define SERIAL_CONFIG_DEFAULT SERIAL_8N1 + +#define SERIAL_1_ENABLE 1 +#if SERIAL_1_ENABLE +# define SERIAL_1_USART USART1 +# define SERIAL_1_IRQ_HANDLER_DEF() void USART1_IRQHandler(void) +#endif + +#define SERIAL_2_ENABLE 1 +#if SERIAL_2_ENABLE +# define SERIAL_2_USART USART2 +# define SERIAL_2_IRQ_HANDLER_DEF() void USART2_IRQHandler(void) +#endif + +#define SERIAL_3_ENABLE 1 +#if SERIAL_3_ENABLE +# define SERIAL_3_USART USART3 +# define SERIAL_3_IRQ_HANDLER_DEF() void USART3_IRQHandler(void) +#endif + +/* Wire (Software I2C) */ +#define WIRE_USE_FULL_SPEED_I2C 0 +#define WIRE_SDA_PIN PB7 +#define WIRE_SCL_PIN PB6 +#define WIRE_DELAY 0 +#define WIRE_BEGIN_TIMEOUT 100 // ms +#define WIRE_BUFF_SIZE 32 + +/* SPI Class */ +#define SPI_CLASS_AVR_COMPATIBILITY_MODE 1 +#define SPI_CLASS_PIN_DEFINE_ENABLE 1 + +#define SPI_CLASS_1_ENABLE 1 +#if SPI_CLASS_1_ENABLE +# define SPI_CLASS_1_SPI SPI1 +#endif + +#define SPI_CLASS_2_ENABLE 1 +#if SPI_CLASS_2_ENABLE +# define SPI_CLASS_2_SPI SPI2 +#endif + +#define SPI_CLASS_3_ENABLE 1 +#if SPI_CLASS_3_ENABLE +# define SPI_CLASS_3_SPI SPI3 +#endif + +/* WString */ +#define WSTRING_MEM_INCLUDE +#define WSTRING_MEM_REALLOC realloc +#define WSTRING_MEM_FREE free + +/* Print */ +#define PRINT_PRINTF_BUFFER_LENGTH 128 + +/* GPIO */ +#define GPIO_DRIVE_DEFAULT GPIO_DRIVE_STRENGTH_STRONGER + +/* External Interrupt */ +#define EXTI_PREEMPTIONPRIORITY_DEFAULT 2 +#define EXTI_SUBPRIORITY_DEFAULT 1 + +/* Timer Interrupt */ +#define TIMER_PREEMPTIONPRIORITY_DEFAULT 0 +#define TIMER_SUBPRIORITY_DEFAULT 3 + +/* Tone */ +#define TONE_TIMER_DEFAULT TIM1 +#define TONE_PREEMPTIONPRIORITY_DEFAULT 0 +#define TONE_SUBPRIORITY_DEFAULT 1 + +/* PWM */ +#define PWM_RESOLUTION_DEFAULT 1000 +#define PWM_FREQUENCY_DEFAULT 10000 + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/delay.c b/ArduinoCore-AT32F403A/cores/arduino/libcore/delay.c new file mode 100644 index 0000000..1a3146f --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/delay.c @@ -0,0 +1,121 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "delay.h" + +#ifndef SYSTICK_TICK_FREQ +# define SYSTICK_TICK_FREQ 1000 // Hz +#endif + +#define SYSTICK_TICK_INTERVAL (1000 / SYSTICK_TICK_FREQ) +#define SYSTICK_LOAD_VALUE (system_core_clock / SYSTICK_TICK_FREQ) +#define SYSTICK_MILLIS (SystemTickCount * SYSTICK_TICK_INTERVAL) + +static volatile uint32_t SystemTickCount = 0; + +/** + * @brief 系统滴答定时器初始化,定时1ms + * @param 无 + * @retval 无 + */ +void Delay_Init(void) +{ + system_core_clock_update(); + SysTick_Config(SYSTICK_LOAD_VALUE); + NVIC_SetPriority(SysTick_IRQn, SYSTICK_PRIORITY); +} + +/** + * @brief 系统滴答定时器中断入口 + * @param 无 + * @retval 无 + */ +void SysTick_Handler(void) +{ + SystemTickCount++; +} + +/** + * @brief 获取单片机自上电以来经过的毫秒数 + * @param 无 + * @retval 当前系统时钟毫秒数 + */ +uint32_t millis(void) +{ + return SYSTICK_MILLIS; +} + +/** + * @brief 获取单片机自上电以来经过的微秒数 + * @param 无 + * @retval 当前系统时钟微秒数 + */ +uint32_t micros(void) +{ + return (SYSTICK_MILLIS * 1000 + (SYSTICK_LOAD_VALUE - SysTick->VAL) / CYCLES_PER_MICROSECOND); +} + +/** + * @brief 毫秒级延时 + * @param ms: 要延时的毫秒数 + * @retval 无 + */ +void delay_ms(uint32_t ms) +{ + uint32_t tickstart = SystemTickCount; + uint32_t wait = ms / SYSTICK_TICK_INTERVAL; + + while((SystemTickCount - tickstart) < wait) + { + } +} + +/** + * @brief 微秒级延时 + * @param us: 要延时的微秒数 + * @retval 无 + */ +void delay_us(uint32_t us) +{ + uint32_t total = 0; + uint32_t target = CYCLES_PER_MICROSECOND * us; + int last = SysTick->VAL; + int now = last; + int diff = 0; +start: + now = SysTick->VAL; + diff = last - now; + if(diff > 0) + { + total += diff; + } + else + { + total += diff + SYSTICK_LOAD_VALUE; + } + if(total > target) + { + return; + } + last = now; + goto start; +} diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/delay.h b/ArduinoCore-AT32F403A/cores/arduino/libcore/delay.h new file mode 100644 index 0000000..719fdf9 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/delay.h @@ -0,0 +1,42 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DELAY_H +#define __DELAY_H + +#include "mcu_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void Delay_Init(void); +uint32_t millis(void); +uint32_t micros(void); +void delay_ms(uint32_t ms); +void delay_us(uint32_t us); + +#ifdef __cplusplus +} +#endif + +#endif /* __DELAY_H */ diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/extend_SRAM.c b/ArduinoCore-AT32F403A/cores/arduino/libcore/extend_SRAM.c new file mode 100644 index 0000000..4065073 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/extend_SRAM.c @@ -0,0 +1,103 @@ +/** + ****************************************************************************** + * File : SRAM/extend_SRAM/EXTEND_SRAM/extend_SRAM.c + * Version: V1.2.7 + * Date : 2020-11-10 + * Brief : This file contains the function extend_SRAM_test used to extend SRAM size + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "extend_SRAM.h" +#include "at32f403a_407.h" + +#define EXTEND_SRAM_224K + +/* Copy to Startup file */ +#if 0 +; Reset handler +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT __main + IMPORT SystemInit + IMPORT extend_SRAM + + MOV32 R0, #0x20001000 + MOV SP, R0 + LDR R0, =extend_SRAM + BLX R0 + MOV32 R0, #0x08000000 + LDR SP, [R0] + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP +#endif + +/** @addtogroup AT32F403A_StdPeriph_Examples + * @{ + */ + + /** @addtogroup SRAM_Extended_SRAM + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ + +#define TEST_RAM_SIZE 0x800 + +/* Private variables ---------------------------------------------------------*/ + + + +/* Private functions ---------------------------------------------------------*/ +/** + * @brief To extend SRAM size + * @param None + * @retval None + */ +void extend_sram(void) +{ +/* Target set_SRAM_96K is selected */ +#ifdef EXTEND_SRAM_96K +/* check if RAM has been set to 96K, if not, change EOPB0 */ + if(((UOPTB->EOPB0)&0xFF)!=0xFF) + { + /* Unlock Option Bytes Program Erase controller */ + FLASH_Unlock(); + /* Erase Option Bytes */ + FLASH_EraseUserOptionBytes(); + /* Change SRAM size to 96KB */ + FLASH_ProgramUserOptionByteData((uint32_t)&UOPTB->EOPB0,0xFF); + NVIC_SystemReset(); + } +#endif + +/* Target set_SRAM_224K is selected */ +#ifdef EXTEND_SRAM_224K + /* check if ram has been set to expectant size, if not, change eopb0 */ + if(((USD->eopb0) & 0xFF) != 0xFE) + { + flash_unlock(); + /* erase user system data bytes */ + flash_user_system_data_erase(); + + /* change sram size */ + flash_user_system_data_program((uint32_t)&USD->eopb0, 0xFE); + + /* system reset */ + nvic_system_reset(); + } +#endif +} + +/** + * @} + */ + +/** + * @} + */ + diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/extend_SRAM.h b/ArduinoCore-AT32F403A/cores/arduino/libcore/extend_SRAM.h new file mode 100644 index 0000000..4f2b60f --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/extend_SRAM.h @@ -0,0 +1,18 @@ +/** + ****************************************************************************** + * File : SRAM/extend_SRAM/EXTEND_SRAM/extend_SRAM.h + * Version: V1.2.7 + * Date : 2020-11-10 + * Brief : This file contains all the macros used in extend_SRAM.c + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __EXTEND_SRAM_H +#define __EXTEND_SRAM_H + +/* Exported functions ------------------------------------------------------- */ +void extend_sram(void); + +#endif /* __EXTEND_SRAM_H */ + diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/exti.c b/ArduinoCore-AT32F403A/cores/arduino/libcore/exti.c new file mode 100644 index 0000000..b8fc58f --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/exti.c @@ -0,0 +1,235 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "exti.h" +#include "gpio.h" + +#define EXTI_GetPortSourceGPIOx(Pin) GPIO_GetPortNum(Pin) +#define EXTI_GetPinSourcex(Pin) GPIO_GetPinNum(Pin) + +static EXTI_CallbackFunction_t EXTI_Function[16] = {0}; + +/** + * @brief 获取外部中断的中断通道 + * @param Pin: 引脚编号 + * @retval 通道编号 + */ +static IRQn_Type EXTI_GetIRQn(uint8_t Pin) +{ + IRQn_Type EXINTx_IRQn = EXINT0_IRQn; + uint8_t Pinx = GPIO_GetPinNum(Pin); + + if(Pinx <= 4) + { + switch(Pinx) + { + case 0: + EXINTx_IRQn = EXINT0_IRQn; + break; + case 1: + EXINTx_IRQn = EXINT1_IRQn; + break; + case 2: + EXINTx_IRQn = EXINT2_IRQn; + break; + case 3: + EXINTx_IRQn = EXINT3_IRQn; + break; + case 4: + EXINTx_IRQn = EXINT4_IRQn; + break; + } + } + else if(Pinx >= 5 && Pinx <= 9) + { + EXINTx_IRQn = EXINT9_5_IRQn; + } + else if(Pinx >= 10 && Pinx <= 15) + { + EXINTx_IRQn = EXINT15_10_IRQn; + } + + return EXINTx_IRQn; +} + +/** + * @brief 外部中断初始化 + * @param Pin: 引脚编号 + * @param Function: 回调函数 + * @param Trigger_Mode: 触发方式 + * @param PreemptionPriority: 抢占优先级 + * @param SubPriority: 子优先级 + * @retval 无 + */ +void EXTIx_Init( + uint8_t Pin, + EXTI_CallbackFunction_t Function, + exint_polarity_config_type line_polarity, + uint8_t PreemptionPriority, + uint8_t SubPriority +) +{ + exint_init_type exint_init_struct; + uint8_t Pinx; + + if(!IS_PIN(Pin)) + return; + + Pinx = GPIO_GetPinNum(Pin); + + if(Pinx > 15) + return; + + EXTI_Function[Pinx] = Function; + + crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE); + + gpio_exint_line_config(GPIO_GetPortNum(Pin), (gpio_pins_source_type)Pinx); + exint_default_para_init(&exint_init_struct); + exint_init_struct.line_select = 1 << Pinx; + exint_init_struct.line_mode = EXINT_LINE_INTERRUPUT; + exint_init_struct.line_polarity = line_polarity; + exint_init_struct.line_enable = TRUE; + exint_init(&exint_init_struct); + + nvic_irq_enable(EXTI_GetIRQn(Pin), PreemptionPriority, SubPriority); + +} + +/** + * @brief 外部中断初始化 (Arduino) + * @param Pin: 引脚编号 + * @param function: 回调函数 + * @param Trigger_Mode: 触发方式 + * @retval 无 + */ +void attachInterrupt(uint8_t Pin, EXTI_CallbackFunction_t Function, exint_polarity_config_type line_polarity) +{ + EXTIx_Init( + Pin, + Function, + line_polarity, + EXTI_PREEMPTIONPRIORITY_DEFAULT, + EXTI_SUBPRIORITY_DEFAULT + ); +} + +/** + * @brief 关闭给定的中断 (Arduino) + * @param Pin: 引脚编号 + * @retval 无 + */ +void detachInterrupt(uint8_t Pin) +{ + if(!IS_PIN(Pin)) + return; + + nvic_irq_disable(EXTI_GetIRQn(Pin)); +} + +#define EXTIx_IRQHANDLER(n) \ +do{\ + if(exint_flag_get(EXINT_LINE_##n) != RESET)\ + {\ + if(EXTI_Function[n]) EXTI_Function[n]();\ + exint_flag_clear(EXINT_LINE_##n);\ + }\ +}while(0) + +/** + * @brief 外部中断入口,通道0 + * @param 无 + * @retval 无 + */ +void EXTI0_IRQHandler(void) +{ + EXTIx_IRQHANDLER(0); +} + +/** + * @brief 外部中断入口,通道1 + * @param 无 + * @retval 无 + */ +void EXTI1_IRQHandler(void) +{ + EXTIx_IRQHANDLER(1); +} + +/** + * @brief 外部中断入口,通道2 + * @param 无 + * @retval 无 + */ +void EXTI2_IRQHandler(void) +{ + EXTIx_IRQHANDLER(2); +} + +/** + * @brief 外部中断入口,通道3 + * @param 无 + * @retval 无 + */ +void EXTI3_IRQHandler(void) +{ + EXTIx_IRQHANDLER(3); +} + +/** + * @brief 外部中断入口,通道4 + * @param 无 + * @retval 无 + */ +void EXTI4_IRQHandler(void) +{ + EXTIx_IRQHANDLER(4); +} + +/** + * @brief 外部中断入口,通道9~5 + * @param 无 + * @retval 无 + */ +void EXTI9_5_IRQHandler(void) +{ + EXTIx_IRQHANDLER(5); + EXTIx_IRQHANDLER(6); + EXTIx_IRQHANDLER(7); + EXTIx_IRQHANDLER(8); + EXTIx_IRQHANDLER(9); +} + +/** + * @brief 外部中断入口,通道15~10 + * @param 无 + * @retval 无 + */ +void EXTI15_10_IRQHandler(void) +{ + EXTIx_IRQHANDLER(10); + EXTIx_IRQHANDLER(11); + EXTIx_IRQHANDLER(12); + EXTIx_IRQHANDLER(13); + EXTIx_IRQHANDLER(14); + EXTIx_IRQHANDLER(15); +} diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/exti.h b/ArduinoCore-AT32F403A/cores/arduino/libcore/exti.h new file mode 100644 index 0000000..a188869 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/exti.h @@ -0,0 +1,56 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __EXTI_H +#define __EXTI_H + +#include "mcu_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CHANGE EXINT_TRIGGER_BOTH_EDGE +#define FALLING EXINT_TRIGGER_FALLING_EDGE +#define RISING EXINT_TRIGGER_RISING_EDGE + +typedef void(*EXTI_CallbackFunction_t)(void); + +void EXTIx_Init( + uint8_t Pin, + EXTI_CallbackFunction_t Function, + exint_polarity_config_type line_polarity, + uint8_t PreemptionPriority, + uint8_t SubPriority +); +void attachInterrupt( + uint8_t Pin, + EXTI_CallbackFunction_t Function, + exint_polarity_config_type polarity_config +); +void detachInterrupt(uint8_t Pin); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/gpio.c b/ArduinoCore-AT32F403A/cores/arduino/libcore/gpio.c new file mode 100644 index 0000000..156d9ab --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/gpio.c @@ -0,0 +1,341 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "gpio.h" + +const PinInfo_TypeDef PIN_MAP[PIN_MAX] = +{ + /*GPIO_Type* GPIOx; //对应GPIOx地址 + TIM_Type* TIMx; //对应TIMx地址 + ADC_Type* ADCx; //对应ADCx地址 + + uint16_t GPIO_Pin_x; //对应GPIO_Pin位 + uint8_t TimerChannel; //对应定时器通道 + uint8_t ADC_CHANNEL;*/ //对应ADC通道 + {GPIOA, TIM2, ADC1, GPIO_Pin_0, 1, ADC_CHANNEL_0}, /* PA0 */ + {GPIOA, TIM2, ADC1, GPIO_Pin_1, 2, ADC_CHANNEL_1}, /* PA1 */ + {GPIOA, TIM2, ADC1, GPIO_Pin_2, 3, ADC_CHANNEL_2}, /* PA2 */ + {GPIOA, TIM2, ADC1, GPIO_Pin_3, 4, ADC_CHANNEL_3}, /* PA3 */ + {GPIOA, NULL, ADC1, GPIO_Pin_4, 0, ADC_CHANNEL_4}, /* PA4 */ + {GPIOA, NULL, ADC1, GPIO_Pin_5, 0, ADC_CHANNEL_5}, /* PA5 */ + {GPIOA, TIM3, ADC1, GPIO_Pin_6, 1, ADC_CHANNEL_6}, /* PA6 */ + {GPIOA, TIM3, ADC1, GPIO_Pin_7, 2, ADC_CHANNEL_7}, /* PA7 */ + {GPIOA, TIM1, NULL, GPIO_Pin_8, 1, ADC_CHANNEL_X}, /* PA8 */ + {GPIOA, TIM1, NULL, GPIO_Pin_9, 2, ADC_CHANNEL_X}, /* PA9 */ + {GPIOA, TIM1, NULL, GPIO_Pin_10, 3, ADC_CHANNEL_X}, /* PA10 */ + {GPIOA, TIM1, NULL, GPIO_Pin_11, 4, ADC_CHANNEL_X}, /* PA11 */ + {GPIOA, NULL, NULL, GPIO_Pin_12, 0, ADC_CHANNEL_X}, /* PA12 */ + {GPIOA, NULL, NULL, GPIO_Pin_13, 0, ADC_CHANNEL_X}, /* PA13 */ + {GPIOA, NULL, NULL, GPIO_Pin_14, 0, ADC_CHANNEL_X}, /* PA14 */ + {GPIOA, TIM2, NULL, GPIO_Pin_15, 1, ADC_CHANNEL_X}, /* PA15 */ + + {GPIOB, TIM3, ADC1, GPIO_Pin_0, 3, ADC_CHANNEL_8}, /* PB0 */ + {GPIOB, TIM3, ADC1, GPIO_Pin_1, 4, ADC_CHANNEL_9}, /* PB1 */ + {GPIOB, NULL, NULL, GPIO_Pin_2, 0, ADC_CHANNEL_X}, /* PB2 */ + {GPIOB, TIM2, NULL, GPIO_Pin_3, 2, ADC_CHANNEL_X}, /* PB3 */ + {GPIOB, TIM3, NULL, GPIO_Pin_4, 1, ADC_CHANNEL_X}, /* PB4 */ + {GPIOB, TIM3, NULL, GPIO_Pin_5, 2, ADC_CHANNEL_X}, /* PB5 */ + {GPIOB, TIM4, NULL, GPIO_Pin_6, 1, ADC_CHANNEL_X}, /* PB6 */ + {GPIOB, TIM4, NULL, GPIO_Pin_7, 2, ADC_CHANNEL_X}, /* PB7 */ + {GPIOB, TIM4, NULL, GPIO_Pin_8, 3, ADC_CHANNEL_X}, /* PB8 */ + {GPIOB, TIM4, NULL, GPIO_Pin_9, 4, ADC_CHANNEL_X}, /* PB9 */ + {GPIOB, TIM2, NULL, GPIO_Pin_10, 3, ADC_CHANNEL_X}, /* PB10 */ + {GPIOB, TIM2, NULL, GPIO_Pin_11, 4, ADC_CHANNEL_X}, /* PB11 */ + {GPIOB, NULL, NULL, GPIO_Pin_12, 0, ADC_CHANNEL_X}, /* PB12 */ + {GPIOB, NULL, NULL, GPIO_Pin_13, 0, ADC_CHANNEL_X}, /* PB13 */ +#ifdef TMR12 + {GPIOB, TIM12, NULL, GPIO_Pin_14, 1, ADC_CHANNEL_X},/* PB14 */ +#else + {GPIOB, NULL, NULL, GPIO_Pin_14, 0, ADC_Channel_X},/* PB14 */ +#endif /*TMR12*/ + {GPIOB, NULL, NULL, GPIO_Pin_15, 0, ADC_CHANNEL_X}, /* PB15 */ + + {GPIOC, NULL, ADC1, GPIO_Pin_0, 0, ADC_CHANNEL_10},/* PC0 */ + {GPIOC, NULL, ADC1, GPIO_Pin_1, 0, ADC_CHANNEL_11},/* PC1 */ + {GPIOC, NULL, ADC1, GPIO_Pin_2, 0, ADC_CHANNEL_12},/* PC2 */ + {GPIOC, NULL, ADC1, GPIO_Pin_3, 0, ADC_CHANNEL_13},/* PC3 */ + {GPIOC, NULL, ADC1, GPIO_Pin_4, 0, ADC_CHANNEL_14},/* PC4 */ + {GPIOC, NULL, ADC1, GPIO_Pin_5, 0, ADC_CHANNEL_15},/* PC5 */ + {GPIOC, TIM3, NULL, GPIO_Pin_6, 1, ADC_CHANNEL_X}, /* PC6 */ + {GPIOC, TIM3, NULL, GPIO_Pin_7, 2, ADC_CHANNEL_X}, /* PC7 */ + {GPIOC, TIM3, NULL, GPIO_Pin_8, 3, ADC_CHANNEL_X}, /* PC8 */ + {GPIOC, TIM3, NULL, GPIO_Pin_9, 4, ADC_CHANNEL_X}, /* PC9 */ + {GPIOC, NULL, NULL, GPIO_Pin_10, 0, ADC_CHANNEL_X}, /* PC10 */ + {GPIOC, NULL, NULL, GPIO_Pin_11, 0, ADC_CHANNEL_X}, /* PC11 */ + {GPIOC, NULL, NULL, GPIO_Pin_12, 0, ADC_CHANNEL_X}, /* PC12 */ + {GPIOC, NULL, NULL, GPIO_Pin_13, 0, ADC_CHANNEL_X}, /* PC13 */ + {GPIOC, NULL, NULL, GPIO_Pin_14, 0, ADC_CHANNEL_X}, /* PC14 */ + {GPIOC, NULL, NULL, GPIO_Pin_15, 0, ADC_CHANNEL_X}, /* PC15 */ + + {GPIOD, NULL, NULL, GPIO_Pin_0, 0, ADC_CHANNEL_X}, /* PD0 */ + {GPIOD, NULL, NULL, GPIO_Pin_1, 0, ADC_CHANNEL_X}, /* PD1 */ + {GPIOD, NULL, NULL, GPIO_Pin_2, 0, ADC_CHANNEL_X}, /* PD2 */ + {GPIOD, NULL, NULL, GPIO_Pin_3, 0, ADC_CHANNEL_X}, /* PD3 */ + {GPIOD, NULL, NULL, GPIO_Pin_4, 0, ADC_CHANNEL_X}, /* PD4 */ + {GPIOD, NULL, NULL, GPIO_Pin_5, 0, ADC_CHANNEL_X}, /* PD5 */ + {GPIOD, NULL, NULL, GPIO_Pin_6, 0, ADC_CHANNEL_X}, /* PD6 */ + {GPIOD, NULL, NULL, GPIO_Pin_7, 0, ADC_CHANNEL_X}, /* PD7 */ + {GPIOD, NULL, NULL, GPIO_Pin_8, 0, ADC_CHANNEL_X}, /* PD8 */ + {GPIOD, NULL, NULL, GPIO_Pin_9, 0, ADC_CHANNEL_X}, /* PD9 */ + {GPIOD, NULL, NULL, GPIO_Pin_10, 0, ADC_CHANNEL_X}, /* PD10 */ + {GPIOD, NULL, NULL, GPIO_Pin_11, 0, ADC_CHANNEL_X}, /* PD11 */ + {GPIOD, TIM4, NULL, GPIO_Pin_12, 1, ADC_CHANNEL_X}, /* PD12 */ + {GPIOD, TIM4, NULL, GPIO_Pin_13, 2, ADC_CHANNEL_X}, /* PD13 */ + {GPIOD, TIM4, NULL, GPIO_Pin_14, 3, ADC_CHANNEL_X}, /* PD14 */ + {GPIOD, TIM4, NULL, GPIO_Pin_15, 4, ADC_CHANNEL_X}, /* PD15 */ + +#ifdef GPIOE + {GPIOE, NULL, NULL, GPIO_Pin_0, 0, ADC_CHANNEL_X}, /* PE0 */ + {GPIOE, NULL, NULL, GPIO_Pin_1, 0, ADC_CHANNEL_X}, /* PE1 */ + {GPIOE, NULL, NULL, GPIO_Pin_2, 0, ADC_CHANNEL_X}, /* PE2 */ + {GPIOE, NULL, NULL, GPIO_Pin_3, 0, ADC_CHANNEL_X}, /* PE3 */ + {GPIOE, NULL, NULL, GPIO_Pin_4, 0, ADC_CHANNEL_X}, /* PE4 */ + {GPIOE, TIM9, NULL, GPIO_Pin_5, 1, ADC_CHANNEL_X}, /* PE5 */ + {GPIOE, TIM9, NULL, GPIO_Pin_6, 2, ADC_CHANNEL_X}, /* PE6 */ + {GPIOE, NULL, NULL, GPIO_Pin_7, 0, ADC_CHANNEL_X}, /* PE7 */ + {GPIOE, NULL, NULL, GPIO_Pin_8, 0, ADC_CHANNEL_X}, /* PE8 */ + {GPIOE, TIM1, NULL, GPIO_Pin_9, 1, ADC_CHANNEL_X}, /* PE9 */ + {GPIOE, NULL, NULL, GPIO_Pin_10, 0, ADC_CHANNEL_X}, /* PE10 */ + {GPIOE, TIM1, NULL, GPIO_Pin_11, 2, ADC_CHANNEL_X}, /* PE11 */ + {GPIOE, NULL, NULL, GPIO_Pin_12, 0, ADC_CHANNEL_X}, /* PE12 */ + {GPIOE, TIM1, NULL, GPIO_Pin_13, 3, ADC_CHANNEL_X}, /* PE13 */ + {GPIOE, TIM1, NULL, GPIO_Pin_14, 4, ADC_CHANNEL_X}, /* PE14 */ + {GPIOE, NULL, NULL, GPIO_Pin_15, 0, ADC_CHANNEL_X}, /* PE15 */ +#endif /*GPIOE*/ + +#ifdef GPIOF + {GPIOF, NULL, NULL, GPIO_Pin_0, 0, ADC_CHANNEL_X}, /* PF0 */ + {GPIOF, NULL, NULL, GPIO_Pin_1, 0, ADC_CHANNEL_X}, /* PF1 */ + {GPIOF, NULL, NULL, GPIO_Pin_2, 0, ADC_CHANNEL_X}, /* PF2 */ + +#ifdef ADC3 + {GPIOF, NULL, ADC3, GPIO_Pin_3, 0, ADC_CHANNEL_9}, /* PF3 */ + {GPIOF, NULL, ADC3, GPIO_Pin_4, 0, ADC_CHANNEL_14},/* PF4 */ + {GPIOF, NULL, ADC3, GPIO_Pin_5, 0, ADC_CHANNEL_15},/* PF5 */ + {GPIOF, TIM10, ADC3, GPIO_Pin_6, 1, ADC_CHANNEL_4}, /* PF6 */ + {GPIOF, TIM11, ADC3, GPIO_Pin_7, 1, ADC_CHANNEL_5}, /* PF7 */ + {GPIOF, TIM13, ADC3, GPIO_Pin_8, 1, ADC_CHANNEL_6}, /* PF8 */ + {GPIOF, TIM14, ADC3, GPIO_Pin_9, 1, ADC_CHANNEL_7}, /* PF9 */ + {GPIOF, NULL, ADC3, GPIO_Pin_10, 0, ADC_CHANNEL_8}, /* PF10 */ +#else + {GPIOF, NULL, NULL, GPIO_Pin_3, 0, ADC_CHANNEL_X}, /* PF3 */ + {GPIOF, NULL, NULL, GPIO_Pin_4, 0, ADC_CHANNEL_X},/* PF4 */ + {GPIOF, NULL, NULL, GPIO_Pin_5, 0, ADC_CHANNEL_X},/* PF5 */ + {GPIOF, TIM10, NULL, GPIO_Pin_6, 1, ADC_CHANNEL_X}, /* PF6 */ + {GPIOF, TIM11, NULL, GPIO_Pin_7, 1, ADC_CHANNEL_X}, /* PF7 */ + {GPIOF, NULL, NULL, GPIO_Pin_8, 0, ADC_CHANNEL_X}, /* PF8 */ + {GPIOF, NULL, NULL, GPIO_Pin_9, 0, ADC_CHANNEL_X}, /* PF9 */ + {GPIOF, NULL, NULL, GPIO_Pin_10, 0, ADC_CHANNEL_X}, /* PF10 */ +#endif /*ADC3*/ + {GPIOF, NULL, NULL, GPIO_Pin_11, 0, ADC_CHANNEL_X}, /* PF11 */ + {GPIOF, NULL, NULL, GPIO_Pin_12, 0, ADC_CHANNEL_X}, /* PF12 */ + {GPIOF, NULL, NULL, GPIO_Pin_13, 0, ADC_CHANNEL_X}, /* PF13 */ + {GPIOF, NULL, NULL, GPIO_Pin_14, 0, ADC_CHANNEL_X}, /* PF14 */ + {GPIOF, NULL, NULL, GPIO_Pin_15, 0, ADC_CHANNEL_X}, /* PF15 */ +#endif /*GPIOF*/ + +#ifdef GPIOG + {GPIOG, NULL, NULL, GPIO_Pin_0, 0, ADC_CHANNEL_X}, /* PG0 */ + {GPIOG, NULL, NULL, GPIO_Pin_1, 0, ADC_CHANNEL_X}, /* PG1 */ + {GPIOG, NULL, NULL, GPIO_Pin_2, 0, ADC_CHANNEL_X}, /* PG2 */ + {GPIOG, NULL, NULL, GPIO_Pin_3, 0, ADC_CHANNEL_X}, /* PG3 */ + {GPIOG, NULL, NULL, GPIO_Pin_4, 0, ADC_CHANNEL_X}, /* PG4 */ + {GPIOG, NULL, NULL, GPIO_Pin_5, 0, ADC_CHANNEL_X}, /* PG5 */ + {GPIOG, NULL, NULL, GPIO_Pin_6, 0, ADC_CHANNEL_X}, /* PG6 */ + {GPIOG, NULL, NULL, GPIO_Pin_7, 0, ADC_CHANNEL_X}, /* PG7 */ + {GPIOG, NULL, NULL, GPIO_Pin_8, 0, ADC_CHANNEL_X}, /* PG8 */ + {GPIOG, NULL, NULL, GPIO_Pin_9, 0, ADC_CHANNEL_X}, /* PG9 */ + {GPIOG, NULL, NULL, GPIO_Pin_10, 0, ADC_CHANNEL_X}, /* PG10 */ + {GPIOG, NULL, NULL, GPIO_Pin_11, 0, ADC_CHANNEL_X}, /* PG11 */ + {GPIOG, NULL, NULL, GPIO_Pin_12, 0, ADC_CHANNEL_X}, /* PG12 */ + {GPIOG, NULL, NULL, GPIO_Pin_13, 0, ADC_CHANNEL_X}, /* PG13 */ + {GPIOG, NULL, NULL, GPIO_Pin_14, 0, ADC_CHANNEL_X}, /* PG14 */ + {GPIOG, NULL, NULL, GPIO_Pin_15, 0, ADC_CHANNEL_X}, /* PG15 */ +#endif /*GPIOG*/ +}; + +/** + * @brief GPIO初始化 + * @param GPIOx: GPIO地址 + * @param GPIO_Pin_x: GPIO对应位 + * @param GPIO_Mode_x: GPIO模式 + * @param GPIO_Speed_x: GPIO速度 + * @retval 无 + */ +void GPIOx_Init( + gpio_type* GPIOx, + uint16_t GPIO_Pin_x, + PinMode_TypeDef Mode, + gpio_drive_type GPIO_Drive_x +) +{ + gpio_init_type gpio_init_struct; + crm_periph_clock_type CRM_GPIOx_PERIPH_CLOCK; + + if(GPIOx == GPIOA) CRM_GPIOx_PERIPH_CLOCK = CRM_GPIOA_PERIPH_CLOCK; + else if(GPIOx == GPIOB)CRM_GPIOx_PERIPH_CLOCK = CRM_GPIOB_PERIPH_CLOCK; + else if(GPIOx == GPIOC)CRM_GPIOx_PERIPH_CLOCK = CRM_GPIOC_PERIPH_CLOCK; + else if(GPIOx == GPIOD)CRM_GPIOx_PERIPH_CLOCK = CRM_GPIOD_PERIPH_CLOCK; +#ifdef GPIOE + else if(GPIOx == GPIOE)CRM_GPIOx_PERIPH_CLOCK = CRM_GPIOE_PERIPH_CLOCK; +#endif /*GPIOE*/ +#ifdef GPIOF + else if(GPIOx == GPIOF)CRM_GPIOx_PERIPH_CLOCK = CRM_GPIOF_PERIPH_CLOCK; +#endif /*GPIOF*/ +#ifdef GPIOG + else if(GPIOx == GPIOG)CRM_GPIOx_PERIPH_CLOCK = CRM_GPIOG_PERIPH_CLOCK; +#endif /*GPIOG*/ + else return; + + gpio_default_para_init(&gpio_init_struct); + gpio_init_struct.gpio_pins = GPIO_Pin_x; + gpio_init_struct.gpio_drive_strength = GPIO_Drive_x; + + if(Mode == INPUT) + { + gpio_init_struct.gpio_mode = GPIO_MODE_INPUT; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + } + else if(Mode == INPUT_PULLUP) + { + gpio_init_struct.gpio_mode = GPIO_MODE_INPUT; + gpio_init_struct.gpio_pull = GPIO_PULL_UP; + } + else if(Mode == INPUT_PULLDOWN) + { + gpio_init_struct.gpio_mode = GPIO_MODE_INPUT; + gpio_init_struct.gpio_pull = GPIO_PULL_DOWN; + } + else if(Mode == INPUT_ANALOG) + { + gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + } + else if(Mode == OUTPUT) + { + gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + } + else if(Mode == OUTPUT_OPEN_DRAIN) + { + gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN; + } + else if(Mode == OUTPUT_AF_PP) + { + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + } + else if(Mode == OUTPUT_AF_OD) + { + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN; + } + else + { + return; + } + + crm_periph_clock_enable(CRM_GPIOx_PERIPH_CLOCK, TRUE); + gpio_init(GPIOx, &gpio_init_struct); +} + +/** + * @brief 禁用JTAG引脚 + * @param 无 + * @retval 无 + */ +void GPIO_JTAG_Disable(void) +{ +// RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_AFIO, ENABLE); +// GPIO_PinsRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); +} + +/** + * @brief 获取当前引脚对应的GPIOx编号 + * @param Pin: 引脚编号 + * @retval 无 + */ +uint8_t GPIO_GetPortNum(uint8_t Pin) +{ + uint8_t retval = 0xFF; + uint8_t index; + gpio_type* GPIOx = PIN_MAP[Pin].GPIOx; + + gpio_type* GPIO_Map[] = + { + GPIOA, + GPIOB, + GPIOC, + GPIOD, +#ifdef GPIOE + GPIOE, +#endif +#ifdef GPIOF + GPIOF, +#endif +#ifdef GPIOG + GPIOG +#endif + }; + + for(index = 0; index < sizeof(GPIO_Map) / sizeof(GPIO_Map[0]); index++) + { + if(GPIOx == GPIO_Map[index]) + { + retval = index; + break; + } + } + + return retval; +} + +/** + * @brief 获取当前引脚对应的 PinSource + * @param GPIO_Pin_x: GPIO对应位 + * @retval 无 + */ +uint8_t GPIO_GetPinSource(uint16_t GPIO_Pin_x) +{ + uint8_t PinSource = 0; + while(GPIO_Pin_x > 1) + { + GPIO_Pin_x >>= 1; + PinSource++; + } + return PinSource; +} + +/** + * @brief 获取当前引脚对应的编号 + * @param Pin: 引脚编号 + * @retval 无 + */ +uint8_t GPIO_GetPinNum(uint8_t Pin) +{ + return GPIO_GetPinSource(PIN_MAP[Pin].GPIO_Pin_x); +} diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/gpio.h b/ArduinoCore-AT32F403A/cores/arduino/libcore/gpio.h new file mode 100644 index 0000000..58b6c22 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/gpio.h @@ -0,0 +1,121 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __GPIO_H +#define __GPIO_H + +#include "mcu_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef NULL +# define NULL ((void*)0) +#endif + +#define ADC_CHANNEL_X ((uint8_t)0xFF) + +#define IS_PIN(Pin) (Pin < PIN_MAX) +#define IS_ADC_PIN(Pin) (IS_PIN(Pin) && PIN_MAP[Pin].ADCx != NULL && PIN_MAP[Pin].ADC_Channel != ADC_CHANNEL_X) +#define IS_PWM_PIN(Pin) (IS_PIN(Pin) && PIN_MAP[Pin].TIMx != NULL && PIN_MAP[Pin].TimerChannel != 0) + +#define GPIO_HIGH(GPIOX,GPIO_PIN_X) ((GPIOX)->scr = (GPIO_PIN_X)) +#define GPIO_LOW(GPIOX,GPIO_PIN_X) ((GPIOX)->clr = (GPIO_PIN_X)) +#define GPIO_READ(GPIOX,GPIO_PIN_X) (((GPIOX)->idt & (GPIO_PIN_X))!=0) +#define GPIO_TOGGLE(GPIOX,GPIO_PIN_X) ((GPIOX)->odt ^= (GPIO_PIN_X)) + +#define portInputRegister(Port) (&(Port->idt)) +#define portOutputRegister(Port) (&(Port->odt)) + +#define analogInPinToBit(Pin) (Pin) +#define digitalPinToInterrupt(Pin) (Pin) +#define digitalPinToPort(Pin) (PIN_MAP[Pin].GPIOx) +#define digitalPinToBitMask(Pin) (PIN_MAP[Pin].GPIO_Pin_x) + +#define digitalWrite_HIGH(Pin) GPIO_HIGH (PIN_MAP[Pin].GPIOx, PIN_MAP[Pin].GPIO_Pin_x) +#define digitalWrite_LOW(Pin) GPIO_LOW (PIN_MAP[Pin].GPIOx, PIN_MAP[Pin].GPIO_Pin_x) +#define digitalRead_FAST(Pin) GPIO_READ (PIN_MAP[Pin].GPIOx, PIN_MAP[Pin].GPIO_Pin_x) +#define togglePin(Pin) GPIO_TOGGLE(PIN_MAP[Pin].GPIOx, PIN_MAP[Pin].GPIO_Pin_x) + +#define LED_BUILTIN PC13 + +typedef enum +{ + PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15, + PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7, PB8, PB9, PB10, PB11, PB12, PB13, PB14, PB15, + PC0, PC1, PC2, PC3, PC4, PC5, PC6, PC7, PC8, PC9, PC10, PC11, PC12, PC13, PC14, PC15, + PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7, PD8, PD9, PD10, PD11, PD12, PD13, PD14, PD15, +#ifdef GPIOE + PE0, PE1, PE2, PE3, PE4, PE5, PE6, PE7, PE8, PE9, PE10, PE11, PE12, PE13, PE14, PE15, +#endif +#ifdef GPIOF + PF0, PF1, PF2, PF3, PF4, PF5, PF6, PF7, PF8, PF9, PF10, PF11, PF12, PF13, PF14, PF15, +#endif +#ifdef GPIOG + PG0, PG1, PG2, PG3, PG4, PG5, PG6, PG7, PG8, PG9, PG10, PG11, PG12, PG13, PG14, PG15, +#endif + PIN_MAX +} Pin_TypeDef; + +typedef struct +{ + gpio_type* GPIOx; + tmr_type* TIMx; + adc_type* ADCx; + uint16_t GPIO_Pin_x; + uint8_t TimerChannel; + uint8_t ADC_Channel; +} PinInfo_TypeDef; + +typedef enum +{ + INPUT, + INPUT_PULLUP, + INPUT_PULLDOWN, + INPUT_ANALOG, + INPUT_ANALOG_DMA, + OUTPUT, + OUTPUT_OPEN_DRAIN, + OUTPUT_AF_OD, + OUTPUT_AF_PP, + PWM +} PinMode_TypeDef; + +extern const PinInfo_TypeDef PIN_MAP[PIN_MAX]; + +void GPIOx_Init( + gpio_type* GPIOx, + uint16_t GPIO_Pin_x, + PinMode_TypeDef Mode, + gpio_drive_type GPIO_Drive_x +); +void GPIO_JTAG_Disable(void); +uint8_t GPIO_GetPortNum(uint8_t Pin); +uint8_t GPIO_GetPinNum(uint8_t Pin); +uint8_t GPIO_GetPinSource(uint16_t GPIO_Pin_x); + +#ifdef __cplusplus +}// extern "C" +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/i2c.c b/ArduinoCore-AT32F403A/cores/arduino/libcore/i2c.c new file mode 100644 index 0000000..44e3e9c --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/i2c.c @@ -0,0 +1,158 @@ +/* + * MIT License + * Copyright (c) 2019 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Arduino.h" +#include "i2c.h" + +void I2Cx_Init(i2c_type *I2Cx, uint32_t baudRate) +{ + if(I2Cx == I2C1) + { + crm_periph_clock_enable(CRM_I2C1_PERIPH_CLOCK, TRUE); + pinMode(PB6, OUTPUT_AF_OD); + pinMode(PB7, OUTPUT_AF_OD); + } +#ifdef CRM_I2C2_PERIPH_CLOCK + else if(I2Cx == I2C2) + { + crm_periph_clock_enable(CRM_I2C2_PERIPH_CLOCK, TRUE); + pinMode(PB10, OUTPUT_AF_OD); + pinMode(PB11, OUTPUT_AF_OD); + } +#endif +#ifdef CRM_I2C3_PERIPH_CLOCK + else if(I2Cx == I2C3) + { + crm_periph_clock_enable(CRM_I2C3_PERIPH_CLOCK, TRUE); + pinMode(PA8, OUTPUT_AF_OD); + pinMode(PC9, OUTPUT_AF_OD); + } +#endif + else + { + return; + } + /* reset i2c peripheral */ + i2c_reset(I2Cx); + /* i2c peripheral initialization */ + i2c_init(I2Cx, I2C_FSMODE_DUTY_2_1, baudRate); + + i2c_own_address1_set(I2Cx, I2C_ADDRESS_MODE_7BIT, 0); + i2c_ack_enable(I2Cx, TRUE); + i2c_master_receive_ack_set(I2Cx, I2C_MASTER_ACK_CURRENT); + /* i2c peripheral enable */ + i2c_enable(I2Cx, TRUE); +} + +void I2Cx_ClearADDRFlag(i2c_type* I2Cx) +{ + __IO uint32_t tmpreg; + + tmpreg = I2Cx->sts1; + + tmpreg = I2Cx->sts2; +} + +void I2Cx_Read(i2c_type *I2Cx, uint8_t slaveAddr, uint8_t regAddr, void *buf, uint32_t length) +{ + uint8_t *dat = (uint8_t *)buf; + + /* enable ack */ + i2c_ack_enable(I2Cx, TRUE); + + /* generate start condtion */ + i2c_start_generate(I2Cx); + + while(!i2c_flag_get(I2Cx, I2C_STARTF_FLAG)); + while(I2Cx->ctrl1 & I2C_CTRL1_STARTGEN); + i2c_7bit_address_send(I2Cx, (slaveAddr << 1), I2C_DIRECTION_TRANSMIT); + while(!i2c_flag_get(I2Cx, I2C_ADDR7F_FLAG)); + I2Cx_ClearADDRFlag(I2Cx); + + i2c_data_send(I2Cx, regAddr); + while(!i2c_flag_get(I2Cx, I2C_TDC_FLAG)); + i2c_flag_clear(I2Cx, I2C_TDC_FLAG); + + i2c_start_generate(I2Cx); + while(!i2c_flag_get(I2Cx, I2C_STARTF_FLAG)); + + i2c_7bit_address_send(I2Cx, (slaveAddr << 1), I2C_DIRECTION_RECEIVE); + while(!i2c_flag_get(I2Cx, I2C_ADDR7F_FLAG)); + I2Cx_ClearADDRFlag(I2Cx); + + while(length --) + { + if(!length) + { + i2c_ack_enable(I2Cx, FALSE); + i2c_stop_generate(I2Cx); + } + while(!i2c_flag_get(I2Cx, I2C_RDBF_FLAG)); + *dat++ = i2c_data_receive(I2Cx); + } + while(I2Cx->ctrl1 & I2C_CTRL1_STOPGEN); +} + +void I2Cx_Write(i2c_type *I2Cx, uint8_t slaveAddr, uint8_t regAddr, void *buf, uint32_t length) +{ + uint8_t *dat = (uint8_t *)buf; + + i2c_start_generate(I2Cx); + while(!i2c_flag_get(I2Cx, I2C_STARTF_FLAG)); + + i2c_7bit_address_send(I2Cx, (slaveAddr << 1), I2C_DIRECTION_TRANSMIT); + while(!i2c_flag_get(I2Cx, I2C_ADDR7F_FLAG)); + I2Cx_ClearADDRFlag(I2Cx); + + i2c_data_send(I2Cx, regAddr); + while(!i2c_flag_get(I2Cx, I2C_TDC_FLAG)); + i2c_flag_clear(I2Cx, I2C_TDC_FLAG); + + while(length --) + { + i2c_data_send(I2Cx, *dat++); + while(!i2c_flag_get(I2Cx, I2C_TDC_FLAG)); + i2c_flag_clear(I2Cx, I2C_TDC_FLAG); + } + + i2c_stop_generate(I2Cx); + + while(I2Cx->ctrl1 & I2C_CTRL1_STOPGEN); +// while(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_TDE)); +// while(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_BTFF)); +} + +uint8_t I2Cx_ReadReg(i2c_type *I2Cx, uint8_t slaveAddr, uint8_t regAddr) +{ + uint8_t retval = 0; + I2Cx_Read(I2Cx, slaveAddr, regAddr, &retval, sizeof(uint8_t)); + return retval; +} + +void I2Cx_WriteReg(i2c_type *I2Cx, uint8_t slaveAddr, uint8_t regAddr, uint8_t value) +{ + I2Cx_Write(I2Cx, slaveAddr, regAddr, &value, sizeof(uint8_t)); +} + + + + diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/i2c.h b/ArduinoCore-AT32F403A/cores/arduino/libcore/i2c.h new file mode 100644 index 0000000..5c2f956 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/i2c.h @@ -0,0 +1,39 @@ +/* + * MIT License + * Copyright (c) 2019 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __HARDWAREI2C_H +#define __HARDWAREI2C_H + +#include +#include "mcu_type.h" +/* I2C START mask */ +#define I2C_CTRL1_STARTGEN ((uint16_t)0x0100) +/* I2C STOP mask */ +#define I2C_CTRL1_STOPGEN ((uint16_t)0x0200) +void I2Cx_Init(i2c_type *I2Cx, uint32_t baudRate); +void I2Cx_Read(i2c_type *I2Cx, uint8_t slaveAddr, uint8_t regAddr, void *buf, uint32_t length); +void I2Cx_Write(i2c_type *I2Cx, uint8_t slaveAddr, uint8_t regAddr, void *buf, uint32_t length); +uint8_t I2Cx_ReadReg(i2c_type *I2Cx, uint8_t slaveAddr, uint8_t regAddr); +void I2Cx_WriteReg(i2c_type *I2Cx, uint8_t slaveAddr, uint8_t regAddr, uint8_t value); + +#endif + diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/mcu_core.c b/ArduinoCore-AT32F403A/cores/arduino/libcore/mcu_core.c new file mode 100644 index 0000000..128e6a7 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/mcu_core.c @@ -0,0 +1,33 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "mcu_core.h" + +void Core_Init(void) +{ + system_clock_config(); + nvic_priority_group_config(NVIC_PRIORITY_GROUP_2); +// GPIO_JTAG_Disable(); + Delay_Init(); + ADCx_Init(ADC1); +} diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/mcu_core.h b/ArduinoCore-AT32F403A/cores/arduino/libcore/mcu_core.h new file mode 100644 index 0000000..4c14a4a --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/mcu_core.h @@ -0,0 +1,49 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __MCU_CORE_H +#define __MCU_CORE_H + +#include "at32f403a_407_clock.h" + +#define sei() __set_PRIMASK(0) +#define cli() __set_PRIMASK(1) + +#include "adc.h" +#include "delay.h" +#include "exti.h" +#include "gpio.h" +#include "pwm.h" +#include "timer.h" +#include "wdg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void Core_Init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/mcu_type.h b/ArduinoCore-AT32F403A/cores/arduino/libcore/mcu_type.h new file mode 100644 index 0000000..5d3486e --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/mcu_type.h @@ -0,0 +1,75 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __MCU_TYPE_H +#define __MCU_TYPE_H + +#include "at32f403a_407.h" +#include "at32f403a_407_conf.h" +#include "config/mcu_config.h" + +#define __AT32__ +#define __AT32F4__ +// #define F_CPU system_core_clock +// #define F_CPU 80000000L +#define CYCLES_PER_MICROSECOND (F_CPU / 1000000U) + +typedef gpio_type GPIO_TypeDef; +typedef spi_type SPI_TypeDef; +typedef tmr_type TIM_TypeDef; + +#define GPIO_Pin_0 GPIO_PINS_0 +#define GPIO_Pin_1 GPIO_PINS_1 +#define GPIO_Pin_2 GPIO_PINS_2 +#define GPIO_Pin_3 GPIO_PINS_3 +#define GPIO_Pin_4 GPIO_PINS_4 +#define GPIO_Pin_5 GPIO_PINS_5 +#define GPIO_Pin_6 GPIO_PINS_6 +#define GPIO_Pin_7 GPIO_PINS_7 +#define GPIO_Pin_8 GPIO_PINS_8 +#define GPIO_Pin_9 GPIO_PINS_9 +#define GPIO_Pin_10 GPIO_PINS_10 +#define GPIO_Pin_11 GPIO_PINS_11 +#define GPIO_Pin_12 GPIO_PINS_12 +#define GPIO_Pin_13 GPIO_PINS_13 +#define GPIO_Pin_14 GPIO_PINS_14 +#define GPIO_Pin_15 GPIO_PINS_15 +#define GPIO_Pin_All GPIO_PINS_All + +#define TIM1 TMR1 +#define TIM2 TMR2 +#define TIM3 TMR3 +#define TIM4 TMR4 +#define TIM5 TMR5 +#define TIM6 TMR6 +#define TIM7 TMR7 +#define TIM8 TMR8 +#define TIM9 TMR9 +#define TIM10 TMR10 +#define TIM11 TMR11 +#define TIM12 TMR12 +#define TIM13 TMR13 +#define TIM14 TMR14 +#define TIM15 TMR15 + + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/pwm.c b/ArduinoCore-AT32F403A/cores/arduino/libcore/pwm.c new file mode 100644 index 0000000..66bcf2c --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/pwm.c @@ -0,0 +1,115 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "pwm.h" +#include "timer.h" +#include "Arduino.h" + +/** + * @brief 定时器输出捕获初始化 + * @param TIMx: 定时器地址 + * @param arr: 自动重装值 + * @param psc: 时钟预分频数 + * @param TimerChannel: 定时器通道 + * @retval 无 + */ +static void TIMx_OCxInit(tmr_type* TIMx, uint32_t arr, uint16_t psc, uint8_t TimerChannel) +{ + tmr_output_config_type tmr_output_struct; + + Timer_ClockCmd(TIMx, true); + + tmr_base_init(TIMx, arr, psc); + tmr_cnt_dir_set(TIMx, TMR_COUNT_UP); + + tmr_output_default_para_init(&tmr_output_struct); + tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_B; + tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_LOW; + tmr_output_struct.oc_idle_state = TRUE; + tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.occ_idle_state = FALSE; + tmr_output_struct.oc_output_state = TRUE; + tmr_output_struct.occ_output_state = TRUE; + + switch(TimerChannel) + { + case 1: + tmr_output_channel_config(TIMx, TMR_SELECT_CHANNEL_1, &tmr_output_struct); + break; + case 2: + tmr_output_channel_config(TIMx, TMR_SELECT_CHANNEL_2, &tmr_output_struct); + break; + case 3: + tmr_output_channel_config(TIMx, TMR_SELECT_CHANNEL_3, &tmr_output_struct); + break; + case 4: + tmr_output_channel_config(TIMx, TMR_SELECT_CHANNEL_4, &tmr_output_struct); + break; + default: + return; + } + + tmr_output_enable(TIMx, TRUE); + tmr_counter_enable(TIMx, TRUE); +} + +/** + * @brief PWM输出初始化 + * @param Pin:引脚编号 + * @param Resolution: PWM分辨率 + * @param Frequency: PWM频率 + * @retval 引脚对应的定时器通道 + */ +uint8_t PWM_Init(uint8_t Pin, uint32_t Resolution, uint32_t Frequency) +{ + uint32_t arr, psc; + + if(!IS_PWM_PIN(Pin)) + { + return 0; + } + + if(Resolution == 0 || Frequency == 0 || (Resolution * Frequency) > F_CPU) + { + return 0; + } + + pinMode(Pin, OUTPUT_AF_PP); + + arr = Resolution; + psc = Timer_GetClockMax(PIN_MAP[Pin].TIMx) / Resolution / Frequency; + + Timer_SetEnable(PIN_MAP[Pin].TIMx, false); + TIMx_OCxInit(PIN_MAP[Pin].TIMx, arr - 1, psc - 1, PIN_MAP[Pin].TimerChannel); + return PIN_MAP[Pin].TimerChannel; +} + +/** + * @brief 输出PWM信号 + * @param Pin: 引脚编号 + * @param Value: PWM输出值 + * @retval PWM占空比值 + */ +void PWM_Write(uint8_t Pin, uint32_t Value) +{ + Timer_SetCompare(PIN_MAP[Pin].TIMx, PIN_MAP[Pin].TimerChannel, Value); +} diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/pwm.h b/ArduinoCore-AT32F403A/cores/arduino/libcore/pwm.h new file mode 100644 index 0000000..35f5a45 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/pwm.h @@ -0,0 +1,41 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __PWM_H +#define __PWM_H + +#include "mcu_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define pwmWrite(pin, value) PWM_Write(pin, value) + +uint8_t PWM_Init(uint8_t Pin, uint32_t Resolution, uint32_t Frequency); +void PWM_Write(uint8_t Pin, uint32_t Value); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/rtc.c b/ArduinoCore-AT32F403A/cores/arduino/libcore/rtc.c new file mode 100644 index 0000000..7e6738e --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/rtc.c @@ -0,0 +1,303 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "rtc.h" + +static const uint8_t table_week[12] = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5}; //Monthly correction data sheet. +static const uint8_t mon_table[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //Month data table of Pingnian + + +/** + * @brief RTC Init. + * @param None + * @retval None + */ +void RTC_Init(void) +{ + /* enable pwc and bpr clocks */ + crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE); + crm_periph_clock_enable(CRM_BPR_PERIPH_CLOCK, TRUE); + /* allow access to bpr domain */ + pwc_battery_powered_domain_access(TRUE); + /* Check Backup data registers is correct*/ + if (bpr_data_read(BPR_DATA1) != 0x5051) + { + /* reset backup domain */ + bpr_reset(); + + /* enable the lick osc */ + crm_clock_source_enable(CRM_CLOCK_SOURCE_LICK, TRUE); + /* wait till lick is ready */ + while(crm_flag_get(CRM_LICK_STABLE_FLAG) == RESET); + /* select the rtc clock source */ + crm_rtc_clock_select(CRM_RTC_CLOCK_LICK); + + /* enable rtc clock */ + crm_rtc_clock_enable(TRUE); + + /* wait for rtc registers update */ + rtc_wait_update_finish(); + + /* wait for the register write to complete */ + rtc_wait_config_finish(); + + /* enable the rtc second */ + rtc_interrupt_enable(RTC_TS_INT, TRUE); + + /* wait for the register write to complete */ + rtc_wait_config_finish(); + + /* set rtc divider: set rtc period to 1sec */ + rtc_divider_set(40000); + + /* wait for the register write to complete */ + rtc_wait_config_finish(); + + /* Set the RTC time */ + RTC_SetTime(2018, 8, 8, 8, 8, 0); + /* wait for the register write to complete */ + rtc_wait_config_finish(); + + /* Writes data to Backup Register */ + bpr_data_write(BPR_DATA1, 0x5051); + } + else + { + /* wait for rtc registers update */ + rtc_wait_update_finish(); + + /* wait for the register write to complete */ + rtc_wait_config_finish(); + /* Clear RTC pending flag */ + rtc_flag_clear(RTC_CFGF_FLAG); + /* wait for the register write to complete */ + rtc_wait_config_finish(); + } +} + +/** + * @brief Judeg the Leap year or Pingnian. + * Month 1 2 3 4 5 6 7 8 9 10 11 12 + * Leap year 31 29 31 30 31 30 31 31 30 31 30 31 + * Pingnian 31 28 31 30 31 30 31 31 30 31 30 31 + * @param year + * @retval 1: Leap year + 2: Pingnian + */ +static uint8_t Is_Leap_Year(uint16_t year) +{ + if(year % 4 == 0) + { + if(year % 100 == 0) + { + if(year % 400 == 0) return 1; + else return 0; + } + else return 1; + } + else return 0; +} + +/** + * @brief Set time. Convert the input clock to a second. + * The time basic : 1970.1.1 + * legitimate year: 1970 ~ 2099 + * @param syear: Year + * smon : Month + * sday : Day + * hour + * min + * sec + * @retval 0: Set time right. + * 1: Set time failed. + */ +uint8_t RTC_SetTime(uint16_t syear, uint8_t smon, uint8_t sday, uint8_t hour, uint8_t min, uint8_t sec) +{ + uint32_t t; + uint32_t seccount = 0; + + if(syear < 1970 || syear > 2099) + return 1; + + for(t = 1970; t < syear; t++) + { + if(Is_Leap_Year(t))seccount += 31622400; + else seccount += 31536000; + } + smon -= 1; + for(t = 0; t < smon; t++) + { + seccount += (uint8_t)mon_table[t] * 86400; + if(Is_Leap_Year(syear) && t == 1)seccount += 86400; + } + seccount += (uint8_t)(sday - 1) * 86400; + seccount += (uint8_t)hour * 3600; + seccount += (uint8_t)min * 60; + seccount += sec; + + /* enable pwc and bpr clocks */ + crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE); + crm_periph_clock_enable(CRM_BPR_PERIPH_CLOCK, TRUE); + /* allow access to bpr domain */ + pwc_battery_powered_domain_access(TRUE); + + /* Set the RTC counter value */ + rtc_counter_set(seccount); + /* wait for the register write to complete */ + rtc_wait_config_finish(); + return 0; +} + +/** + * @brief Set RTC alarm. + * The time basic : 1970.1.1 + * legitimate year: 1970 ~ 2099 + * @param syear : Year + * smon : Month + * sday : Day + * hour + * min + * sec + * @retval 0: Set Alarm right. + * 1: Set Alarm failed. + */ +uint8_t RTC_SetAlarm(uint16_t syear, uint8_t smon, uint8_t sday, uint8_t hour, uint8_t min, uint8_t sec) +{ + uint16_t t; + uint8_t seccount = 0; + + if(syear < 1970 || syear > 2099) + return 1; + + for(t = 1970; t < syear; t++) + { + if(Is_Leap_Year(t))seccount += 31622400; + else seccount += 31536000; + } + smon -= 1; + for(t = 0; t < smon; t++) + { + seccount += (uint8_t)mon_table[t] * 86400; + if(Is_Leap_Year(syear) && t == 1)seccount += 86400; + } + seccount += (uint8_t)(sday - 1) * 86400; + seccount += (uint8_t)hour * 3600; + seccount += (uint8_t)min * 60; + seccount += sec; + + /* enable pwc and bpr clocks */ + crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE); + crm_periph_clock_enable(CRM_BPR_PERIPH_CLOCK, TRUE); + /* allow access to bpr domain */ + pwc_battery_powered_domain_access(TRUE); + + /* Set the RTC counter value */ + rtc_alarm_set(seccount); + /* wait for the register write to complete */ + rtc_wait_config_finish(); + + return 0; +} + +/** + * @brief Get current time. + * @param None. + * @retval None. + */ +void RTC_GetCalendar(RTC_Calendar_TypeDef* calendar) +{ + static RTC_Calendar_TypeDef _calendar; + static uint16_t daycnt = 0; + uint32_t timecount = 0; + uint32_t temp = 0; + uint32_t temp1 = 0; + + timecount = rtc_counter_get(); + temp = timecount / 86400; + if(daycnt != temp) + { + daycnt = temp; + temp1 = 1970; + while(temp >= 365) + { + if(Is_Leap_Year(temp1)) + { + if(temp >= 366)temp -= 366; + else + { + temp1++; + break; + } + } + else temp -= 365; + temp1++; + } + _calendar.year = temp1; + temp1 = 0; + while(temp >= 28) + { + if(Is_Leap_Year(_calendar.year) && temp1 == 1) + { + if(temp >= 29)temp -= 29; + else break; + } + else + { + if(temp >= mon_table[temp1])temp -= mon_table[temp1]; + else break; + } + temp1++; + } + _calendar.month = temp1 + 1; + _calendar.day = temp + 1; + } + temp = timecount % 86400; + _calendar.hour = temp / 3600; + _calendar.min = (temp % 3600) / 60; + _calendar.sec = (temp % 3600) % 60; + _calendar.week = RTC_GetWeek(_calendar.year, _calendar.month, _calendar.day); + + *calendar = _calendar; +} + +/** + * @brief Get current week by Input Leap year\mouth\day. + * @param syear : Year + * smon : Month + * sday : Day + * @retval week number. + */ +uint8_t RTC_GetWeek(uint16_t year, uint8_t month, uint8_t day) +{ + uint16_t temp2; + uint8_t yearH, yearL; + + yearH = year / 100; + yearL = year % 100; + if (yearH > 19)yearL += 100; + temp2 = yearL + yearL / 4; + temp2 = temp2 % 7; + temp2 = temp2 + day + table_week[month - 1]; + if (yearL % 4 == 0 && month < 3) + temp2--; + return(temp2 % 7); +} diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/rtc.h b/ArduinoCore-AT32F403A/cores/arduino/libcore/rtc.h new file mode 100644 index 0000000..115e843 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/rtc.h @@ -0,0 +1,53 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __RTC_H +#define __RTC_H + +#include "mcu_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + uint8_t hour; + uint8_t min; + uint8_t sec; + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t week; +} RTC_Calendar_TypeDef; + +void RTC_Init(void); +void RTC_GetCalendar(RTC_Calendar_TypeDef* calendar); +uint8_t RTC_SetAlarm(uint16_t syear, uint8_t smon, uint8_t sday, uint8_t hour, uint8_t min, uint8_t sec); +uint8_t RTC_GetWeek(uint16_t year, uint8_t month, uint8_t day); +uint8_t RTC_SetTime(uint16_t syear, uint8_t smon, uint8_t sday, uint8_t hour, uint8_t min, uint8_t sec); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/syscall.c b/ArduinoCore-AT32F403A/cores/arduino/libcore/syscall.c new file mode 100644 index 0000000..67541ac --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/syscall.c @@ -0,0 +1,108 @@ +/** + * \file syscalls_at32.c + * + * Implementation of newlib syscall. + * + */ +#include "at32f403a_407.h" +#include "at32f403a_407_conf.h" +#if defined ( __GNUC__ ) /* GCC CS3 */ + #include +#endif +#include +#undef errno +extern int errno; + +extern size_t uart_debug_write(uint8_t *data, uint32_t size); + +// Helper macro to mark unused parameters and prevent compiler warnings. +// Appends _UNUSED to the variable name to prevent accidentally using them. +#ifdef UNUSED + #undef UNUSED +#endif +#ifdef __GNUC__ + #define UNUSED(x) x ## _UNUSED __attribute__((__unused__)) +#else + #define UNUSED(x) x ## _UNUSED +#endif + +__attribute__((weak)) +caddr_t _sbrk(int incr) +{ + extern char _estack; /* Defined in the linker script */ + extern char _Min_Stack_Size; /* Defined in the linker script */ + extern char _end; /* Defined by the linker */ + static char *heap_end = &_end ; + char *prev_heap_end = heap_end; + + if (heap_end + incr > (char *)__get_MSP()) { + /* Heap and stack collision */ + errno = ENOMEM; + return (caddr_t) -1; + } + /* Ensure to keep minimum stack size defined in the linker script */ + if (heap_end + incr >= (char *)(&_estack - &_Min_Stack_Size)) { + errno = ENOMEM; + return (caddr_t) -1; + } + + heap_end += incr ; + return (caddr_t) prev_heap_end ; +} + +__attribute__((weak)) +int _close(UNUSED(int file)) +{ + return -1; +} + +__attribute__((weak)) +int _fstat(UNUSED(int file), struct stat *st) +{ + st->st_mode = S_IFCHR ; + return 0; +} + +__attribute__((weak)) +int _isatty(UNUSED(int file)) +{ + return 1; +} + +__attribute__((weak)) +int _lseek(UNUSED(int file), UNUSED(int ptr), UNUSED(int dir)) +{ + return 0; +} + +__attribute__((weak)) +int _read(UNUSED(int file), UNUSED(char *ptr), UNUSED(int len)) +{ + return 0; +} + +/* Moved to Print.cpp to support Print::printf() +__attribute__((weak)) +int _write(UNUSED(int file), char *ptr, int len) +{ +} +*/ + +__attribute__((weak)) +void _exit(UNUSED(int status)) +{ + for (; ;) ; +} + +__attribute__((weak)) +int _kill(UNUSED(int pid), UNUSED(int sig)) +{ + errno = EINVAL; + return -1; +} + +__attribute__((weak)) +int _getpid(void) +{ + return 1; +} \ No newline at end of file diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/timer.c b/ArduinoCore-AT32F403A/cores/arduino/libcore/timer.c new file mode 100644 index 0000000..05949be --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/timer.c @@ -0,0 +1,608 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "timer.h" + +typedef enum +{ + TIMER1, TIMER2, TIMER3, TIMER4, TIMER5, TIMER6, TIMER7, TIMER8, + TIMER9, TIMER10, TIMER11, TIMER12, TIMER13, TIMER14, TIMER15, + TIMER_MAX +} TIMER_Type; + +static Timer_CallbackFunction_t Timer_CallbackFunction[TIMER_MAX] = { 0 }; + +/** + * @brief 启动或关闭指定定时器的时钟 + * @param TIMx:定时器地址 + * @param NewState: ENABLE启动,DISABLE关闭 + * @retval 无 + */ +void Timer_ClockCmd(tmr_type* TIMx, bool Enable) +{ + int index; + typedef struct + { + tmr_type* tmr; + crm_periph_clock_type crm_periph_clock; + } crm_tmr_clock_map_t; + +# define CLOCK_MAP_DEF(n) {TMR##n, CRM_TMR##n##_PERIPH_CLOCK} + + static const crm_tmr_clock_map_t clock_map[] = + { + CLOCK_MAP_DEF(1), + CLOCK_MAP_DEF(2), + CLOCK_MAP_DEF(3), + CLOCK_MAP_DEF(4), + CLOCK_MAP_DEF(5), + CLOCK_MAP_DEF(6), + CLOCK_MAP_DEF(7), + CLOCK_MAP_DEF(8), + CLOCK_MAP_DEF(9), + CLOCK_MAP_DEF(10), + CLOCK_MAP_DEF(11), + CLOCK_MAP_DEF(12), + CLOCK_MAP_DEF(13), + CLOCK_MAP_DEF(14) + }; + + for(index = 0; index < sizeof(clock_map) / sizeof(crm_tmr_clock_map_t); index++) + { + if(TIMx == clock_map[index].tmr) + { + crm_periph_clock_enable(clock_map[index].crm_periph_clock, Enable ? TRUE : FALSE); + } + } +} + +static float Qsqrt(float number) +{ + long i; + float x2, y; + const float threehalfs = 1.5f; + x2 = number * 0.5f; + y = number; + i = *(long*)&y; + i = 0x5f3759df - (i >> 1); + y = *(float*)&i; + y = y * (threehalfs - (x2 * y * y)); + y = y * (threehalfs - (x2 * y * y)); + return 1.0f / y; +} + +/** + * @brief 频率因数分解,获取接近的值 + * @param freq: 中断频率(Hz) + * @param clock: 定时器时钟 + * @param *period: 重装值地址 + * @param *prescaler: 时钟分频值地址 + * @retval 误差值(Hz) + */ +static bool Timer_FreqFactorization( + uint32_t freq, + uint32_t clock, + uint16_t* factor1, + uint16_t* factor2, + int32_t* error +) +{ + uint32_t targetProdect; + uint16_t fct1; + uint16_t fct2; + uint16_t fct1_save = 1; + uint16_t fct2_save = 1; + uint16_t fct_max; + uint16_t max_error = 0xFFFF; + + if(freq == 0 || freq > clock) + { + return false; + } + + /* 获取目标乘积 */ + targetProdect = clock / freq; + + /* 从targetProdect的平方根开始计算 */ + fct1 = Qsqrt(targetProdect); + + /* 计算因数最大值,减少遍历次数 */ + fct_max = (targetProdect < 0xFFFF) ? targetProdect : 0xFFFF; + + /* 遍历,使两因数的乘积足够接近prodect */ + for(; fct1 > 1; fct1--) + { + for(fct2 = fct1; fct2 < fct_max; fct2++) + { + /* 求误差 */ + int32_t newerr = fct1 * fct2 - targetProdect; + + if(newerr < 0) + { + newerr = -newerr; + } + + if(newerr < max_error) + { + /* 保存最小误差 */ + max_error = (uint16_t)newerr; + + fct1_save = fct1; + fct2_save = fct2; + + /* 最佳 */ + if(max_error == 0) + { + break; + } + } + } + } + + *factor1 = fct1_save; + *factor2 = fct2_save; + *error = (freq - clock / (fct1_save * fct2_save)); + + return true; +} + +/** + * @brief 将定时中断时间转换为重装值和时钟分频值 + * @param time: 中断时间(微秒) + * @param clock: 定时器时钟 + * @param *period: 重装值地址 + * @param *prescaler: 时钟分频值地址 + * @retval 无 + */ +static void Timer_TimeFactorization( + uint32_t time, + uint32_t clock, + uint16_t* factor1, + uint16_t* factor2 +) +{ + const uint32_t cyclesPerMicros = clock / 1000000U; + const uint32_t prodect = time * cyclesPerMicros; + uint16_t fct1, fct2; + + if(prodect < cyclesPerMicros * 30) + { + fct1 = 10; + fct2 = prodect / 10; + } + else if(prodect < 65535 * 1000) + { + fct1 = prodect / 1000; + fct2 = prodect / fct1; + } + else + { + fct1 = prodect / 20000; + fct2 = prodect / fct1; + } + *factor1 = fct1; + *factor2 = fct2; +} + +/** + * @brief 定时器使能 + * @param TIMx: 定时器地址 + * @param Enable: 使能 + * @retval 无 + */ +void Timer_SetEnable(tmr_type* TIMx, bool Enable) +{ + tmr_counter_enable(TIMx, Enable ? TRUE : FALSE); +} + +/** + * @brief 定时中断配置 + * @param TIMx:定时器地址 + * @param Time: 中断时间(微秒) + * @param Function: 定时中断回调函数 + * @retval 无 + */ +void Timer_SetInterrupt(tmr_type* TIMx, uint32_t Time, Timer_CallbackFunction_t Function) +{ + uint16_t period = 0; + uint16_t prescaler = 0; + uint32_t clock = Timer_GetClockMax(TIMx); + + if(Time == 0) + { + return; + } + + /*将定时中断时间转换为重装值和时钟分频值*/ + Timer_TimeFactorization( + Time, + clock, + &period, + &prescaler + ); + + /*定时中断配置*/ + Timer_SetInterruptBase( + TIMx, + period, + prescaler, + Function, + TIMER_PREEMPTIONPRIORITY_DEFAULT, + TIMER_SUBPRIORITY_DEFAULT + ); +} + +/** + * @brief 更新定时中断频率 + * @param TIMx:定时器地址 + * @param Freq:中断频率 + * @retval true: 设置成功 + */ +bool Timer_SetInterruptFreqUpdate(tmr_type* TIMx, uint32_t Freq) +{ + uint16_t period, prescaler; + uint32_t clock = Timer_GetClockMax(TIMx); + int32_t error; + + if(Freq == 0) + return false; + + bool success = Timer_FreqFactorization( + Freq, + clock, + &period, + &prescaler, + &error + ); + + if(!success) + { + return false; + } + + tmr_base_init(TIMx, period - 1, prescaler - 1); + return true; +} + +/** + * @brief 获取定时器最大频率 + * @param TIMx:定时器地址 + * @retval 最大频率 + */ +uint32_t Timer_GetClockMax(tmr_type* TIMx) +{ + static crm_clocks_freq_type crm_clocks_freq_struct = {0}; + if(!crm_clocks_freq_struct.sclk_freq) + { + crm_clocks_freq_get(&crm_clocks_freq_struct); + } + + return crm_clocks_freq_struct.apb1_freq * 2; +} + +/** + * @brief 获取定时器中断频率 + * @param TIMx:定时器地址 + * @retval 中断频率 + */ +uint32_t Timer_GetClockOut(tmr_type* TIMx) +{ + uint32_t clock = Timer_GetClockMax(TIMx); + + return (clock / ((TIMx->pr + 1) * (TIMx->div + 1))); +} + +/** + * @brief 更新定时中断时间 + * @param TIMx:定时器地址 + * @param Time: 中断时间(微秒) + * @retval 无 + */ +void Timer_SetInterruptTimeUpdate(TIM_TypeDef* TIMx, uint32_t Time) +{ + uint16_t period, prescaler; + uint32_t clock = Timer_GetClockMax(TIMx); + + Timer_TimeFactorization( + Time, + clock, + &period, + &prescaler + ); + + tmr_base_init(TIMx, period - 1, prescaler - 1); +} + +/** + * @brief 定时中断基本配置 + * @param TIMx:定时器地址 + * @param Period:重装值 + * @param Prescaler:时钟分频值 + * @param Function: 定时中断回调函数 + * @param PreemptionPriority: 抢占优先级 + * @param SubPriority: 子优先级 + * @retval 无 + */ +void Timer_SetInterruptBase( + tmr_type* TIMx, + uint16_t Period, + uint16_t Prescaler, + Timer_CallbackFunction_t Function, + uint8_t PreemptionPriority, + uint8_t SubPriority +) +{ + IRQn_Type TMRx_IRQn = (IRQn_Type)0; + TIMER_Type TIMERx = TIMER1; + +#define TMRx_IRQ_DEF(n,x_IRQn)\ +do{\ + if(TIMx == TIM##n)\ + {\ + TIMERx = TIMER##n;\ + TMRx_IRQn = x_IRQn;\ + goto match;\ + }\ +}\ +while(0) + + /*如果编译器提示:identifier "xxx_IRQn" is undefined + *把未定义的注释掉即可 + */ + TMRx_IRQ_DEF(1, TMR1_OVF_TMR10_IRQn); + TMRx_IRQ_DEF(2, TMR2_GLOBAL_IRQn); + TMRx_IRQ_DEF(3, TMR3_GLOBAL_IRQn); + TMRx_IRQ_DEF(4, TMR4_GLOBAL_IRQn); + TMRx_IRQ_DEF(5, TMR5_GLOBAL_IRQn); + TMRx_IRQ_DEF(6, TMR6_GLOBAL_IRQn); + TMRx_IRQ_DEF(7, TMR7_GLOBAL_IRQn); + TMRx_IRQ_DEF(8, TMR8_OVF_TMR13_IRQn); + TMRx_IRQ_DEF(9, TMR1_BRK_TMR9_IRQn); + TMRx_IRQ_DEF(10, TMR1_OVF_TMR10_IRQn); + TMRx_IRQ_DEF(11, TMR1_TRG_HALL_TMR11_IRQn); + TMRx_IRQ_DEF(12, TMR8_BRK_TMR12_IRQn); + TMRx_IRQ_DEF(13, TMR8_OVF_TMR13_IRQn); + TMRx_IRQ_DEF(14, TMR8_TRG_HALL_TMR14_IRQn); + +match: + + if(TMRx_IRQn == 0) + { + return; + } + + Timer_CallbackFunction[TIMERx] = Function; + + tmr_reset(TIMx); + Timer_ClockCmd(TIMx, true); + + tmr_repetition_counter_set(TIMx, 0); + tmr_cnt_dir_set(TIMx, TMR_COUNT_UP); + tmr_base_init(TIMx, Period - 1, Prescaler - 1); + + nvic_irq_enable(TMRx_IRQn, PreemptionPriority, SubPriority); + + tmr_flag_clear(TIMx, TMR_OVF_FLAG); + tmr_interrupt_enable(TIMx, TMR_OVF_INT, TRUE); +} + +/** + * @brief 设置输出比较值 + * @param TIMx: 定时器地址 + * @param TimerChannel: 定时器通道 + * @param Compare:输出比较值 + * @retval 无 + */ +void Timer_SetCompare(TIM_TypeDef* TIMx, uint8_t TimerChannel, uint32_t Compare) +{ + switch(TimerChannel) + { + case 1: + tmr_channel_value_set(TIMx, TMR_SELECT_CHANNEL_1, Compare); + break; + case 2: + tmr_channel_value_set(TIMx, TMR_SELECT_CHANNEL_2, Compare); + break; + case 3: + tmr_channel_value_set(TIMx, TMR_SELECT_CHANNEL_3, Compare); + break; + case 4: + tmr_channel_value_set(TIMx, TMR_SELECT_CHANNEL_4, Compare); + break; + default: + break; + } +} + +/** + * @brief 获取捕获值 + * @param TIMx: 定时器地址 + * @param TimerChannel: 定时器通道 + * @retval 捕获值 + */ +uint16_t Timer_GetCompare(TIM_TypeDef* TIMx, uint8_t TimerChannel) +{ + uint16_t retval = 0; + switch(TimerChannel) + { + case 1: + retval = tmr_channel_value_get(TIMx, TMR_SELECT_CHANNEL_1); + break; + case 2: + retval = tmr_channel_value_get(TIMx, TMR_SELECT_CHANNEL_2); + break; + case 3: + retval = tmr_channel_value_get(TIMx, TMR_SELECT_CHANNEL_3); + break; + case 4: + retval = tmr_channel_value_get(TIMx, TMR_SELECT_CHANNEL_4); + break; + default: + break; + } + + return retval; +} + +/** + * @brief 更新定时器时钟预分频数 + * @param TIMx: 定时器地址 + * @param rescaler: 时钟预分频数 + * @retval 无 + */ +void Timer_SetPrescaler(tmr_type* TIMx, uint16_t rescaler) +{ + TIMx->div = rescaler; +} + +/** + * @brief 更新定时器自动重装值 + * @param TIMx: 定时器地址 + * @param Reload: 自动重装值 + * @retval 无 + */ +void Timer_SetReload(tmr_type* TIMx, uint16_t Reload) +{ + TIMx->pr = Reload; +} + +/** + * @brief 应用定时器更改 + * @param TIMx: 定时器地址 + * @retval 无 + */ +void Timer_GenerateUpdate(tmr_type* TIMx) +{ + TIMx->swevt_bit.ovfswtr = TRUE; +} + +#define TMRx_IRQHANDLER(n) \ +do{\ + if (tmr_flag_get(TMR##n, TMR_OVF_FLAG) != RESET)\ + {\ + if(Timer_CallbackFunction[TIMER##n])\ + {\ + Timer_CallbackFunction[TIMER##n]();\ + }\ + tmr_flag_clear(TMR##n, TMR_OVF_FLAG);\ + }\ +}while(0) + +/** + * @brief 定时中断入口,定时器1、10 + * @param 无 + * @retval 无 + */ +void TMR1_OV_TMR10_IRQHandler(void) +{ + TMRx_IRQHANDLER(1); + TMRx_IRQHANDLER(10); +} + +/** + * @brief 定时中断入口,定时器2 + * @param 无 + * @retval 无 + */ +void TMR2_GLOBAL_IRQHandler(void) +{ + TMRx_IRQHANDLER(2); +} + +/** + * @brief 定时中断入口,定时器3 + * @param 无 + * @retval 无 + */ +void TMR3_GLOBAL_IRQHandler(void) +{ + TMRx_IRQHANDLER(3); +} + +/** + * @brief 定时中断入口,定时器4 + * @param 无 + * @retval 无 + */ +void TMR4_GLOBAL_IRQHandler(void) +{ + TMRx_IRQHANDLER(4); +} + +/** + * @brief 定时中断入口,定时器5 + * @param 无 + * @retval 无 + */ +void TMR5_GLOBAL_IRQHandler(void) +{ + TMRx_IRQHANDLER(5); +} + +/** + * @brief 定时中断入口,定时器6 + * @param 无 + * @retval 无 + */ +void TMR6_GLOBAL_IRQHandler(void) +{ +#ifdef TMR6 + TMRx_IRQHANDLER(6); +#endif +} + +/** + * @brief 定时中断入口,定时器7 + * @param 无 + * @retval 无 + */ +void TMR7_GLOBAL_IRQHandler(void) +{ +#ifdef TMR7 + TMRx_IRQHANDLER(7); +#endif +} + +/** + * @brief 定时中断入口,定时器8、13 + * @param 无 + * @retval 无 + */ +void TMR8_OV_TMR13_IRQHandler(void) +{ + TMRx_IRQHANDLER(8); +#ifdef TMR13 + TMRx_IRQHANDLER(13); +#endif +} + +/** + * @brief 定时中断入口,定时器15 + * @param 无 + * @retval 无 + */ +void TMR15_OV_IRQHandler(void) +{ +#ifdef TMR15 + TMRx_IRQHANDLER(15); +#endif +} diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/timer.h b/ArduinoCore-AT32F403A/cores/arduino/libcore/timer.h new file mode 100644 index 0000000..da05314 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/timer.h @@ -0,0 +1,58 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __TIMER_H +#define __TIMER_H + +#include +#include "mcu_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void(*Timer_CallbackFunction_t)(void); + +void Timer_SetEnable(tmr_type* TIMx, bool Enable); +void Timer_SetInterrupt(tmr_type* TIMx, uint32_t time, Timer_CallbackFunction_t Function); +void Timer_SetInterruptTimeUpdate(tmr_type* TIMx, uint32_t Time); +bool Timer_SetInterruptFreqUpdate(tmr_type* TIMx, uint32_t Freq); +void Timer_SetInterruptBase( + tmr_type* TIMx, + uint16_t Period, uint16_t Prescaler, + Timer_CallbackFunction_t Function, + uint8_t PreemptionPriority, uint8_t SubPriority +); +void Timer_SetCompare(tmr_type* TIMx, uint8_t TimerChannel, uint32_t Compare); +void Timer_SetPrescaler(tmr_type* TIMx, uint16_t Prescaler); +void Timer_SetReload(tmr_type* TIMx, uint16_t Reload); +void Timer_ClockCmd(tmr_type* TIMx, bool Enable); +uint32_t Timer_GetClockMax(tmr_type* TIMx); +uint32_t Timer_GetClockOut(tmr_type* TIMx); +uint16_t Timer_GetCompare(tmr_type* TIMx, uint8_t TimerChannel); +void Timer_GenerateUpdate(tmr_type* TIMx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/wdg.c b/ArduinoCore-AT32F403A/cores/arduino/libcore/wdg.c new file mode 100644 index 0000000..5465e59 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/wdg.c @@ -0,0 +1,96 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "wdg.h" + +uint32_t WDG_Init(uint32_t timeout) +{ + uint32_t reload_value; + uint32_t real_timeout = 0; + + uint16_t division; + + static const uint8_t div_map[] = + { + WDT_CLK_DIV_4, /*!< wdt clock divider value is 4 */ + WDT_CLK_DIV_8, /*!< wdt clock divider value is 8 */ + WDT_CLK_DIV_16, /*!< wdt clock divider value is 16 */ + WDT_CLK_DIV_32, /*!< wdt clock divider value is 32 */ + WDT_CLK_DIV_64, /*!< wdt clock divider value is 64 */ + WDT_CLK_DIV_128, /*!< wdt clock divider value is 128 */ + WDT_CLK_DIV_256 /*!< wdt clock divider value is 256 */ + }; + + /* set reload value + * lick_freq = 40000 + * timeout = reload_value * divider / lick_freq * 1000 (ms) + * timeout / divider * lick_freq / 1000 = reload_value + */ + const uint32_t lick_freq = 40000; + + for(int i = 0; i < sizeof(div_map) / sizeof(uint8_t); i++) + { + int div = 4 << i; + reload_value = (uint64_t)timeout * lick_freq / div / 1000; + + if(reload_value <= 0xFFF) + { + real_timeout = (uint64_t)reload_value * div * 1000 / lick_freq; + division = div_map[i]; + break; + } + } + + if(reload_value > 0xFFF) + { + return 0; + } + + if(crm_flag_get(CRM_WDT_RESET_FLAG) != RESET) + { + /* reset from wdt */ + crm_flag_clear(CRM_WDT_RESET_FLAG); + } + + /* disable register write protection */ + wdt_register_write_enable(TRUE); + + /* set the wdt divider value */ + wdt_divider_set(division); + + + /* Set counter reload value */ + wdt_reload_value_set(3000 - 1); + + /* Reload IWDG counter */ + wdt_counter_reload(); + + /* Enable IWDG (the LSI oscillator will be enabled by hardware) */ + wdt_enable(); + + return real_timeout; +} + +void WDG_ReloadCounter(void) +{ + wdt_counter_reload(); +} diff --git a/ArduinoCore-AT32F403A/cores/arduino/libcore/wdg.h b/ArduinoCore-AT32F403A/cores/arduino/libcore/wdg.h new file mode 100644 index 0000000..af6caa2 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/libcore/wdg.h @@ -0,0 +1,39 @@ +/* + * MIT License + * Copyright (c) 2017 - 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __WDT_H +#define __WDT_H + +#include "mcu_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t WDG_Init(uint32_t timeout); +void WDG_ReloadCounter(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/cores/arduino/main.cpp b/ArduinoCore-AT32F403A/cores/arduino/main.cpp new file mode 100644 index 0000000..2f92de8 --- /dev/null +++ b/ArduinoCore-AT32F403A/cores/arduino/main.cpp @@ -0,0 +1,45 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ +#include +#include "libcore/mcu_core.h" +extern void setup(void); +extern void loop(void); + +// Force init to be called *first*, i.e. before static object allocation. +// Otherwise, statically allocated objects that need libmaple may fail. + __attribute__(( constructor (101))) void premain() { + +} + +int main(void) { + Core_Init(); + setup(); + + while (1) { + loop(); + } + return 0; +} diff --git a/ArduinoCore-AT32F403A/libraries/Generic_Examples/empty.h b/ArduinoCore-AT32F403A/libraries/Generic_Examples/empty.h new file mode 100644 index 0000000..e69de29 diff --git a/ArduinoCore-AT32F403A/libraries/Generic_Examples/examples/01.Basics/Blink/Blink.ino b/ArduinoCore-AT32F403A/libraries/Generic_Examples/examples/01.Basics/Blink/Blink.ino new file mode 100644 index 0000000..9abb8f5 --- /dev/null +++ b/ArduinoCore-AT32F403A/libraries/Generic_Examples/examples/01.Basics/Blink/Blink.ino @@ -0,0 +1,37 @@ +/* + Blink + + Turns an LED on for one second, then off for one second, repeatedly. + + Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO + it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to + the correct LED pin independent of which board is used. + If you want to know what pin the on-board LED is connected to on your Arduino + model, check the Technical Specs of your board at: + https://www.arduino.cc/en/Main/Products + + modified 8 May 2014 + by Scott Fitzgerald + modified 2 Sep 2016 + by Arturo Guadalupi + modified 8 Sep 2016 + by Colby Newman + + This example code is in the public domain. + + https://www.arduino.cc/en/Tutorial/BuiltInExamples/Blink +*/ + +// the setup function runs once when you press reset or power the board +void setup() { + // initialize digital pin LED_BUILTIN as an output. + pinMode(LED_BUILTIN, OUTPUT); +} + +// the loop function runs over and over again forever +void loop() { + digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) + delay(1000); // wait for a second + digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW + delay(1000); // wait for a second +} diff --git a/ArduinoCore-AT32F403A/libraries/Generic_Examples/examples/01.Basics/Blink/Blink.txt b/ArduinoCore-AT32F403A/libraries/Generic_Examples/examples/01.Basics/Blink/Blink.txt new file mode 100644 index 0000000..0626334 --- /dev/null +++ b/ArduinoCore-AT32F403A/libraries/Generic_Examples/examples/01.Basics/Blink/Blink.txt @@ -0,0 +1 @@ +Turn an LED on and off. \ No newline at end of file diff --git a/ArduinoCore-AT32F403A/platform.txt b/ArduinoCore-AT32F403A/platform.txt new file mode 100644 index 0000000..f44ff6a --- /dev/null +++ b/ArduinoCore-AT32F403A/platform.txt @@ -0,0 +1,68 @@ +##==============================================## +name=WeActStudio AT32F403A Boards +version=0.0.1 +##==============================================## + +####AT32 compile variables + +## compiler variables +compiler.path={runtime.tools.xpack-arm-none-eabi-gcc.path}\bin\ + +##All the command +compiler.asm.cmd=arm-none-eabi-gcc +compiler.c.cmd=arm-none-eabi-gcc +compiler.cpp.cmd=arm-none-eabi-g++ +compiler.ar.cmd=arm-none-eabi-ar +compiler.elf.cmd=arm-none-eabi-g++ +compiler.hex.cmd=arm-none-eabi-objcopy +compiler.bin.cmd=arm-none-eabi-objcopy +compiler.size.cmd=arm-none-eabi-size + +##Set the compiler flags +compiler.ar.flags=rcs +compiler.asm.flags=-mthumb -Wall -g -Os +compiler.c.flags=-mthumb -Wall -std=gnu11 -ffunction-sections -g -Os -fno-exceptions +compiler.cpp.flags=-mthumb -Wall -std=gnu++11 -ffunction-sections -g -Os -fno-exceptions -fno-rtti +compiler.elf.flags=-mthumb -g -Wl,--gc-sections -Wall --specs=nano.specs -lstdc++ -lm +compiler.hex.flags=-Oihex +compiler.bin.flags=-Obinary + +build.common_flags=-mthumb + +##===============================================## +## In there,set the include path,for FrameLib use + +compiler.FrameLib.c.flags="-I{build.system.path}\Drivers\CMSIS\Include" "-I{build.system.path}\AT32F403A" "-I{build.system.path}\Drivers\Firmware\inc" "-I{build.system.path}\libcore" "-I{build.system.path}\libcore\config" + +##===============================================## + +recipe.S.o.pattern="{compiler.path}{compiler.asm.cmd}" {compiler.asm.flags} -mcpu={build.mcu} -c "{source_file}" -o "{object_file}" + +recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO_{build.board} -DF_PLL_CLOCK_SOURCE={build.f_pll_clock_source} -DF_PLL_MULT={build.f_pll_mult} -DF_PLL_OUTPUT_RANGE={build.f_pll_output_range} -DF_HEXT_DIV={build.f_hext_div} -DF_HSI_DIV={build.f_hsi_div} {build.extra_flags} {compiler.FrameLib.c.flags} {includes} -c "{source_file}" -o "{object_file}" + +recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO_{build.board} -DF_PLL_CLOCK_SOURCE={build.f_pll_clock_source} -DF_PLL_MULT={build.f_pll_mult} -DF_PLL_OUTPUT_RANGE={build.f_pll_output_range} -DF_HEXT_DIV={build.f_hext_div} -DF_HSI_DIV={build.f_hsi_div} {build.extra_flags} {compiler.FrameLib.c.flags} {includes} -c "{source_file}" -o "{object_file}" + +recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} "{archive_file_path}" "{object_file}" + +recipe.c.combine.pattern="{compiler.path}{compiler.elf.cmd}" {compiler.elf.flags} -mcpu={build.mcu} "-L{build.variant.path}" "-T{build.variant.path}\{build.ldscript}" {object_files} "{archive_file_path}" "{build.variant.path}\{build.variant_system_lib}" -o "{build.path}/{build.project_name}.elf" +##recipe.c.combine.pattern="{compiler.path}{compiler.elf.cmd}" {compiler.elf.flags} -mcpu={build.mcu} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group {object_files} -Wl,--whole-archive "{archive_file_path}" -Wl,--no-whole-archive -Wl,--end-group + +recipe.objcopy.eep.pattern= + +recipe.objcopy.hex.pattern="{compiler.path}{compiler.hex.cmd}" {compiler.hex.flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex" + +recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" + +recipe.size.regex=\.text\s+([0-9]+).* + + +# Uploader tools +# ------------------- + +tools.Artery_ISP_Console.cmd=WeAct Studio Download Tool.bat +tools.Artery_ISP_Console.cmd.windows=WeAct Studio Download Tool.bat +tools.Artery_ISP_Console.path={runtime.tools.Artery_ISP_Console.path} + +tools.Artery_ISP_Console.upload.params.verbose=-d +tools.Artery_ISP_Console.upload.params.quiet= +tools.Artery_ISP_Console.upload.pattern="{path}\{cmd}" "{build.path}/{build.project_name}.hex" \ No newline at end of file diff --git a/ArduinoCore-AT32F403A/system/AT32F403A/syscall.c b/ArduinoCore-AT32F403A/system/AT32F403A/syscall.c new file mode 100644 index 0000000..9e14ee0 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/AT32F403A/syscall.c @@ -0,0 +1,108 @@ +/** + * \file syscalls_at32.c + * + * Implementation of newlib syscall. + * + */ +#include "at32f403a_407.h" +#include "at32f403a_407_conf.h" +// #if defined ( __GNUC__ ) /* GCC CS3 */ +#include +// #endif +#include +#undef errno +extern int errno; + +extern size_t uart_debug_write(uint8_t *data, uint32_t size); + +// Helper macro to mark unused parameters and prevent compiler warnings. +// Appends _UNUSED to the variable name to prevent accidentally using them. +#ifdef UNUSED + #undef UNUSED +#endif +#ifdef __GNUC__ + #define UNUSED(x) x ## _UNUSED __attribute__((__unused__)) +#else + #define UNUSED(x) x ## _UNUSED +#endif + +__attribute__((weak)) +caddr_t _sbrk(int incr) +{ + extern char _estack; /* Defined in the linker script */ + extern char _Min_Stack_Size; /* Defined in the linker script */ + extern char _end; /* Defined by the linker */ + static char *heap_end = &_end ; + char *prev_heap_end = heap_end; + + if (heap_end + incr > (char *)__get_MSP()) { + /* Heap and stack collision */ + errno = ENOMEM; + return (caddr_t) -1; + } + /* Ensure to keep minimum stack size defined in the linker script */ + if (heap_end + incr >= (char *)(&_estack - &_Min_Stack_Size)) { + errno = ENOMEM; + return (caddr_t) -1; + } + + heap_end += incr ; + return (caddr_t) prev_heap_end ; +} + +__attribute__((weak)) +int _close(UNUSED(int file)) +{ + return -1; +} + +__attribute__((weak)) +int _fstat(UNUSED(int file), struct stat *st) +{ + st->st_mode = S_IFCHR ; + return 0; +} + +__attribute__((weak)) +int _isatty(UNUSED(int file)) +{ + return 1; +} + +__attribute__((weak)) +int _lseek(UNUSED(int file), UNUSED(int ptr), UNUSED(int dir)) +{ + return 0; +} + +__attribute__((weak)) +int _read(UNUSED(int file), UNUSED(char *ptr), UNUSED(int len)) +{ + return 0; +} + +/* Moved to Print.cpp to support Print::printf() +__attribute__((weak)) +int _write(UNUSED(int file), char *ptr, int len) +{ +} +*/ + +__attribute__((weak)) +void _exit(UNUSED(int status)) +{ + for (; ;) ; +} + +__attribute__((weak)) +int _kill(UNUSED(int pid), UNUSED(int sig)) +{ + errno = EINVAL; + return -1; +} + +__attribute__((weak)) +int _getpid(void) +{ + return 1; +} \ No newline at end of file diff --git a/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/at32f403a_407.h b/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/at32f403a_407.h new file mode 100644 index 0000000..2b73416 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/at32f403a_407.h @@ -0,0 +1,575 @@ +/** + ************************************************************************** + * @file at32f403a_407.h + * @version v2.0.9 + * @date 2022-04-25 + * @brief at32f403a_407 header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ +#ifndef __AT32F403A_407_H +#define __AT32F403A_407_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (__CC_ARM) + #pragma anon_unions +#endif + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup AT32F403A_407 + * @{ + */ + +/** @addtogroup Library_configuration_section + * @{ + */ + +/** + * tip: to avoid modifying this file each time you need to switch between these + * devices, you can define the device in your toolchain compiler preprocessor. + */ + +#if !defined (AT32F403AVCT7) && !defined (AT32F403ARCT7) && !defined (AT32F403ACCT7) && \ + !defined (AT32F403ACCU7) && !defined (AT32F403AVGT7) && !defined (AT32F403ACGT7) && \ + !defined (AT32F403ARGT7) && !defined (AT32F403ACGU7) && !defined (AT32F403AVET7) && \ + !defined (AT32F403ARET7) && !defined (AT32F403ACET7) && !defined (AT32F403ACEU7) && \ + !defined (AT32F407RGT7) && !defined (AT32F407VGT7) && !defined (AT32F407RCT7) && \ + !defined (AT32F407VCT7) && !defined (AT32F407RET7) && !defined (AT32F407VET7) && \ + !defined (AT32F407AVCT7) && !defined (AT32F407AVGT7) + + #error "Please select first the target device used in your application (in at32f403a_407.h file)" +#endif + +#if defined (AT32F403AVCT7) || defined (AT32F403ARCT7) || defined (AT32F403ACCT7) || \ + defined (AT32F403ACCU7) || defined (AT32F403AVGT7) || defined (AT32F403ACGT7) || \ + defined (AT32F403ARGT7) || defined (AT32F403ACGU7) || defined (AT32F403AVET7) || \ + defined (AT32F403ACET7) || defined (AT32F403ARET7) || defined (AT32F403ACEU7) + + #define AT32F403Axx +#endif + +#if defined (AT32F407RGT7) || defined (AT32F407VGT7) || defined (AT32F407RCT7) || \ + defined (AT32F407VCT7) || defined (AT32F407VET7) || defined (AT32F407RET7) || \ + defined (AT32F407AVCT7) || defined (AT32F407AVGT7) + + #define AT32F407xx +#endif + +#ifndef USE_STDPERIPH_DRIVER +/** + * @brief comment the line below if you will not use the peripherals drivers. + * in this case, these drivers will not be included and the application code will + * be based on direct access to peripherals registers + */ + #ifdef _RTE_ + #include "RTE_Components.h" + #ifdef RTE_DEVICE_STDPERIPH_FRAMEWORK + #define USE_STDPERIPH_DRIVER + #endif + #endif +#endif + +/** + * @brief at32f403a_407 standard peripheral library version number + */ +#define __AT32F403A_407_LIBRARY_VERSION_MAJOR (0x02) /*!< [31:24] major version */ +#define __AT32F403A_407_LIBRARY_VERSION_MIDDLE (0x00) /*!< [23:16] middle version */ +#define __AT32F403A_407_LIBRARY_VERSION_MINOR (0x09) /*!< [15:8] minor version */ +#define __AT32F403A_407_LIBRARY_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __AT32F403A_407_LIBRARY_VERSION ((__AT32F403A_407_LIBRARY_VERSION_MAJOR << 24) | \ + (__AT32F403A_407_LIBRARY_VERSION_MIDDLE << 16) | \ + (__AT32F403A_407_LIBRARY_VERSION_MINOR << 8) | \ + (__AT32F403A_407_LIBRARY_VERSION_RC)) + +/** + * @} + */ + +/** @addtogroup Configuration_section_for_CMSIS + * @{ + */ + +/** + * @brief configuration of the cortex-m4 processor and core peripherals + */ +#define __CM4_REV 0x0001U /*!< core revision r0p1 */ +#define __MPU_PRESENT 1 /*!< mpu present */ +#define __NVIC_PRIO_BITS 4 /*!< at32 uses 4 bits for the priority levels */ +#define __Vendor_SysTickConfig 0 /*!< set to 1 if different systick config is used */ +#define __FPU_PRESENT 1U /*!< fpu present */ + +/** + * @brief at32f403a_407 interrupt number definition, according to the selected device + * in @ref Library_configuration_section + */ +typedef enum IRQn +{ + /****** cortex-m4 processor exceptions numbers ***************************************************/ + Reset_IRQn = -15, /*!< 1 reset vector, invoked on power up and warm reset */ + NonMaskableInt_IRQn = -14, /*!< 2 non maskable interrupt */ + HardFault_IRQn = -13, /*!< 3 hard fault, all classes of fault */ + MemoryManagement_IRQn = -12, /*!< 4 cortex-m4 memory management interrupt */ + BusFault_IRQn = -11, /*!< 5 cortex-m4 bus fault interrupt */ + UsageFault_IRQn = -10, /*!< 6 cortex-m4 usage fault interrupt */ + SVCall_IRQn = -5, /*!< 11 cortex-m4 sv call interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 cortex-m4 debug monitor interrupt */ + PendSV_IRQn = -2, /*!< 14 cortex-m4 pend sv interrupt */ + SysTick_IRQn = -1, /*!< 15 cortex-m4 system tick interrupt */ + + /****** at32 specific interrupt numbers *********************************************************/ + WWDT_IRQn = 0, /*!< window watchdog timer interrupt */ + PVM_IRQn = 1, /*!< pvm through exint line detection interrupt */ + TAMPER_IRQn = 2, /*!< tamper interrupt */ + RTC_IRQn = 3, /*!< rtc global interrupt */ + FLASH_IRQn = 4, /*!< flash global interrupt */ + CRM_IRQn = 5, /*!< crm global interrupt */ + EXINT0_IRQn = 6, /*!< external line0 interrupt */ + EXINT1_IRQn = 7, /*!< external line1 interrupt */ + EXINT2_IRQn = 8, /*!< external line2 interrupt */ + EXINT3_IRQn = 9, /*!< external line3 interrupt */ + EXINT4_IRQn = 10, /*!< external line4 interrupt */ + DMA1_Channel1_IRQn = 11, /*!< dma1 channel 1 global interrupt */ + DMA1_Channel2_IRQn = 12, /*!< dma1 channel 2 global interrupt */ + DMA1_Channel3_IRQn = 13, /*!< dma1 channel 3 global interrupt */ + DMA1_Channel4_IRQn = 14, /*!< dma1 channel 4 global interrupt */ + DMA1_Channel5_IRQn = 15, /*!< dma1 channel 5 global interrupt */ + DMA1_Channel6_IRQn = 16, /*!< dma1 channel 6 global interrupt */ + DMA1_Channel7_IRQn = 17, /*!< dma1 channel 7 global interrupt */ + +#if defined (AT32F403Axx) + ADC1_2_IRQn = 18, /*!< adc1 and adc2 global interrupt */ + USBFS_H_CAN1_TX_IRQn = 19, /*!< usb device high priority or can1 tx interrupts */ + USBFS_L_CAN1_RX0_IRQn = 20, /*!< usb device low priority or can1 rx0 interrupts */ + CAN1_RX1_IRQn = 21, /*!< can1 rx1 interrupt */ + CAN1_SE_IRQn = 22, /*!< can1 se interrupt */ + EXINT9_5_IRQn = 23, /*!< external line[9:5] interrupts */ + TMR1_BRK_TMR9_IRQn = 24, /*!< tmr1 brake interrupt */ + TMR1_OVF_TMR10_IRQn = 25, /*!< tmr1 overflow interrupt */ + TMR1_TRG_HALL_TMR11_IRQn = 26, /*!< tmr1 trigger and hall interrupt */ + TMR1_CH_IRQn = 27, /*!< tmr1 channel interrupt */ + TMR2_GLOBAL_IRQn = 28, /*!< tmr2 global interrupt */ + TMR3_GLOBAL_IRQn = 29, /*!< tmr3 global interrupt */ + TMR4_GLOBAL_IRQn = 30, /*!< tmr4 global interrupt */ + I2C1_EVT_IRQn = 31, /*!< i2c1 event interrupt */ + I2C1_ERR_IRQn = 32, /*!< i2c1 error interrupt */ + I2C2_EVT_IRQn = 33, /*!< i2c2 event interrupt */ + I2C2_ERR_IRQn = 34, /*!< i2c2 error interrupt */ + SPI1_IRQn = 35, /*!< spi1 global interrupt */ + SPI2_I2S2EXT_IRQn = 36, /*!< spi2 global interrupt */ + USART1_IRQn = 37, /*!< usart1 global interrupt */ + USART2_IRQn = 38, /*!< usart2 global interrupt */ + USART3_IRQn = 39, /*!< usart3 global interrupt */ + EXINT15_10_IRQn = 40, /*!< external line[15:10] interrupts */ + RTCAlarm_IRQn = 41, /*!< rtc alarm through exint line interrupt */ + USBFSWakeUp_IRQn = 42, /*!< usb device wakeup from suspend through exint line interrupt */ + TMR8_BRK_TMR12_IRQn = 43, /*!< tmr8 brake interrupt */ + TMR8_OVF_TMR13_IRQn = 44, /*!< tmr8 overflow interrupt */ + TMR8_TRG_HALL_TMR14_IRQn = 45, /*!< tmr8 trigger and hall interrupt */ + TMR8_CH_IRQn = 46, /*!< tmr8 channel interrupt */ + ADC3_IRQn = 47, /*!< adc3 global interrupt */ + XMC_IRQn = 48, /*!< xmc global interrupt */ + SDIO1_IRQn = 49, /*!< sdio1 global interrupt */ + TMR5_GLOBAL_IRQn = 50, /*!< tmr5 global interrupt */ + SPI3_I2S3EXT_IRQn = 51, /*!< spi3 global interrupt */ + UART4_IRQn = 52, /*!< uart4 global interrupt */ + UART5_IRQn = 53, /*!< uart5 global interrupt */ + TMR6_GLOBAL_IRQn = 54, /*!< tmr6 global interrupt */ + TMR7_GLOBAL_IRQn = 55, /*!< tmr7 global interrupt */ + DMA2_Channel1_IRQn = 56, /*!< dma2 channel 1 global interrupt */ + DMA2_Channel2_IRQn = 57, /*!< dma2 channel 2 global interrupt */ + DMA2_Channel3_IRQn = 58, /*!< dma2 channel 3 global interrupt */ + DMA2_Channel4_5_IRQn = 59, /*!< dma2 channel 4 and channel 5 global interrupt */ + SDIO2_IRQn = 60, /*!< sdio2 global interrupt */ + I2C3_EVT_IRQn = 61, /*!< i2c3 event interrupt */ + I2C3_ERR_IRQn = 62, /*!< i2c3 error interrupt */ + SPI4_IRQn = 63, /*!< spi4 global interrupt */ + CAN2_TX_IRQn = 68, /*!< can2 tx interrupt */ + CAN2_RX0_IRQn = 69, /*!< can2 rx0 interrupt */ + CAN2_RX1_IRQn = 70, /*!< can2 rx1 interrupt */ + CAN2_SE_IRQn = 71, /*!< can2 se interrupt */ + ACC_IRQn = 72, /*!< acc interrupt */ + USBFS_MAPH_IRQn = 73, /*!< usb map hp interrupt */ + USBFS_MAPL_IRQn = 74, /*!< usb map lp interrupt */ + DMA2_Channel6_7_IRQn = 75, /*!< dma2 channel 6 and channel 7 global interrupt */ + USART6_IRQn = 76, /*!< usart6 interrupt */ + UART7_IRQn = 77, /*!< uart7 interrupt */ + UART8_IRQn = 78, /*!< uart8 interrupt */ +#endif + +#if defined (AT32F407xx) + ADC1_2_IRQn = 18, /*!< adc1 and adc2 global interrupt */ + USBFS_H_CAN1_TX_IRQn = 19, /*!< usb device high priority or can1 tx interrupts */ + USBFS_L_CAN1_RX0_IRQn = 20, /*!< usb device low priority or can1 rx0 interrupts */ + CAN1_RX1_IRQn = 21, /*!< can1 rx1 interrupt */ + CAN1_SE_IRQn = 22, /*!< can1 se interrupt */ + EXINT9_5_IRQn = 23, /*!< external line[9:5] interrupts */ + TMR1_BRK_TMR9_IRQn = 24, /*!< tmr1 brake interrupt */ + TMR1_OVF_TMR10_IRQn = 25, /*!< tmr1 overflow interrupt */ + TMR1_TRG_HALL_TMR11_IRQn = 26, /*!< tmr1 trigger and hall interrupt */ + TMR1_CH_IRQn = 27, /*!< tmr1 channel interrupt */ + TMR2_GLOBAL_IRQn = 28, /*!< tmr2 global interrupt */ + TMR3_GLOBAL_IRQn = 29, /*!< tmr3 global interrupt */ + TMR4_GLOBAL_IRQn = 30, /*!< tmr4 global interrupt */ + I2C1_EVT_IRQn = 31, /*!< i2c1 event interrupt */ + I2C1_ERR_IRQn = 32, /*!< i2c1 error interrupt */ + I2C2_EVT_IRQn = 33, /*!< i2c2 event interrupt */ + I2C2_ERR_IRQn = 34, /*!< i2c2 error interrupt */ + SPI1_IRQn = 35, /*!< spi1 global interrupt */ + SPI2_I2S2EXT_IRQn = 36, /*!< spi2 global interrupt */ + USART1_IRQn = 37, /*!< usart1 global interrupt */ + USART2_IRQn = 38, /*!< usart2 global interrupt */ + USART3_IRQn = 39, /*!< usart3 global interrupt */ + EXINT15_10_IRQn = 40, /*!< external line[15:10] interrupts */ + RTCAlarm_IRQn = 41, /*!< rtc alarm through exint line interrupt */ + USBFSWakeUp_IRQn = 42, /*!< usb device wakeup from suspend through exint line interrupt */ + TMR8_BRK_TMR12_IRQn = 43, /*!< tmr8 brake interrupt */ + TMR8_OVF_TMR13_IRQn = 44, /*!< tmr8 overflow interrupt */ + TMR8_TRG_HALL_TMR14_IRQn = 45, /*!< tmr8 trigger and hall interrupt */ + TMR8_CH_IRQn = 46, /*!< tmr8 channel interrupt */ + ADC3_IRQn = 47, /*!< adc3 global interrupt */ + XMC_IRQn = 48, /*!< xmc global interrupt */ + SDIO1_IRQn = 49, /*!< sdio1 global interrupt */ + TMR5_GLOBAL_IRQn = 50, /*!< tmr5 global interrupt */ + SPI3_I2S3EXT_IRQn = 51, /*!< spi3 global interrupt */ + UART4_IRQn = 52, /*!< uart4 global interrupt */ + UART5_IRQn = 53, /*!< uart5 global interrupt */ + TMR6_GLOBAL_IRQn = 54, /*!< tmr6 global interrupt */ + TMR7_GLOBAL_IRQn = 55, /*!< tmr7 global interrupt */ + DMA2_Channel1_IRQn = 56, /*!< dma2 channel 1 global interrupt */ + DMA2_Channel2_IRQn = 57, /*!< dma2 channel 2 global interrupt */ + DMA2_Channel3_IRQn = 58, /*!< dma2 channel 3 global interrupt */ + DMA2_Channel4_5_IRQn = 59, /*!< dma2 channel 4 and channel 5 global interrupt */ + SDIO2_IRQn = 60, /*!< sdio2 global interrupt */ + I2C3_EVT_IRQn = 61, /*!< i2c3 event interrupt */ + I2C3_ERR_IRQn = 62, /*!< i2c3 error interrupt */ + SPI4_IRQn = 63, /*!< spi4 global interrupt */ + CAN2_TX_IRQn = 68, /*!< can2 tx interrupt */ + CAN2_RX0_IRQn = 69, /*!< can2 rx0 interrupt */ + CAN2_RX1_IRQn = 70, /*!< can2 rx1 interrupt */ + CAN2_SE_IRQn = 71, /*!< can2 se interrupt */ + ACC_IRQn = 72, /*!< acc interrupt */ + USBFS_MAPH_IRQn = 73, /*!< usb map hp interrupt */ + USBFS_MAPL_IRQn = 74, /*!< usb map lp interrupt */ + DMA2_Channel6_7_IRQn = 75, /*!< dma2 channel 6 and channel 7 global interrupt */ + USART6_IRQn = 76, /*!< usart6 interrupt */ + UART7_IRQn = 77, /*!< uart7 interrupt */ + UART8_IRQn = 78, /*!< uart8 interrupt */ + EMAC_IRQn = 79, /*!< emac interrupt */ + EMAC_WKUP_IRQn = 80, /*!< emac wakeup interrupt */ +#endif + +} IRQn_Type; + +/** + * @} + */ + +#include "core_cm4.h" +#include "system_at32f403a_407.h" +#include + +/** @addtogroup Exported_types + * @{ + */ + +typedef int32_t INT32; +typedef int16_t INT16; +typedef int8_t INT8; +typedef uint32_t UINT32; +typedef uint16_t UINT16; +typedef uint8_t UINT8; + +typedef int32_t s32; +typedef int16_t s16; +typedef int8_t s8; + +typedef const int32_t sc32; /*!< read only */ +typedef const int16_t sc16; /*!< read only */ +typedef const int8_t sc8; /*!< read only */ + +typedef __IO int32_t vs32; +typedef __IO int16_t vs16; +typedef __IO int8_t vs8; + +typedef __I int32_t vsc32; /*!< read only */ +typedef __I int16_t vsc16; /*!< read only */ +typedef __I int8_t vsc8; /*!< read only */ + +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +typedef const uint32_t uc32; /*!< read only */ +typedef const uint16_t uc16; /*!< read only */ +typedef const uint8_t uc8; /*!< read only */ + +typedef __IO uint32_t vu32; +typedef __IO uint16_t vu16; +typedef __IO uint8_t vu8; + +typedef __I uint32_t vuc32; /*!< read only */ +typedef __I uint16_t vuc16; /*!< read only */ +typedef __I uint8_t vuc8; /*!< read only */ + +/** + * @brief flag status + */ +typedef enum {RESET = 0, SET = !RESET} flag_status; + +/** + * @brief confirm state + */ +typedef enum {FALSE = 0, TRUE = !FALSE} confirm_state; + +/** + * @brief error status + */ +typedef enum {ERROR = 0, SUCCESS = !ERROR} error_status; + +/** + * @} + */ + +/** @addtogroup Exported_macro + * @{ + */ + +#define REG8(addr) *(volatile uint8_t *)(addr) +#define REG16(addr) *(volatile uint16_t *)(addr) +#define REG32(addr) *(volatile uint32_t *)(addr) + +#define MAKE_VALUE(reg_offset, bit_num) (uint32_t)(((reg_offset) << 16) | (bit_num & 0x1F)) + +#define PERIPH_REG(periph_base, value) REG32((periph_base + (value >> 16))) +#define PERIPH_REG_BIT(value) (0x1U << (value & 0x1F)) + +/** + * @} + */ + +/** @addtogroup Peripheral_memory_map + * @{ + */ + +#define FLASH_BASE ((uint32_t)0x08000000) +#define SPIM_FLASH_BASE ((uint32_t)0x08400000) +#define USD_BASE ((uint32_t)0x1FFFF800) +#define SRAM_BASE ((uint32_t)0x20000000) +#define PERIPH_BASE ((uint32_t)0x40000000) +#define XMC_REG_BASE ((uint32_t)0xA0000000) +#define DEBUG_BASE ((uint32_t)0xE0042000) + +#define APB1PERIPH_BASE (PERIPH_BASE + 0x00000) +#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) +#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) + +#if defined (AT32F403Axx) +/* apb1 bus base address */ +#define TMR2_BASE (APB1PERIPH_BASE + 0x0000) +#define TMR3_BASE (APB1PERIPH_BASE + 0x0400) +#define TMR4_BASE (APB1PERIPH_BASE + 0x0800) +#define TMR5_BASE (APB1PERIPH_BASE + 0x0C00) +#define TMR6_BASE (APB1PERIPH_BASE + 0x1000) +#define TMR7_BASE (APB1PERIPH_BASE + 0x1400) +#define TMR12_BASE (APB1PERIPH_BASE + 0x1800) +#define TMR13_BASE (APB1PERIPH_BASE + 0x1C00) +#define TMR14_BASE (APB1PERIPH_BASE + 0x2000) +#define RTC_BASE (APB1PERIPH_BASE + 0x2800) +#define WWDT_BASE (APB1PERIPH_BASE + 0x2C00) +#define WDT_BASE (APB1PERIPH_BASE + 0x3000) +#define SPI2_BASE (APB1PERIPH_BASE + 0x3800) +#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00) +#define SPI4_BASE (APB1PERIPH_BASE + 0x4000) +#define USART2_BASE (APB1PERIPH_BASE + 0x4400) +#define USART3_BASE (APB1PERIPH_BASE + 0x4800) +#define UART4_BASE (APB1PERIPH_BASE + 0x4C00) +#define UART5_BASE (APB1PERIPH_BASE + 0x5000) +#define I2C1_BASE (APB1PERIPH_BASE + 0x5400) +#define I2C2_BASE (APB1PERIPH_BASE + 0x5800) +#define USBFS_BASE (APB1PERIPH_BASE + 0x5C00) +#define CAN1_BASE (APB1PERIPH_BASE + 0x6400) +#define CAN2_BASE (APB1PERIPH_BASE + 0x6800) +#define BPR_BASE (APB1PERIPH_BASE + 0x6C00) +#define PWC_BASE (APB1PERIPH_BASE + 0x7000) +#define DAC_BASE (APB1PERIPH_BASE + 0x7400) +/* apb2 bus base address */ +#define IOMUX_BASE (APB2PERIPH_BASE + 0x0000) +#define EXINT_BASE (APB2PERIPH_BASE + 0x0400) +#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) +#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00) +#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000) +#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400) +#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800) +#define ADC1_BASE (APB2PERIPH_BASE + 0x2400) +#define ADC2_BASE (APB2PERIPH_BASE + 0x2800) +#define TMR1_BASE (APB2PERIPH_BASE + 0x2C00) +#define SPI1_BASE (APB2PERIPH_BASE + 0x3000) +#define TMR8_BASE (APB2PERIPH_BASE + 0x3400) +#define USART1_BASE (APB2PERIPH_BASE + 0x3800) +#define ADC3_BASE (APB2PERIPH_BASE + 0x3C00) +#define TMR9_BASE (APB2PERIPH_BASE + 0x4C00) +#define TMR10_BASE (APB2PERIPH_BASE + 0x5000) +#define TMR11_BASE (APB2PERIPH_BASE + 0x5400) +#define ACC_BASE (APB2PERIPH_BASE + 0x5800) +#define I2C3_BASE (APB2PERIPH_BASE + 0x5C00) +#define USART6_BASE (APB2PERIPH_BASE + 0x6000) +#define UART7_BASE (APB2PERIPH_BASE + 0x6400) +#define UART8_BASE (APB2PERIPH_BASE + 0x6800) +#define I2S2EXT_BASE (APB2PERIPH_BASE + 0x6C00) +#define I2S3EXT_BASE (APB2PERIPH_BASE + 0x7000) +#define SDIO1_BASE (APB2PERIPH_BASE + 0x8000) +/* ahb bus base address */ +#define DMA1_BASE (AHBPERIPH_BASE + 0x0000) +#define DMA1_CHANNEL1_BASE (AHBPERIPH_BASE + 0x0008) +#define DMA1_CHANNEL2_BASE (AHBPERIPH_BASE + 0x001C) +#define DMA1_CHANNEL3_BASE (AHBPERIPH_BASE + 0x0030) +#define DMA1_CHANNEL4_BASE (AHBPERIPH_BASE + 0x0044) +#define DMA1_CHANNEL5_BASE (AHBPERIPH_BASE + 0x0058) +#define DMA1_CHANNEL6_BASE (AHBPERIPH_BASE + 0x006C) +#define DMA1_CHANNEL7_BASE (AHBPERIPH_BASE + 0x0080) +#define DMA2_BASE (AHBPERIPH_BASE + 0x0400) +#define DMA2_CHANNEL1_BASE (AHBPERIPH_BASE + 0x0408) +#define DMA2_CHANNEL2_BASE (AHBPERIPH_BASE + 0x041C) +#define DMA2_CHANNEL3_BASE (AHBPERIPH_BASE + 0x0430) +#define DMA2_CHANNEL4_BASE (AHBPERIPH_BASE + 0x0444) +#define DMA2_CHANNEL5_BASE (AHBPERIPH_BASE + 0x0458) +#define DMA2_CHANNEL6_BASE (AHBPERIPH_BASE + 0x046C) +#define DMA2_CHANNEL7_BASE (AHBPERIPH_BASE + 0x0480) +#define CRM_BASE (AHBPERIPH_BASE + 0x1000) +#define FLASH_REG_BASE (AHBPERIPH_BASE + 0x2000) +#define CRC_BASE (AHBPERIPH_BASE + 0x3000) +#define SDIO2_BASE (AHBPERIPH_BASE + 0x3400) +#define XMC_BANK1_REG_BASE (XMC_REG_BASE + 0x0000) +#define XMC_BANK1E_REG_BASE (XMC_REG_BASE + 0x0104) +#define XMC_BANK1E_H_BASE (XMC_REG_BASE + 0x0220) +#define XMC_BANK2_REG_BASE (XMC_REG_BASE + 0x0060) +#define XMC_BANK3_REG_BASE (XMC_REG_BASE + 0x0080) +#define XMC_BANK4_REG_BASE (XMC_REG_BASE + 0x00A0) +#endif + +#if defined (AT32F407xx) +/* apb1 bus base address */ +#define TMR2_BASE (APB1PERIPH_BASE + 0x0000) +#define TMR3_BASE (APB1PERIPH_BASE + 0x0400) +#define TMR4_BASE (APB1PERIPH_BASE + 0x0800) +#define TMR5_BASE (APB1PERIPH_BASE + 0x0C00) +#define TMR6_BASE (APB1PERIPH_BASE + 0x1000) +#define TMR7_BASE (APB1PERIPH_BASE + 0x1400) +#define TMR12_BASE (APB1PERIPH_BASE + 0x1800) +#define TMR13_BASE (APB1PERIPH_BASE + 0x1C00) +#define TMR14_BASE (APB1PERIPH_BASE + 0x2000) +#define RTC_BASE (APB1PERIPH_BASE + 0x2800) +#define WWDT_BASE (APB1PERIPH_BASE + 0x2C00) +#define WDT_BASE (APB1PERIPH_BASE + 0x3000) +#define SPI2_BASE (APB1PERIPH_BASE + 0x3800) +#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00) +#define SPI4_BASE (APB1PERIPH_BASE + 0x4000) +#define USART2_BASE (APB1PERIPH_BASE + 0x4400) +#define USART3_BASE (APB1PERIPH_BASE + 0x4800) +#define UART4_BASE (APB1PERIPH_BASE + 0x4C00) +#define UART5_BASE (APB1PERIPH_BASE + 0x5000) +#define I2C1_BASE (APB1PERIPH_BASE + 0x5400) +#define I2C2_BASE (APB1PERIPH_BASE + 0x5800) +#define USBFS_BASE (APB1PERIPH_BASE + 0x5C00) +#define CAN1_BASE (APB1PERIPH_BASE + 0x6400) +#define CAN2_BASE (APB1PERIPH_BASE + 0x6800) +#define BPR_BASE (APB1PERIPH_BASE + 0x6C00) +#define PWC_BASE (APB1PERIPH_BASE + 0x7000) +#define DAC_BASE (APB1PERIPH_BASE + 0x7400) +/* apb2 bus base address */ +#define IOMUX_BASE (APB2PERIPH_BASE + 0x0000) +#define EXINT_BASE (APB2PERIPH_BASE + 0x0400) +#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) +#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00) +#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000) +#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400) +#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800) +#define ADC1_BASE (APB2PERIPH_BASE + 0x2400) +#define ADC2_BASE (APB2PERIPH_BASE + 0x2800) +#define TMR1_BASE (APB2PERIPH_BASE + 0x2C00) +#define SPI1_BASE (APB2PERIPH_BASE + 0x3000) +#define TMR8_BASE (APB2PERIPH_BASE + 0x3400) +#define USART1_BASE (APB2PERIPH_BASE + 0x3800) +#define ADC3_BASE (APB2PERIPH_BASE + 0x3C00) +#define TMR9_BASE (APB2PERIPH_BASE + 0x4C00) +#define TMR10_BASE (APB2PERIPH_BASE + 0x5000) +#define TMR11_BASE (APB2PERIPH_BASE + 0x5400) +#define ACC_BASE (APB2PERIPH_BASE + 0x5800) +#define I2C3_BASE (APB2PERIPH_BASE + 0x5C00) +#define USART6_BASE (APB2PERIPH_BASE + 0x6000) +#define UART7_BASE (APB2PERIPH_BASE + 0x6400) +#define UART8_BASE (APB2PERIPH_BASE + 0x6800) +#define I2S2EXT_BASE (APB2PERIPH_BASE + 0x6C00) +#define I2S3EXT_BASE (APB2PERIPH_BASE + 0x7000) +#define SDIO1_BASE (APB2PERIPH_BASE + 0x8000) +/* ahb bus base address */ +#define DMA1_BASE (AHBPERIPH_BASE + 0x0000) +#define DMA1_CHANNEL1_BASE (AHBPERIPH_BASE + 0x0008) +#define DMA1_CHANNEL2_BASE (AHBPERIPH_BASE + 0x001C) +#define DMA1_CHANNEL3_BASE (AHBPERIPH_BASE + 0x0030) +#define DMA1_CHANNEL4_BASE (AHBPERIPH_BASE + 0x0044) +#define DMA1_CHANNEL5_BASE (AHBPERIPH_BASE + 0x0058) +#define DMA1_CHANNEL6_BASE (AHBPERIPH_BASE + 0x006C) +#define DMA1_CHANNEL7_BASE (AHBPERIPH_BASE + 0x0080) +#define DMA2_BASE (AHBPERIPH_BASE + 0x0400) +#define DMA2_CHANNEL1_BASE (AHBPERIPH_BASE + 0x0408) +#define DMA2_CHANNEL2_BASE (AHBPERIPH_BASE + 0x041C) +#define DMA2_CHANNEL3_BASE (AHBPERIPH_BASE + 0x0430) +#define DMA2_CHANNEL4_BASE (AHBPERIPH_BASE + 0x0444) +#define DMA2_CHANNEL5_BASE (AHBPERIPH_BASE + 0x0458) +#define DMA2_CHANNEL6_BASE (AHBPERIPH_BASE + 0x046C) +#define DMA2_CHANNEL7_BASE (AHBPERIPH_BASE + 0x0480) +#define CRM_BASE (AHBPERIPH_BASE + 0x1000) +#define FLASH_REG_BASE (AHBPERIPH_BASE + 0x2000) +#define CRC_BASE (AHBPERIPH_BASE + 0x3000) +#define SDIO2_BASE (AHBPERIPH_BASE + 0x3400) +#define EMAC_BASE (AHBPERIPH_BASE + 0x8000) +#define XMC_BANK1_REG_BASE (XMC_REG_BASE + 0x0000) +#define XMC_BANK2_REG_BASE (XMC_REG_BASE + 0x0060) +#define EMAC_MMC_BASE (EMAC_BASE + 0x0100) +#define EMAC_PTP_BASE (EMAC_BASE + 0x0700) +#define EMAC_DMA_BASE (EMAC_BASE + 0x1000) +#endif + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#include "at32f403a_407_def.h" +#include "at32f403a_407_conf.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/cmsis_compiler.h b/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/cmsis_compiler.h new file mode 100644 index 0000000..adbf296 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/cmsis_compiler.h @@ -0,0 +1,283 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.1.0 + * @date 09. October 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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 __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6.6 LTM (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100) + #include "cmsis_armclang_ltm.h" + + /* + * Arm Compiler above 6.10.1 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __RESTRICT + #define __RESTRICT __restrict + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/cmsis_gcc.h b/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/cmsis_gcc.h new file mode 100644 index 0000000..67bda4e --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/cmsis_gcc.h @@ -0,0 +1,2211 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.4.1 + * @date 27. May 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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 __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START + +/** + \brief Initializes data and bss sections + \details This default implementations initialized all data and additional bss + sections relying on .copy.table and .zero.table specified properly + in the used linker script. + + */ +__STATIC_FORCEINLINE __NO_RETURN void __cmsis_start(void) +{ + extern void _start(void) __NO_RETURN; + + typedef struct { + uint32_t const* src; + uint32_t* dest; + uint32_t wlen; + } __copy_table_t; + + typedef struct { + uint32_t* dest; + uint32_t wlen; + } __zero_table_t; + + extern const __copy_table_t __copy_table_start__; + extern const __copy_table_t __copy_table_end__; + extern const __zero_table_t __zero_table_start__; + extern const __zero_table_t __zero_table_end__; + + for (__copy_table_t const* pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = pTable->src[i]; + } + } + + for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = 0u; + } + } + + _start(); +} + +#define __PROGRAM_START __cmsis_start +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP __StackTop +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT __StackLimit +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section(".vectors"))) +#endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#ifndef __STACK_SEAL +#define __STACK_SEAL __StackSeal +#endif + +#ifndef __TZ_STACK_SEAL_SIZE +#define __TZ_STACK_SEAL_SIZE 8U +#endif + +#ifndef __TZ_STACK_SEAL_VALUE +#define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL +#endif + + +__STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) { + *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE; +} +#endif + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI() __ASM volatile ("wfi":::"memory") + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE() __ASM volatile ("wfe":::"memory") + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV() __ASM volatile ("sev") + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return result; +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1, ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1, ARG2) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); + __ISB(); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); + __ISB(); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#endif +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1, ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + +#define __USAT16(ARG1, ARG2) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16_RORn(uint32_t op1, uint32_t rotate) +{ + uint32_t result; + if (__builtin_constant_p(rotate) && ((rotate == 8U) || (rotate == 16U) || (rotate == 24U))) { + __ASM volatile ("sxtb16 %0, %1, ROR %2" : "=r" (result) : "r" (op1), "i" (rotate) ); + } else { + result = __SXTB16(__ROR(op1, rotate)) ; + } + return result; +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16_RORn(uint32_t op1, uint32_t op2, uint32_t rotate) +{ + uint32_t result; + if (__builtin_constant_p(rotate) && ((rotate == 8U) || (rotate == 16U) || (rotate == 24U))) { + __ASM volatile ("sxtab16 %0, %1, %2, ROR %3" : "=r" (result) : "r" (op1) , "r" (op2) , "i" (rotate)); + } else { + result = __SXTAB16(op1, __ROR(op2, rotate)); + } + return result; +} + + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +#define __PKHBT(ARG1,ARG2,ARG3) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/cmsis_version.h b/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/cmsis_version.h new file mode 100644 index 0000000..8b4765f --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/cmsis_version.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.5 + * @date 02. February 2022 + ******************************************************************************/ +/* + * Copyright (c) 2009-2022 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_VERSION_H +#define __CMSIS_VERSION_H + +/* CMSIS Version definitions */ +#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ +#define __CM_CMSIS_VERSION_SUB ( 6U) /*!< [15:0] CMSIS Core(M) sub version */ +#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ +#endif diff --git a/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/core_cm4.h b/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/core_cm4.h new file mode 100644 index 0000000..e21cd14 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/core_cm4.h @@ -0,0 +1,2129 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V5.1.2 + * @date 04. June 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M4 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (4U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000U + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and FP Feature Register 2 Definitions */ + +#define FPU_MVFR2_VFP_Misc_Pos 4U /*!< MVFR2: VFP Misc bits Position */ +#define FPU_MVFR2_VFP_Misc_Msk (0xFUL << FPU_MVFR2_VFP_Misc_Pos) /*!< MVFR2: VFP Misc bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ +#define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + /* ARM Application Note 321 states that the M4 does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/mpu_armv7.h b/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/mpu_armv7.h new file mode 100644 index 0000000..d9eedf8 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/mpu_armv7.h @@ -0,0 +1,275 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for Armv7-M MPU + * @version V5.1.2 + * @date 25. May 2020 + ******************************************************************************/ +/* + * Copyright (c) 2017-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV7_H +#define ARM_MPU_ARMV7_H + +#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes +#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes +#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes +#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes +#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes +#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte +#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes +#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes +#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes +#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes +#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes +#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes +#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes +#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes +#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes +#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte +#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes +#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes +#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes +#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes +#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes +#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes +#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes +#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes +#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes +#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte +#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes +#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes + +#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access +#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only +#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only +#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access +#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only +#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access + +/** MPU Region Base Address Register Value +* +* \param Region The region to be configured, number 0 to 15. +* \param BaseAddress The base address for the region. +*/ +#define ARM_MPU_RBAR(Region, BaseAddress) \ + (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ + ((Region) & MPU_RBAR_REGION_Msk) | \ + (MPU_RBAR_VALID_Msk)) + +/** +* MPU Memory Access Attributes +* +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +*/ +#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ + ((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ + (((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ + (((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ + (((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ + ((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ + (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ + (((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \ + (((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \ + (((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \ + (((MPU_RASR_ENABLE_Msk)))) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ + ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) + +/** +* MPU Memory Access Attribute for strongly ordered memory. +* - TEX: 000b +* - Shareable +* - Non-cacheable +* - Non-bufferable +*/ +#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) + +/** +* MPU Memory Access Attribute for device memory. +* - TEX: 000b (if shareable) or 010b (if non-shareable) +* - Shareable or non-shareable +* - Non-cacheable +* - Bufferable (if shareable) or non-bufferable (if non-shareable) +* +* \param IsShareable Configures the device memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) + +/** +* MPU Memory Access Attribute for normal memory. +* - TEX: 1BBb (reflecting outer cacheability rules) +* - Shareable or non-shareable +* - Cacheable or non-cacheable (reflecting inner cacheability rules) +* - Bufferable or non-bufferable (reflecting inner cacheability rules) +* +* \param OuterCp Configures the outer cache policy. +* \param InnerCp Configures the inner cache policy. +* \param IsShareable Configures the memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) >> 1U), ((InnerCp) & 1U)) + +/** +* MPU Memory Access Attribute non-cacheable policy. +*/ +#define ARM_MPU_CACHEP_NOCACHE 0U + +/** +* MPU Memory Access Attribute write-back, write and read allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_WRA 1U + +/** +* MPU Memory Access Attribute write-through, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WT_NWA 2U + +/** +* MPU Memory Access Attribute write-back, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_NWA 3U + + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; //!< The region base address register value (RBAR) + uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DMB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; + __DSB(); + __ISB(); +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RASR = 0U; +} + +/** Configure an MPU region. +* \param rbar Value for RBAR register. +* \param rasr Value for RASR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) +{ + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rasr Value for RASR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Memcpy with strictly ordered memory access, e.g. used by code in ARM_MPU_Load(). +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + while (cnt > MPU_TYPE_RALIASES) { + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); + table += MPU_TYPE_RALIASES; + cnt -= MPU_TYPE_RALIASES; + } + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); +} + +#endif diff --git a/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/system_at32f403a_407.h b/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/system_at32f403a_407.h new file mode 100644 index 0000000..dd23713 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/CMSIS/Include/system_at32f403a_407.h @@ -0,0 +1,86 @@ +/** + ************************************************************************** + * @file system_at32f403a_407.h + * @version v2.0.9 + * @date 2022-04-25 + * @brief cmsis cortex-m4 system header file. + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#ifndef __SYSTEM_AT32F403A_407_H +#define __SYSTEM_AT32F403A_407_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup AT32F403A_407_system + * @{ + */ + +/** @defgroup AT32F403A_407_system_clock_stable_definition + * @{ + */ + +#define HEXT_STABLE_DELAY (5000u) +#define PLL_STABLE_DELAY (500u) + +/** + * @} + */ + +/** @defgroup AT32F403A_407_system_exported_variables + * @{ + */ + +extern unsigned int system_core_clock; /*!< system clock frequency (core clock) */ + +/** + * @} + */ + +/** @defgroup AT32F403A_407_system_exported_functions + * @{ + */ + +extern void SystemInit(void); +extern void system_core_clock_update(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_acc.h b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_acc.h new file mode 100644 index 0000000..5415a24 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_acc.h @@ -0,0 +1,202 @@ +/** + ************************************************************************** + * @file at32f403a_407_acc.h + * @version v2.0.9 + * @date 2022-04-25 + * @brief at32f403a_407 acc header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_ACC_H +#define __AT32F403A_407_ACC_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f403a_407.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @addtogroup ACC + * @{ + */ + +/** @defgroup ACC_exported_constants + * @{ + */ + +#define ACC_CAL_HICKCAL ((uint16_t)0x0000) /*!< acc hick calibration */ +#define ACC_CAL_HICKTRIM ((uint16_t)0x0002) /*!< acc hick trim */ + +#define ACC_RSLOST_FLAG ((uint16_t)0x0002) /*!< acc reference signal lost error flag */ +#define ACC_CALRDY_FLAG ((uint16_t)0x0001) /*!< acc internal high-speed clock calibration ready error flag */ + +#define ACC_CALRDYIEN_INT ((uint16_t)0x0020) /*!< acc internal high-speed clock calibration ready interrupt enable */ +#define ACC_EIEN_INT ((uint16_t)0x0010) /*!< acc reference signal lost interrupt enable */ + +/** + * @} + */ + +/** @defgroup ACC_exported_types + * @{ + */ + +/** + * @brief type define acc register all + */ +typedef struct +{ + + /** + * @brief acc sts register, offset:0x00 + */ + union + { + __IO uint32_t sts; + struct + { + __IO uint32_t calrdy : 1; /* [0] */ + __IO uint32_t rslost : 1; /* [1] */ + __IO uint32_t reserved1 : 30;/* [31:2] */ + } sts_bit; + }; + + /** + * @brief acc ctrl1 register, offset:0x04 + */ + union + { + __IO uint32_t ctrl1; + struct + { + __IO uint32_t calon : 1; /* [0] */ + __IO uint32_t entrim : 1; /* [1] */ + __IO uint32_t reserved1 : 2; /* [3:2] */ + __IO uint32_t eien : 1; /* [4] */ + __IO uint32_t calrdyien : 1; /* [5] */ + __IO uint32_t reserved2 : 2; /* [7:6] */ + __IO uint32_t step : 4; /* [11:8] */ + __IO uint32_t reserved3 : 20;/* [31:12] */ + } ctrl1_bit; + }; + + /** + * @brief acc ctrl2 register, offset:0x08 + */ + union + { + __IO uint32_t ctrl2; + struct + { + __IO uint32_t hickcal : 8; /* [7:0] */ + __IO uint32_t hicktrim : 6; /* [13:8] */ + __IO uint32_t reserved1 : 18;/* [31:14] */ + } ctrl2_bit; + }; + + /** + * @brief acc acc_c1 register, offset:0x0C + */ + union + { + __IO uint32_t c1; + struct + { + __IO uint32_t c1 : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } c1_bit; + }; + + /** + * @brief acc acc_c2 register, offset:0x10 + */ + union + { + __IO uint32_t c2; + struct + { + __IO uint32_t c2 : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } c2_bit; + }; + + /** + * @brief acc acc_c3 register, offset:0x14 + */ + union + { + __IO uint32_t c3; + struct + { + __IO uint32_t c3 : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } c3_bit; + }; +} acc_type; + +/** + * @} + */ + +#define ACC ((acc_type *) ACC_BASE) + +/** @defgroup ACC_exported_functions + * @{ + */ + +void acc_calibration_mode_enable(uint16_t acc_trim, confirm_state new_state); +void acc_step_set(uint8_t step_value); +void acc_interrupt_enable(uint16_t acc_int, confirm_state new_state); +uint8_t acc_hicktrim_get(void); +uint8_t acc_hickcal_get(void); +void acc_write_c1(uint16_t acc_c1_value); +void acc_write_c2(uint16_t acc_c2_value); +void acc_write_c3(uint16_t acc_c3_value); +uint16_t acc_read_c1(void); +uint16_t acc_read_c2(void); +uint16_t acc_read_c3(void); +flag_status acc_flag_get(uint16_t acc_flag); +void acc_flag_clear(uint16_t acc_flag); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_adc.h b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_adc.h new file mode 100644 index 0000000..cb07297 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_adc.h @@ -0,0 +1,642 @@ +/** + ************************************************************************** + * @file at32f403a_407_adc.h + * @version v2.0.9 + * @date 2022-04-25 + * @brief at32f403a_407 adc header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_ADC_H +#define __AT32F403A_407_ADC_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f403a_407.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @addtogroup ADC + * @{ + */ + +/** @defgroup ADC_interrupts_definition + * @brief adc interrupt + * @{ + */ + +#define ADC_CCE_INT ((uint32_t)0x00000020) /*!< channels conversion end interrupt */ +#define ADC_VMOR_INT ((uint32_t)0x00000040) /*!< voltage monitoring out of range interrupt */ +#define ADC_PCCE_INT ((uint32_t)0x00000080) /*!< preempt channels conversion end interrupt */ + +/** + * @} + */ + +/** @defgroup ADC_flags_definition + * @brief adc flag + * @{ + */ + +#define ADC_VMOR_FLAG ((uint8_t)0x01) /*!< voltage monitoring out of range flag */ +#define ADC_CCE_FLAG ((uint8_t)0x02) /*!< channels conversion end flag */ +#define ADC_PCCE_FLAG ((uint8_t)0x04) /*!< preempt channels conversion end flag */ +#define ADC_PCCS_FLAG ((uint8_t)0x08) /*!< preempt channel conversion start flag */ +#define ADC_OCCS_FLAG ((uint8_t)0x10) /*!< ordinary channel conversion start flag */ + +/** + * @} + */ + +/** @defgroup ADC_exported_types + * @{ + */ + +/** + * @brief adc combine mode type(these options are reserved in adc2 and adc3) + */ +typedef enum +{ + ADC_INDEPENDENT_MODE = 0x00, /*!< independent mode */ + ADC_ORDINARY_SMLT_PREEMPT_SMLT_MODE = 0x01, /*!< combined ordinary simultaneous + preempt simultaneous mode */ + ADC_ORDINARY_SMLT_PREEMPT_INTERLTRIG_MODE = 0x02, /*!< combined ordinary simultaneous + preempt interleaved trigger mode */ + ADC_ORDINARY_SHORTSHIFT_PREEMPT_SMLT_MODE = 0x03, /*!< combined ordinary short shifting + preempt simultaneous mode */ + ADC_ORDINARY_LONGSHIFT_PREEMPT_SMLT_MODE = 0x04, /*!< combined ordinary long shifting + preempt simultaneous mode */ + ADC_PREEMPT_SMLT_ONLY_MODE = 0x05, /*!< preempt simultaneous mode only */ + ADC_ORDINARY_SMLT_ONLY_MODE = 0x06, /*!< ordinary simultaneous mode only */ + ADC_ORDINARY_SHORTSHIFT_ONLY_MODE = 0x07, /*!< ordinary short shifting mode only */ + ADC_ORDINARY_LONGSHIFT_ONLY_MODE = 0x08, /*!< slow interleaved mode only */ + ADC_PREEMPT_INTERLTRIG_ONLY_MODE = 0x09 /*!< alternate trigger mode only */ +} adc_combine_mode_type; + +/** + * @brief adc data align type + */ +typedef enum +{ + ADC_RIGHT_ALIGNMENT = 0x00, /*!< data right alignment */ + ADC_LEFT_ALIGNMENT = 0x01 /*!< data left alignment */ +} adc_data_align_type; + +/** + * @brief adc channel select type + */ +typedef enum +{ + ADC_CHANNEL_0 = 0x00, /*!< adc channel 0 */ + ADC_CHANNEL_1 = 0x01, /*!< adc channel 1 */ + ADC_CHANNEL_2 = 0x02, /*!< adc channel 2 */ + ADC_CHANNEL_3 = 0x03, /*!< adc channel 3 */ + ADC_CHANNEL_4 = 0x04, /*!< adc channel 4 */ + ADC_CHANNEL_5 = 0x05, /*!< adc channel 5 */ + ADC_CHANNEL_6 = 0x06, /*!< adc channel 6 */ + ADC_CHANNEL_7 = 0x07, /*!< adc channel 7 */ + ADC_CHANNEL_8 = 0x08, /*!< adc channel 8 */ + ADC_CHANNEL_9 = 0x09, /*!< adc channel 9 */ + ADC_CHANNEL_10 = 0x0A, /*!< adc channel 10 */ + ADC_CHANNEL_11 = 0x0B, /*!< adc channel 11 */ + ADC_CHANNEL_12 = 0x0C, /*!< adc channel 12 */ + ADC_CHANNEL_13 = 0x0D, /*!< adc channel 13 */ + ADC_CHANNEL_14 = 0x0E, /*!< adc channel 14 */ + ADC_CHANNEL_15 = 0x0F, /*!< adc channel 15 */ + ADC_CHANNEL_16 = 0x10, /*!< adc channel 16 */ + ADC_CHANNEL_17 = 0x11 /*!< adc channel 17 */ +} adc_channel_select_type; + +/** + * @brief adc sampletime select type + */ +typedef enum +{ + ADC_SAMPLETIME_1_5 = 0x00, /*!< adc sample time 1.5 cycle */ + ADC_SAMPLETIME_7_5 = 0x01, /*!< adc sample time 7.5 cycle */ + ADC_SAMPLETIME_13_5 = 0x02, /*!< adc sample time 13.5 cycle */ + ADC_SAMPLETIME_28_5 = 0x03, /*!< adc sample time 28.5 cycle */ + ADC_SAMPLETIME_41_5 = 0x04, /*!< adc sample time 41.5 cycle */ + ADC_SAMPLETIME_55_5 = 0x05, /*!< adc sample time 55.5 cycle */ + ADC_SAMPLETIME_71_5 = 0x06, /*!< adc sample time 71.5 cycle */ + ADC_SAMPLETIME_239_5 = 0x07 /*!< adc sample time 239.5 cycle */ +} adc_sampletime_select_type; + +/** + * @brief adc ordinary group trigger event select type + */ +typedef enum +{ + /*adc1 and adc2 ordinary trigger event*/ + ADC12_ORDINARY_TRIG_TMR1CH1 = 0x00, /*!< timer1 ch1 event as trigger source of adc1/adc2 ordinary sequence */ + ADC12_ORDINARY_TRIG_TMR1CH2 = 0x01, /*!< timer1 ch2 event as trigger source of adc1/adc2 ordinary sequence */ + ADC12_ORDINARY_TRIG_TMR1CH3 = 0x02, /*!< timer1 ch3 event as trigger source of adc1/adc2 ordinary sequence */ + ADC12_ORDINARY_TRIG_TMR2CH2 = 0x03, /*!< timer2 ch2 event as trigger source of adc1/adc2 ordinary sequence */ + ADC12_ORDINARY_TRIG_TMR3TRGOUT = 0x04, /*!< timer3 trgout event as trigger source of adc1/adc2 ordinary sequence */ + ADC12_ORDINARY_TRIG_TMR4CH4 = 0x05, /*!< timer4 ch4 event as trigger source of adc1/adc2 ordinary sequence */ + ADC12_ORDINARY_TRIG_EXINT11_TMR8TRGOUT = 0x06, /*!< exint line11/timer8 trgout event as trigger source of adc1/adc2 ordinary sequence */ + ADC12_ORDINARY_TRIG_SOFTWARE = 0x07, /*!< software(OCSWTRG) control bit as trigger source of adc1/adc2 ordinary sequence */ + ADC12_ORDINARY_TRIG_TMR1TRGOUT = 0x0D, /*!< timer1 trgout event as trigger source of adc1/adc2 ordinary sequence */ + ADC12_ORDINARY_TRIG_TMR8CH1 = 0x0E, /*!< timer8 ch1 event as trigger source of adc1/adc2 ordinary sequence */ + ADC12_ORDINARY_TRIG_TMR8CH2 = 0x0F, /*!< timer8 ch2 event as trigger source of adc1/adc2 ordinary sequence */ + /*adc3 ordinary trigger event*/ + ADC3_ORDINARY_TRIG_TMR3CH1 = 0x00, /*!< timer3 ch1 event as trigger source of adc3 ordinary sequence */ + ADC3_ORDINARY_TRIG_TMR2CH3 = 0x01, /*!< timer2 ch3 event as trigger source of adc3 ordinary sequence */ + ADC3_ORDINARY_TRIG_TMR1CH3 = 0x02, /*!< timer1 ch3 event as trigger source of adc3 ordinary sequence */ + ADC3_ORDINARY_TRIG_TMR8CH1 = 0x03, /*!< timer8 ch1 event as trigger source of adc3 ordinary sequence */ + ADC3_ORDINARY_TRIG_TMR8TRGOUT = 0x04, /*!< timer8 trgout event as trigger source of adc3 ordinary sequence */ + ADC3_ORDINARY_TRIG_TMR5CH1 = 0x05, /*!< timer5 ch1 event as trigger source of adc3 ordinary sequence */ + ADC3_ORDINARY_TRIG_TMR5CH3 = 0x06, /*!< timer5 ch3 event as trigger source of adc3 ordinary sequence */ + ADC3_ORDINARY_TRIG_SOFTWARE = 0x07, /*!< software(OCSWTRG) control bit as trigger source of adc3 ordinary sequence */ + ADC3_ORDINARY_TRIG_TMR1TRGOUT = 0x0D, /*!< timer1 trgout event as trigger source of adc3 ordinary sequence */ + ADC3_ORDINARY_TRIG_TMR1CH1 = 0x0E, /*!< timer1 ch1 event as trigger source of adc3 ordinary sequence */ + ADC3_ORDINARY_TRIG_TMR8CH3 = 0x0F /*!< timer8 ch3 event as trigger source of adc3 ordinary sequence */ +} adc_ordinary_trig_select_type; + +/** + * @brief adc preempt group trigger event select type + */ +typedef enum +{ + /*adc1 and adc2 preempt trigger event*/ + ADC12_PREEMPT_TRIG_TMR1TRGOUT = 0x00, /*!< timer1 trgout event as trigger source of adc1/adc2 preempt sequence */ + ADC12_PREEMPT_TRIG_TMR1CH4 = 0x01, /*!< timer1 ch4 event as trigger source of adc1/adc2 preempt sequence */ + ADC12_PREEMPT_TRIG_TMR2TRGOUT = 0x02, /*!< timer2 trgout event as trigger source of adc1/adc2 preempt sequence */ + ADC12_PREEMPT_TRIG_TMR2CH1 = 0x03, /*!< timer2 ch1 event as trigger source of adc1/adc2 preempt sequence */ + ADC12_PREEMPT_TRIG_TMR3CH4 = 0x04, /*!< timer3 ch4 event as trigger source of adc1/adc2 preempt sequence */ + ADC12_PREEMPT_TRIG_TMR4TRGOUT = 0x05, /*!< timer4 trgout event as trigger source of adc1/adc2 preempt sequence */ + ADC12_PREEMPT_TRIG_EXINT15_TMR8CH4 = 0x06, /*!< exint line15/timer8 ch4 event as trigger source of adc1/adc2 preempt sequence */ + ADC12_PREEMPT_TRIG_SOFTWARE = 0x07, /*!< software(PCSWTRG) control bit as trigger source of adc1/adc2 preempt sequence */ + ADC12_PREEMPT_TRIG_TMR1CH1 = 0x0D, /*!< timer1 ch1 event as trigger source of adc1/adc2 preempt sequence */ + ADC12_PREEMPT_TRIG_TMR8CH1 = 0x0E, /*!< timer8 ch1 event as trigger source of adc1/adc2 preempt sequence */ + ADC12_PREEMPT_TRIG_TMR8TRGOUT = 0x0F, /*!< timer8 trgout event as trigger source of adc1/adc2 preempt sequence */ + /*adc3 preempt trigger event*/ + ADC3_PREEMPT_TRIG_TMR1TRGOUT = 0x00, /*!< timer1 trgout event as trigger source of adc3 preempt sequence */ + ADC3_PREEMPT_TRIG_TMR1CH4 = 0x01, /*!< timer1 ch4 event as trigger source of adc3 preempt sequence */ + ADC3_PREEMPT_TRIG_TMR4CH3 = 0x02, /*!< timer4 ch3 event as trigger source of adc3 preempt sequence */ + ADC3_PREEMPT_TRIG_TMR8CH2 = 0x03, /*!< timer8 ch2 event as trigger source of adc3 preempt sequence */ + ADC3_PREEMPT_TRIG_TMR8CH4 = 0x04, /*!< timer8 ch4 event as trigger source of adc3 preempt sequence */ + ADC3_PREEMPT_TRIG_TMR5TRGOUT = 0x05, /*!< timer5 trgout event as trigger source of adc3 preempt sequence */ + ADC3_PREEMPT_TRIG_TMR5CH4 = 0x06, /*!< timer5 ch4 event as trigger source of adc3 preempt sequence */ + ADC3_PREEMPT_TRIG_SOFTWARE = 0x07, /*!< software(PCSWTRG) control bit as trigger source of adc3 preempt sequence */ + ADC3_PREEMPT_TRIG_TMR1CH1 = 0x0D, /*!< timer1 ch1 event as trigger source of adc3 preempt sequence */ + ADC3_PREEMPT_TRIG_TMR1CH2 = 0x0E, /*!< timer1 ch2 event as trigger source of adc3 preempt sequence */ + ADC3_PREEMPT_TRIG_TMR8TRGOUT = 0x0F /*!< timer8 trgout event as trigger source of adc3 preempt sequence */ +} adc_preempt_trig_select_type; + +/** + * @brief adc preempt channel type + */ +typedef enum +{ + ADC_PREEMPT_CHANNEL_1 = 0x00, /*!< adc preempt channel 1 */ + ADC_PREEMPT_CHANNEL_2 = 0x01, /*!< adc preempt channel 2 */ + ADC_PREEMPT_CHANNEL_3 = 0x02, /*!< adc preempt channel 3 */ + ADC_PREEMPT_CHANNEL_4 = 0x03 /*!< adc preempt channel 4 */ +} adc_preempt_channel_type; + +/** + * @brief adc voltage_monitoring type + */ +typedef enum +{ + ADC_VMONITOR_SINGLE_ORDINARY = 0x00800200, /*!< voltage_monitoring on a single ordinary channel */ + ADC_VMONITOR_SINGLE_PREEMPT = 0x00400200, /*!< voltage_monitoring on a single preempt channel */ + ADC_VMONITOR_SINGLE_ORDINARY_PREEMPT = 0x00C00200, /*!< voltage_monitoring on a single ordinary or preempt channel */ + ADC_VMONITOR_ALL_ORDINARY = 0x00800000, /*!< voltage_monitoring on all ordinary channel */ + ADC_VMONITOR_ALL_PREEMPT = 0x00400000, /*!< voltage_monitoring on all preempt channel */ + ADC_VMONITOR_ALL_ORDINARY_PREEMPT = 0x00C00000, /*!< voltage_monitoring on all ordinary and preempt channel */ + ADC_VMONITOR_NONE = 0x00000000 /*!< no channel guarded by the voltage_monitoring */ +} adc_voltage_monitoring_type; + +/** + * @brief adc base config type + */ +typedef struct +{ + confirm_state sequence_mode; /*!< adc sequence mode */ + confirm_state repeat_mode; /*!< adc repeat mode */ + adc_data_align_type data_align; /*!< adc data alignment */ + uint8_t ordinary_channel_length; /*!< adc ordinary channel sequence length*/ +} adc_base_config_type; + +/** + * @brief type define adc register all + */ +typedef struct +{ + + /** + * @brief adc sts register, offset:0x00 + */ + union + { + __IO uint32_t sts; + struct + { + __IO uint32_t vmor : 1; /* [0] */ + __IO uint32_t cce : 1; /* [1] */ + __IO uint32_t pcce : 1; /* [2] */ + __IO uint32_t pccs : 1; /* [3] */ + __IO uint32_t occs : 1; /* [4] */ + __IO uint32_t reserved1 : 27;/* [31:5] */ + } sts_bit; + }; + + /** + * @brief adc ctrl1 register, offset:0x04 + */ + union + { + __IO uint32_t ctrl1; + struct + { + __IO uint32_t vmcsel : 5; /* [4:0] */ + __IO uint32_t cceien : 1; /* [5] */ + __IO uint32_t vmorien : 1; /* [6] */ + __IO uint32_t pcceien : 1; /* [7] */ + __IO uint32_t sqen : 1; /* [8] */ + __IO uint32_t vmsgen : 1; /* [9] */ + __IO uint32_t pcautoen : 1; /* [10] */ + __IO uint32_t ocpen : 1; /* [11] */ + __IO uint32_t pcpen : 1; /* [12] */ + __IO uint32_t ocpcnt : 3; /* [15:13] */ + __IO uint32_t mssel : 4; /* [19:16] */ + __IO uint32_t reserved1 : 2; /* [21:20] */ + __IO uint32_t pcvmen : 1; /* [22] */ + __IO uint32_t ocvmen : 1; /* [23] */ + __IO uint32_t reserved2 : 8; /* [31:24] */ + } ctrl1_bit; + }; + + /** + * @brief adc ctrl2 register, offset:0x08 + */ + union + { + __IO uint32_t ctrl2; + struct + { + __IO uint32_t adcen : 1; /* [0] */ + __IO uint32_t rpen : 1; /* [1] */ + __IO uint32_t adcal : 1; /* [2] */ + __IO uint32_t adcalinit : 1; /* [3] */ + __IO uint32_t reserved1 : 4; /* [7:4] */ + __IO uint32_t ocdmaen : 1; /* [8] */ + __IO uint32_t reserved2 : 2; /* [10:9] */ + __IO uint32_t dtalign : 1; /* [11] */ + __IO uint32_t pctesel_l : 3; /* [14:12] */ + __IO uint32_t pcten : 1; /* [15] */ + __IO uint32_t reserved3 : 1; /* [16] */ + __IO uint32_t octesel_l : 3; /* [19:17] */ + __IO uint32_t octen : 1; /* [20] */ + __IO uint32_t pcswtrg : 1; /* [21] */ + __IO uint32_t ocswtrg : 1; /* [22] */ + __IO uint32_t itsrven : 1; /* [23] */ + __IO uint32_t pctesel_h : 1; /* [24] */ + __IO uint32_t octesel_h : 1; /* [25] */ + __IO uint32_t reserved4 : 6; /* [31:26] */ + } ctrl2_bit; + }; + + /** + * @brief adc spt1 register, offset:0x0C + */ + union + { + __IO uint32_t spt1; + struct + { + __IO uint32_t cspt10 : 3; /* [2:0] */ + __IO uint32_t cspt11 : 3; /* [5:3] */ + __IO uint32_t cspt12 : 3; /* [8:6] */ + __IO uint32_t cspt13 : 3; /* [11:9] */ + __IO uint32_t cspt14 : 3; /* [14:12] */ + __IO uint32_t cspt15 : 3; /* [17:15] */ + __IO uint32_t cspt16 : 3; /* [20:18] */ + __IO uint32_t cspt17 : 3; /* [23:21] */ + __IO uint32_t reserved1 : 8;/* [31:24] */ + } spt1_bit; + }; + + /** + * @brief adc spt2 register, offset:0x10 + */ + union + { + __IO uint32_t spt2; + struct + { + __IO uint32_t cspt0 : 3;/* [2:0] */ + __IO uint32_t cspt1 : 3;/* [5:3] */ + __IO uint32_t cspt2 : 3;/* [8:6] */ + __IO uint32_t cspt3 : 3;/* [11:9] */ + __IO uint32_t cspt4 : 3;/* [14:12] */ + __IO uint32_t cspt5 : 3;/* [17:15] */ + __IO uint32_t cspt6 : 3;/* [20:18] */ + __IO uint32_t cspt7 : 3;/* [23:21] */ + __IO uint32_t cspt8 : 3;/* [26:24] */ + __IO uint32_t cspt9 : 3;/* [29:27] */ + __IO uint32_t reserved1 : 2;/* [31:30] */ + } spt2_bit; + }; + + /** + * @brief adc pcdto1 register, offset:0x14 + */ + union + { + __IO uint32_t pcdto1; + struct + { + __IO uint32_t pcdto1 : 12; /* [11:0] */ + __IO uint32_t reserved1 : 20; /* [31:12] */ + } pcdto1_bit; + }; + + /** + * @brief adc pcdto2 register, offset:0x18 + */ + union + { + __IO uint32_t pcdto2; + struct + { + __IO uint32_t pcdto2 : 12; /* [11:0] */ + __IO uint32_t reserved1 : 20; /* [31:12] */ + } pcdto2_bit; + }; + + /** + * @brief adc pcdto3 register, offset:0x1C + */ + union + { + __IO uint32_t pcdto3; + struct + { + __IO uint32_t pcdto3 : 12; /* [11:0] */ + __IO uint32_t reserved1 : 20; /* [31:12] */ + } pcdto3_bit; + }; + + /** + * @brief adc pcdto4 register, offset:0x20 + */ + union + { + __IO uint32_t pcdto4; + struct + { + __IO uint32_t pcdto4 : 12; /* [11:0] */ + __IO uint32_t reserved1 : 20; /* [31:12] */ + } pcdto4_bit; + }; + + /** + * @brief adc vmhb register, offset:0x24 + */ + union + { + __IO uint32_t vmhb; + struct + { + __IO uint32_t vmhb : 12; /* [11:0] */ + __IO uint32_t reserved1 : 20; /* [31:12] */ + } vmhb_bit; + }; + + /** + * @brief adc vmlb register, offset:0x28 + */ + union + { + __IO uint32_t vmlb; + struct + { + __IO uint32_t vmlb : 12; /* [11:0] */ + __IO uint32_t reserved1 : 20; /* [31:12] */ + } vmlb_bit; + }; + + /** + * @brief adc osq1 register, offset:0x2C + */ + union + { + __IO uint32_t osq1; + struct + { + __IO uint32_t osn13 : 5; /* [4:0] */ + __IO uint32_t osn14 : 5; /* [9:5] */ + __IO uint32_t osn15 : 5; /* [14:10] */ + __IO uint32_t osn16 : 5; /* [19:15] */ + __IO uint32_t oclen : 4; /* [23:20] */ + __IO uint32_t reserved1 : 8; /* [31:24] */ + } osq1_bit; + }; + + /** + * @brief adc osq2 register, offset:0x30 + */ + union + { + __IO uint32_t osq2; + struct + { + __IO uint32_t osn7 : 5; /* [4:0] */ + __IO uint32_t osn8 : 5; /* [9:5] */ + __IO uint32_t osn9 : 5; /* [14:10] */ + __IO uint32_t osn10 : 5; /* [19:15] */ + __IO uint32_t osn11 : 5; /* [24:20] */ + __IO uint32_t osn12 : 5; /* [29:25] */ + __IO uint32_t reserved1 : 2; /* [31:30] */ + } osq2_bit; + }; + + /** + * @brief adc osq3 register, offset:0x34 + */ + union + { + __IO uint32_t osq3; + struct + { + __IO uint32_t osn1 : 5; /* [4:0] */ + __IO uint32_t osn2 : 5; /* [9:5] */ + __IO uint32_t osn3 : 5; /* [14:10] */ + __IO uint32_t osn4 : 5; /* [19:15] */ + __IO uint32_t osn5 : 5; /* [24:20] */ + __IO uint32_t osn6 : 5; /* [29:25] */ + __IO uint32_t reserved1 : 2; /* [31:30] */ + } osq3_bit; + }; + + /** + * @brief adc psq register, offset:0x38 + */ + union + { + __IO uint32_t psq; + struct + { + __IO uint32_t psn1 : 5; /* [4:0] */ + __IO uint32_t psn2 : 5; /* [9:5] */ + __IO uint32_t psn3 : 5; /* [14:10] */ + __IO uint32_t psn4 : 5; /* [19:15] */ + __IO uint32_t pclen : 2; /* [21:20] */ + __IO uint32_t reserved1 : 10;/* [31:22] */ + } psq_bit; + }; + + /** + * @brief adc pdt1 register, offset:0x3C + */ + union + { + __IO uint32_t pdt1; + struct + { + __IO uint32_t pdt1 : 16; /* [15:0] */ + __IO uint32_t reserved1 : 16; /* [31:16] */ + } pdt1_bit; + }; + + /** + * @brief adc pdt2 register, offset:0x40 + */ + union + { + __IO uint32_t pdt2; + struct + { + __IO uint32_t pdt2 : 16; /* [15:0] */ + __IO uint32_t reserved1 : 16; /* [31:16] */ + } pdt2_bit; + }; + + /** + * @brief adc pdt3 register, offset:0x44 + */ + union + { + __IO uint32_t pdt3; + struct + { + __IO uint32_t pdt3 : 16; /* [15:0] */ + __IO uint32_t reserved1 : 16; /* [31:16] */ + } pdt3_bit; + }; + + /** + * @brief adc pdt4 register, offset:0x48 + */ + union + { + __IO uint32_t pdt4; + struct + { + __IO uint32_t pdt4 : 16; /* [15:0] */ + __IO uint32_t reserved1 : 16; /* [31:16] */ + } pdt4_bit; + }; + + /** + * @brief adc odt register, offset:0x4C + */ + union + { + __IO uint32_t odt; + struct + { + __IO uint32_t odt : 16; /* [15:0] */ + __IO uint32_t adc2odt : 16; /* [31:16] */ + } odt_bit; + }; + +} adc_type; + +/** + * @} + */ + +#define ADC1 ((adc_type *) ADC1_BASE) +#define ADC2 ((adc_type *) ADC2_BASE) +#define ADC3 ((adc_type *) ADC3_BASE) + +/** @defgroup ADC_exported_functions + * @{ + */ + +void adc_reset(adc_type *adc_x); +void adc_enable(adc_type *adc_x, confirm_state new_state); +void adc_combine_mode_select(adc_combine_mode_type combine_mode); +void adc_base_default_para_init(adc_base_config_type *adc_base_struct); +void adc_base_config(adc_type *adc_x, adc_base_config_type *adc_base_struct); +void adc_dma_mode_enable(adc_type *adc_x, confirm_state new_state); +void adc_interrupt_enable(adc_type *adc_x, uint32_t adc_int, confirm_state new_state); +void adc_calibration_init(adc_type *adc_x); +flag_status adc_calibration_init_status_get(adc_type *adc_x); +void adc_calibration_start(adc_type *adc_x); +flag_status adc_calibration_status_get(adc_type *adc_x); +void adc_voltage_monitor_enable(adc_type *adc_x, adc_voltage_monitoring_type adc_voltage_monitoring); +void adc_voltage_monitor_threshold_value_set(adc_type *adc_x, uint16_t adc_high_threshold, uint16_t adc_low_threshold); +void adc_voltage_monitor_single_channel_select(adc_type *adc_x, adc_channel_select_type adc_channel); +void adc_ordinary_channel_set(adc_type *adc_x, adc_channel_select_type adc_channel, uint8_t adc_sequence, adc_sampletime_select_type adc_sampletime); +void adc_preempt_channel_length_set(adc_type *adc_x, uint8_t adc_channel_lenght); +void adc_preempt_channel_set(adc_type *adc_x, adc_channel_select_type adc_channel, uint8_t adc_sequence, adc_sampletime_select_type adc_sampletime); +void adc_ordinary_conversion_trigger_set(adc_type *adc_x, adc_ordinary_trig_select_type adc_ordinary_trig, confirm_state new_state); +void adc_preempt_conversion_trigger_set(adc_type *adc_x, adc_preempt_trig_select_type adc_preempt_trig, confirm_state new_state); +void adc_preempt_offset_value_set(adc_type *adc_x, adc_preempt_channel_type adc_preempt_channel, uint16_t adc_offset_value); +void adc_ordinary_part_count_set(adc_type *adc_x, uint8_t adc_channel_count); +void adc_ordinary_part_mode_enable(adc_type *adc_x, confirm_state new_state); +void adc_preempt_part_mode_enable(adc_type *adc_x, confirm_state new_state); +void adc_preempt_auto_mode_enable(adc_type *adc_x, confirm_state new_state); +void adc_tempersensor_vintrv_enable(confirm_state new_state); +void adc_ordinary_software_trigger_enable(adc_type *adc_x, confirm_state new_state); +flag_status adc_ordinary_software_trigger_status_get(adc_type *adc_x); +void adc_preempt_software_trigger_enable(adc_type *adc_x, confirm_state new_state); +flag_status adc_preempt_software_trigger_status_get(adc_type *adc_x); +uint16_t adc_ordinary_conversion_data_get(adc_type *adc_x); +uint32_t adc_combine_ordinary_conversion_data_get(void); +uint16_t adc_preempt_conversion_data_get(adc_type *adc_x, adc_preempt_channel_type adc_preempt_channel); +flag_status adc_flag_get(adc_type *adc_x, uint8_t adc_flag); +void adc_flag_clear(adc_type *adc_x, uint32_t adc_flag); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_bpr.h b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_bpr.h new file mode 100644 index 0000000..03235e1 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_bpr.h @@ -0,0 +1,789 @@ +/** + ************************************************************************** + * @file at32f403a_407_bpr.h + * @version v2.0.9 + * @date 2022-04-25 + * @brief at32f403a_407 bpr header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_BPR_H +#define __AT32F403A_407_BPR_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f403a_407.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @addtogroup BPR + * @{ + */ + +/** @defgroup BPR_flags_definition + * @brief bpr flag + * @{ + */ + +#define BPR_TAMPER_INTERRUPT_FLAG ((uint32_t)0x00000001) /*!< bpr tamper interrupt flag */ +#define BPR_TAMPER_EVENT_FLAG ((uint32_t)0x00000002) /*!< bpr tamper event flag */ + +/** + * @} + */ + +/** @defgroup BPR_exported_types + * @{ + */ + +/** + * @brief battery powered register data type + */ +typedef enum +{ + BPR_DATA1 = 0x04, /*!< bpr data register 1 */ + BPR_DATA2 = 0x08, /*!< bpr data register 2 */ + BPR_DATA3 = 0x0C, /*!< bpr data register 3 */ + BPR_DATA4 = 0x10, /*!< bpr data register 4 */ + BPR_DATA5 = 0x14, /*!< bpr data register 5 */ + BPR_DATA6 = 0x18, /*!< bpr data register 6 */ + BPR_DATA7 = 0x1C, /*!< bpr data register 7 */ + BPR_DATA8 = 0x20, /*!< bpr data register 8 */ + BPR_DATA9 = 0x24, /*!< bpr data register 9 */ + BPR_DATA10 = 0x28, /*!< bpr data register 10 */ + BPR_DATA11 = 0x40, /*!< bpr data register 11 */ + BPR_DATA12 = 0x44, /*!< bpr data register 12 */ + BPR_DATA13 = 0x48, /*!< bpr data register 13 */ + BPR_DATA14 = 0x4C, /*!< bpr data register 14 */ + BPR_DATA15 = 0x50, /*!< bpr data register 15 */ + BPR_DATA16 = 0x54, /*!< bpr data register 16 */ + BPR_DATA17 = 0x58, /*!< bpr data register 17 */ + BPR_DATA18 = 0x5C, /*!< bpr data register 18 */ + BPR_DATA19 = 0x60, /*!< bpr data register 19 */ + BPR_DATA20 = 0x64, /*!< bpr data register 20 */ + BPR_DATA21 = 0x68, /*!< bpr data register 21 */ + BPR_DATA22 = 0x6C, /*!< bpr data register 22 */ + BPR_DATA23 = 0x70, /*!< bpr data register 23 */ + BPR_DATA24 = 0x74, /*!< bpr data register 24 */ + BPR_DATA25 = 0x78, /*!< bpr data register 25 */ + BPR_DATA26 = 0x7C, /*!< bpr data register 26 */ + BPR_DATA27 = 0x80, /*!< bpr data register 27 */ + BPR_DATA28 = 0x84, /*!< bpr data register 28 */ + BPR_DATA29 = 0x88, /*!< bpr data register 29 */ + BPR_DATA30 = 0x8C, /*!< bpr data register 30 */ + BPR_DATA31 = 0x90, /*!< bpr data register 31 */ + BPR_DATA32 = 0x94, /*!< bpr data register 32 */ + BPR_DATA33 = 0x98, /*!< bpr data register 33 */ + BPR_DATA34 = 0x9C, /*!< bpr data register 34 */ + BPR_DATA35 = 0xA0, /*!< bpr data register 35 */ + BPR_DATA36 = 0xA4, /*!< bpr data register 36 */ + BPR_DATA37 = 0xA8, /*!< bpr data register 37 */ + BPR_DATA38 = 0xAC, /*!< bpr data register 38 */ + BPR_DATA39 = 0xB0, /*!< bpr data register 39 */ + BPR_DATA40 = 0xB4, /*!< bpr data register 40 */ + BPR_DATA41 = 0xB8, /*!< bpr data register 41 */ + BPR_DATA42 = 0xBC /*!< bpr data register 42 */ +} bpr_data_type; + +/** + * @brief bpr rtc output type + */ +typedef enum +{ + BPR_RTC_OUTPUT_NONE = 0x000, /*!< output disable */ + BPR_RTC_OUTPUT_CLOCK_CAL_BEFORE = 0x080, /*!< output clock before calibration */ + BPR_RTC_OUTPUT_ALARM = 0x100, /*!< output alarm event with pluse mode */ + BPR_RTC_OUTPUT_SECOND = 0x300, /*!< output second event with pluse mode */ + BPR_RTC_OUTPUT_CLOCK_CAL_AFTER = 0x480, /*!< output clock after calibration */ + BPR_RTC_OUTPUT_ALARM_TOGGLE = 0x900, /*!< output alarm event with toggle mode */ + BPR_RTC_OUTPUT_SECOND_TOGGLE = 0xB00 /*!< output second event with toggle mode */ +} bpr_rtc_output_type; + +/** + * @brief tamper pin active level type + */ +typedef enum +{ + BPR_TAMPER_PIN_ACTIVE_HIGH = 0x00, /*!< tamper pin input active level is high */ + BPR_TAMPER_PIN_ACTIVE_LOW = 0x01 /*!< tamper pin input active level is low */ +} bpr_tamper_pin_active_level_type; + +/** + * @brief type define bpr register all + */ +typedef struct +{ + /** + * @brief reserved, offset:0x00 + */ + __IO uint32_t reserved1; + + /** + * @brief bpr dt1 register, offset:0x04 + */ + union + { + __IO uint32_t dt1; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt1_bit; + }; + + /** + * @brief bpr dt2 register, offset:0x08 + */ + union + { + __IO uint32_t dt2; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt2_bit; + }; + + /** + * @brief bpr dt3 register, offset:0x0C + */ + union + { + __IO uint32_t dt3; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt3_bit; + }; + + /** + * @brief bpr dt4 register, offset:0x10 + */ + union + { + __IO uint32_t dt4; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt4_bit; + }; + + /** + * @brief bpr dt5 register, offset:0x14 + */ + union + { + __IO uint32_t dt5; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt5_bit; + }; + + /** + * @brief bpr dt6 register, offset:0x18 + */ + union + { + __IO uint32_t dt6; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt6_bit; + }; + + /** + * @brief bpr dt7 register, offset:0x1C + */ + union + { + __IO uint32_t dt7; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt7_bit; + }; + + /** + * @brief bpr dt8 register, offset:0x20 + */ + union + { + __IO uint32_t dt8; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt8_bit; + }; + + /** + * @brief bpr dt9 register, offset:0x24 + */ + union + { + __IO uint32_t dt9; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt9_bit; + }; + + /** + * @brief bpr dt10 register, offset:0x28 + */ + union + { + __IO uint32_t dt10; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt10_bit; + }; + + /** + * @brief bpr rtccal register, offset:0x2C + */ + union + { + __IO uint32_t rtccal; + struct + { + __IO uint32_t calval : 7; /* [6:0] */ + __IO uint32_t calout : 1; /* [7] */ + __IO uint32_t outen : 1; /* [8] */ + __IO uint32_t outsel : 1; /* [9] */ + __IO uint32_t ccos : 1; /* [10] */ + __IO uint32_t outm : 1; /* [11] */ + __IO uint32_t reserved1 : 20;/* [31:12] */ + } rtccal_bit; + }; + + /** + * @brief bpr ctrl register, offset:0x30 + */ + union + { + __IO uint32_t ctrl; + struct + { + __IO uint32_t tpen : 1; /* [0] */ + __IO uint32_t tpp : 1; /* [1] */ + __IO uint32_t reserved1 : 30;/* [31:2] */ + } ctrl_bit; + }; + + /** + * @brief bpr ctrlsts register, offset:0x34 + */ + union + { + __IO uint32_t ctrlsts; + struct + { + __IO uint32_t tpefclr : 1;/* [0] */ + __IO uint32_t tpifclr : 1;/* [1] */ + __IO uint32_t tpien : 1;/* [2] */ + __IO uint32_t reserved1 : 5;/* [7:3] */ + __IO uint32_t tpef : 1;/* [8] */ + __IO uint32_t tpif : 1;/* [9] */ + __IO uint32_t reserved2 : 22;/* [31:10] */ + } ctrlsts_bit; + }; + + /** + * @brief reserved, offset:0x38 + */ + __IO uint32_t reserved2; + + /** + * @brief reserved, offset:0x3C + */ + __IO uint32_t reserved3; + + /** + * @brief bpr dt11 register, offset:0x40 + */ + union + { + __IO uint32_t dt11; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt11_bit; + }; + + /** + * @brief bpr dt12 register, offset:0x44 + */ + union + { + __IO uint32_t dt12; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt12_bit; + }; + + /** + * @brief bpr dt13 register, offset:0x48 + */ + union + { + __IO uint32_t dt13; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt13_bit; + }; + + /** + * @brief bpr dt14 register, offset:0x4C + */ + union + { + __IO uint32_t dt14; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt14_bit; + }; + + /** + * @brief bpr dt15 register, offset:0x50 + */ + union + { + __IO uint32_t dt15; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt15_bit; + }; + + /** + * @brief bpr dt16 register, offset:0x54 + */ + union + { + __IO uint32_t dt16; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt16_bit; + }; + + /** + * @brief bpr dt17 register, offset:0x58 + */ + union + { + __IO uint32_t dt17; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt17_bit; + }; + + /** + * @brief bpr dt18 register, offset:0x5C + */ + union + { + __IO uint32_t dt18; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt18_bit; + }; + + /** + * @brief bpr dt19 register, offset:0x60 + */ + union + { + __IO uint32_t dt19; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt19_bit; + }; + + /** + * @brief bpr dt20 register, offset:0x64 + */ + union + { + __IO uint32_t dt20; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt20_bit; + }; + + /** + * @brief bpr dt21 register, offset:0x68 + */ + union + { + __IO uint32_t dt21; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt21_bit; + }; + + /** + * @brief bpr dt22 register, offset:6C + */ + union + { + __IO uint32_t dt22; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt22_bit; + }; + + /** + * @brief bpr dt23 register, offset:0x70 + */ + union + { + __IO uint32_t dt23; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt23_bit; + }; + + /** + * @brief bpr dt24 register, offset:0x74 + */ + union + { + __IO uint32_t dt24; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt24_bit; + }; + + /** + * @brief bpr dt25 register, offset:0x78 + */ + union + { + __IO uint32_t dt25; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt25_bit; + }; + + /** + * @brief bpr dt26 register, offset:0x7C + */ + union + { + __IO uint32_t dt26; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt26_bit; + }; + + /** + * @brief bpr dt27 register, offset:0x80 + */ + union + { + __IO uint32_t dt27; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt27_bit; + }; + + /** + * @brief bpr dt28 register, offset:0x84 + */ + union + { + __IO uint32_t dt28; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt28_bit; + }; + + /** + * @brief bpr dt29 register, offset:0x88 + */ + union + { + __IO uint32_t dt29; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt29_bit; + }; + + /** + * @brief bpr dt30 register, offset:0x8C + */ + union + { + __IO uint32_t dt30; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt30_bit; + }; + + /** + * @brief bpr dt31 register, offset:0x90 + */ + union + { + __IO uint32_t dt31; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt31_bit; + }; + + /** + * @brief bpr dt32 register, offset:0x94 + */ + union + { + __IO uint32_t dt32; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt32_bit; + }; + + /** + * @brief bpr dt33 register, offset:0x98 + */ + union + { + __IO uint32_t dt33; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt33_bit; + }; + + /** + * @brief bpr dt34 register, offset:0x9C + */ + union + { + __IO uint32_t dt34; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt34_bit; + }; + + /** + * @brief bpr dt35 register, offset:0xA0 + */ + union + { + __IO uint32_t dt35; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt35_bit; + }; + + /** + * @brief bpr dt36 register, offset:0xA4 + */ + union + { + __IO uint32_t dt36; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt36_bit; + }; + + /** + * @brief bpr dt37 register, offset:0xA8 + */ + union + { + __IO uint32_t dt37; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt37_bit; + }; + + /** + * @brief bpr dt38 register, offset:0xAC + */ + union + { + __IO uint32_t dt38; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt38_bit; + }; + + /** + * @brief bpr dt39 register, offset:0xB0 + */ + union + { + __IO uint32_t dt39; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt39_bit; + }; + + /** + * @brief bpr dt40 register, offset:0xB4 + */ + union + { + __IO uint32_t dt40; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt40_bit; + }; + + /** + * @brief bpr dt41 register, offset:0xB8 + */ + union + { + __IO uint32_t dt41; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt41_bit; + }; + + /** + * @brief bpr dt42 register, offset:0xBC + */ + union + { + __IO uint32_t dt42; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:15] */ + } dt42_bit; + }; +} bpr_type; + +/** + * @} + */ + +#define BPR ((bpr_type *) BPR_BASE) + +/** @defgroup BPR_exported_functions + * @{ + */ + +void bpr_reset(void); +flag_status bpr_flag_get(uint32_t flag); +void bpr_flag_clear(uint32_t flag); +void bpr_interrupt_enable(confirm_state new_state); +uint16_t bpr_data_read(bpr_data_type bpr_data); +void bpr_data_write(bpr_data_type bpr_data, uint16_t data_value); +void bpr_rtc_output_select(bpr_rtc_output_type output_source); +void bpr_rtc_clock_calibration_value_set(uint8_t calibration_value); +void bpr_tamper_pin_enable(confirm_state new_state); +void bpr_tamper_pin_active_level_set(bpr_tamper_pin_active_level_type active_level); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_can.h b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_can.h new file mode 100644 index 0000000..247dfff --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_can.h @@ -0,0 +1,986 @@ +/** + ************************************************************************** + * @file at32f403a_407_can.h + * @version v2.0.9 + * @date 2022-04-25 + * @brief at32f403a_407 can header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_CAN_H +#define __AT32F403A_407_CAN_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* includes ------------------------------------------------------------------*/ +#include "at32f403a_407.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @addtogroup CAN + * @{ + */ + + +/** @defgroup CAN_timeout_count + * @{ + */ + +#define FZC_TIMEOUT ((uint32_t)0x0000FFFF) /*!< time out for fzc bit */ +#define DZC_TIMEOUT ((uint32_t)0x0000FFFF) /*!< time out for dzc bit */ + +/** + * @} + */ + +/** @defgroup CAN_flags_definition + * @brief can flag + * @{ + */ + +#define CAN_EAF_FLAG ((uint32_t)0x01) /*!< error active flag */ +#define CAN_EPF_FLAG ((uint32_t)0x02) /*!< error passive flag */ +#define CAN_BOF_FLAG ((uint32_t)0x03) /*!< bus-off flag */ +#define CAN_ETR_FLAG ((uint32_t)0x04) /*!< error type record flag */ +#define CAN_EOIF_FLAG ((uint32_t)0x05) /*!< error occur interrupt flag */ +#define CAN_TM0TCF_FLAG ((uint32_t)0x06) /*!< transmit mailbox 0 transmission completed flag */ +#define CAN_TM1TCF_FLAG ((uint32_t)0x07) /*!< transmit mailbox 1 transmission completed flag */ +#define CAN_TM2TCF_FLAG ((uint32_t)0x08) /*!< transmit mailbox 2 transmission completed flag */ +#define CAN_RF0MN_FLAG ((uint32_t)0x09) /*!< receive fifo 0 message num flag */ +#define CAN_RF0FF_FLAG ((uint32_t)0x0A) /*!< receive fifo 0 full flag */ +#define CAN_RF0OF_FLAG ((uint32_t)0x0B) /*!< receive fifo 0 overflow flag */ +#define CAN_RF1MN_FLAG ((uint32_t)0x0C) /*!< receive fifo 1 message num flag */ +#define CAN_RF1FF_FLAG ((uint32_t)0x0D) /*!< receive fifo 1 full flag */ +#define CAN_RF1OF_FLAG ((uint32_t)0x0E) /*!< receive fifo 1 overflow flag */ +#define CAN_QDZIF_FLAG ((uint32_t)0x0F) /*!< quit doze mode interrupt flag */ +#define CAN_EDZC_FLAG ((uint32_t)0x10) /*!< enter doze mode confirm flag */ +#define CAN_TMEF_FLAG ((uint32_t)0x11) /*!< transmit mailbox empty flag */ + +/** + * @} + */ + +/** @defgroup CAN_interrupts_definition + * @brief can interrupt + * @{ + */ + +#define CAN_TCIEN_INT ((uint32_t)0x00000001) /*!< transmission complete interrupt */ +#define CAN_RF0MIEN_INT ((uint32_t)0x00000002) /*!< receive fifo 0 message interrupt */ +#define CAN_RF0FIEN_INT ((uint32_t)0x00000004) /*!< receive fifo 0 full interrupt */ +#define CAN_RF0OIEN_INT ((uint32_t)0x00000008) /*!< receive fifo 0 overflow interrupt */ +#define CAN_RF1MIEN_INT ((uint32_t)0x00000010) /*!< receive fifo 1 message interrupt */ +#define CAN_RF1FIEN_INT ((uint32_t)0x00000020) /*!< receive fifo 1 full interrupt */ +#define CAN_RF1OIEN_INT ((uint32_t)0x00000040) /*!< receive fifo 1 overflow interrupt */ +#define CAN_EAIEN_INT ((uint32_t)0x00000100) /*!< error active interrupt */ +#define CAN_EPIEN_INT ((uint32_t)0x00000200) /*!< error passive interrupt */ +#define CAN_BOIEN_INT ((uint32_t)0x00000400) /*!< bus-off interrupt */ +#define CAN_ETRIEN_INT ((uint32_t)0x00000800) /*!< error type record interrupt */ +#define CAN_EOIEN_INT ((uint32_t)0x00008000) /*!< error occur interrupt */ +#define CAN_QDZIEN_INT ((uint32_t)0x00010000) /*!< quit doze mode interrupt */ +#define CAN_EDZIEN_INT ((uint32_t)0x00020000) /*!< enter doze mode confirm interrupt */ + +/** + * @} + */ + +/** + * @brief can flag clear operation macro definition val + */ +#define CAN_MSTS_EOIF_VAL ((uint32_t)0x00000004) /*!< eoif bit value, it clear by writing 1 */ +#define CAN_MSTS_QDZIF_VAL ((uint32_t)0x00000008) /*!< qdzif bit value, it clear by writing 1 */ +#define CAN_MSTS_EDZIF_VAL ((uint32_t)0x00000010) /*!< edzif bit value, it clear by writing 1 */ +#define CAN_TSTS_TM0TCF_VAL ((uint32_t)0x00000001) /*!< tm0tcf bit value, it clear by writing 1 */ +#define CAN_TSTS_TM1TCF_VAL ((uint32_t)0x00000100) /*!< tm1tcf bit value, it clear by writing 1 */ +#define CAN_TSTS_TM2TCF_VAL ((uint32_t)0x00010000) /*!< tm2tcf bit value, it clear by writing 1 */ +#define CAN_TSTS_TM0CT_VAL ((uint32_t)0x00000080) /*!< tm0ct bit value, it clear by writing 1 */ +#define CAN_TSTS_TM1CT_VAL ((uint32_t)0x00008000) /*!< tm1ct bit value, it clear by writing 1 */ +#define CAN_TSTS_TM2CT_VAL ((uint32_t)0x00800000) /*!< tm2ct bit value, it clear by writing 1 */ +#define CAN_RF0_RF0FF_VAL ((uint32_t)0x00000008) /*!< rf0ff bit value, it clear by writing 1 */ +#define CAN_RF0_RF0OF_VAL ((uint32_t)0x00000010) /*!< rf0of bit value, it clear by writing 1 */ +#define CAN_RF0_RF0R_VAL ((uint32_t)0x00000020) /*!< rf0r bit value, it clear by writing 1 */ +#define CAN_RF1_RF1FF_VAL ((uint32_t)0x00000008) /*!< rf1ff bit value, it clear by writing 1 */ +#define CAN_RF1_RF1OF_VAL ((uint32_t)0x00000010) /*!< rf1of bit value, it clear by writing 1 */ +#define CAN_RF1_RF1R_VAL ((uint32_t)0x00000020) /*!< rf1r bit value, it clear by writing 1 */ + +/** @defgroup CAN_exported_types + * @{ + */ + +/** + * @brief can filter fifo + */ +typedef enum +{ + CAN_FILTER_FIFO0 = 0x00, /*!< filter fifo 0 assignment for filter x */ + CAN_FILTER_FIFO1 = 0x01 /*!< filter fifo 1 assignment for filter x */ +} can_filter_fifo_type; + +/** + * @brief can filter mode + */ +typedef enum +{ + CAN_FILTER_MODE_ID_MASK = 0x00, /*!< identifier mask mode */ + CAN_FILTER_MODE_ID_LIST = 0x01 /*!< identifier list mode */ +} can_filter_mode_type; + +/** + * @brief can filter bit width select + */ +typedef enum +{ + CAN_FILTER_16BIT = 0x00, /*!< two 16-bit filters */ + CAN_FILTER_32BIT = 0x01 /*!< one 32-bit filter */ +} can_filter_bit_width_type; + +/** + * @brief can mode + */ +typedef enum +{ + CAN_MODE_COMMUNICATE = 0x00, /*!< communication mode */ + CAN_MODE_LOOPBACK = 0x01, /*!< loopback mode */ + CAN_MODE_LISTENONLY = 0x02, /*!< listen-only mode */ + CAN_MODE_LISTENONLY_LOOPBACK = 0x03 /*!< loopback combined with listen-only mode */ +} can_mode_type; + +/** + * @brief can operating mode + */ +typedef enum +{ + CAN_OPERATINGMODE_FREEZE = 0x00, /*!< freeze mode */ + CAN_OPERATINGMODE_DOZE = 0x01, /*!< doze mode */ + CAN_OPERATINGMODE_COMMUNICATE = 0x02 /*!< communication mode */ +} can_operating_mode_type; + +/** + * @brief can resynchronization adjust width + */ +typedef enum +{ + CAN_RSAW_1TQ = 0x00, /*!< 1 time quantum */ + CAN_RSAW_2TQ = 0x01, /*!< 2 time quantum */ + CAN_RSAW_3TQ = 0x02, /*!< 3 time quantum */ + CAN_RSAW_4TQ = 0x03 /*!< 4 time quantum */ +} can_rsaw_type; + +/** + * @brief can bit time segment 1 + */ +typedef enum +{ + CAN_BTS1_1TQ = 0x00, /*!< 1 time quantum */ + CAN_BTS1_2TQ = 0x01, /*!< 2 time quantum */ + CAN_BTS1_3TQ = 0x02, /*!< 3 time quantum */ + CAN_BTS1_4TQ = 0x03, /*!< 4 time quantum */ + CAN_BTS1_5TQ = 0x04, /*!< 5 time quantum */ + CAN_BTS1_6TQ = 0x05, /*!< 6 time quantum */ + CAN_BTS1_7TQ = 0x06, /*!< 7 time quantum */ + CAN_BTS1_8TQ = 0x07, /*!< 8 time quantum */ + CAN_BTS1_9TQ = 0x08, /*!< 9 time quantum */ + CAN_BTS1_10TQ = 0x09, /*!< 10 time quantum */ + CAN_BTS1_11TQ = 0x0A, /*!< 11 time quantum */ + CAN_BTS1_12TQ = 0x0B, /*!< 12 time quantum */ + CAN_BTS1_13TQ = 0x0C, /*!< 13 time quantum */ + CAN_BTS1_14TQ = 0x0D, /*!< 14 time quantum */ + CAN_BTS1_15TQ = 0x0E, /*!< 15 time quantum */ + CAN_BTS1_16TQ = 0x0F /*!< 16 time quantum */ +} can_bts1_type; + +/** + * @brief can bit time segment 2 + */ +typedef enum +{ + CAN_BTS2_1TQ = 0x00, /*!< 1 time quantum */ + CAN_BTS2_2TQ = 0x01, /*!< 2 time quantum */ + CAN_BTS2_3TQ = 0x02, /*!< 3 time quantum */ + CAN_BTS2_4TQ = 0x03, /*!< 4 time quantum */ + CAN_BTS2_5TQ = 0x04, /*!< 5 time quantum */ + CAN_BTS2_6TQ = 0x05, /*!< 6 time quantum */ + CAN_BTS2_7TQ = 0x06, /*!< 7 time quantum */ + CAN_BTS2_8TQ = 0x07 /*!< 8 time quantum */ +} can_bts2_type; + +/** + * @brief can identifier type + */ +typedef enum +{ + CAN_ID_STANDARD = 0x00, /*!< standard Id */ + CAN_ID_EXTENDED = 0x01 /*!< extended Id */ +} can_identifier_type; + +/** + * @brief can transmission frame type + */ +typedef enum +{ + CAN_TFT_DATA = 0x00, /*!< data frame */ + CAN_TFT_REMOTE = 0x01 /*!< remote frame */ +} can_trans_frame_type; + +/** + * @brief can tx mailboxes + */ +typedef enum +{ + CAN_TX_MAILBOX0 = 0x00, /*!< can tx mailbox 0 */ + CAN_TX_MAILBOX1 = 0x01, /*!< can tx mailbox 1 */ + CAN_TX_MAILBOX2 = 0x02 /*!< can tx mailbox 2 */ +} can_tx_mailbox_num_type; + +/** + * @brief can receive fifo + */ +typedef enum +{ + CAN_RX_FIFO0 = 0x00, /*!< can fifo 0 used to receive */ + CAN_RX_FIFO1 = 0x01 /*!< can fifo 1 used to receive */ +} can_rx_fifo_num_type; + +/** + * @brief can transmit status + */ +typedef enum +{ + CAN_TX_STATUS_FAILED = 0x00, /*!< can transmission failed */ + CAN_TX_STATUS_SUCCESSFUL = 0x01, /*!< can transmission successful */ + CAN_TX_STATUS_PENDING = 0x02, /*!< can transmission pending */ + CAN_TX_STATUS_NO_EMPTY = 0x04 /*!< can transmission no empty mailbox */ +} can_transmit_status_type; + +/** + * @brief can enter doze mode status + */ +typedef enum +{ + CAN_ENTER_DOZE_FAILED = 0x00, /*!< can enter the doze mode failed */ + CAN_ENTER_DOZE_SUCCESSFUL = 0x01 /*!< can enter the doze mode successful */ +} can_enter_doze_status_type; + +/** + * @brief can quit doze mode status + */ +typedef enum +{ + CAN_QUIT_DOZE_FAILED = 0x00, /*!< can quit doze mode failed */ + CAN_QUIT_DOZE_SUCCESSFUL = 0x01 /*!< can quit doze mode successful */ +} can_quit_doze_status_type; + +/** + * @brief can message discarding rule select when overflow + */ +typedef enum +{ + CAN_DISCARDING_FIRST_RECEIVED = 0x00, /*!< can discarding the first received message */ + CAN_DISCARDING_LAST_RECEIVED = 0x01 /*!< can discarding the last received message */ +} can_msg_discarding_rule_type; + +/** + * @brief can multiple message sending sequence rule + */ +typedef enum +{ + CAN_SENDING_BY_ID = 0x00, /*!< can sending the minimum id message first*/ + CAN_SENDING_BY_REQUEST = 0x01 /*!< can sending the first request message first */ +} can_msg_sending_rule_type; + +/** + * @brief can error type record + */ +typedef enum +{ + CAN_ERRORRECORD_NOERR = 0x00, /*!< no error */ + CAN_ERRORRECORD_STUFFERR = 0x01, /*!< stuff error */ + CAN_ERRORRECORD_FORMERR = 0x02, /*!< form error */ + CAN_ERRORRECORD_ACKERR = 0x03, /*!< acknowledgment error */ + CAN_ERRORRECORD_BITRECESSIVEERR = 0x04, /*!< bit recessive error */ + CAN_ERRORRECORD_BITDOMINANTERR = 0x05, /*!< bit dominant error */ + CAN_ERRORRECORD_CRCERR = 0x06, /*!< crc error */ + CAN_ERRORRECORD_SOFTWARESETERR = 0x07 /*!< software set error */ +} can_error_record_type; + +/** + * @brief can init structure definition + */ +typedef struct +{ + can_mode_type mode_selection; /*!< specifies the can mode.*/ + + confirm_state ttc_enable; /*!< time triggered communication mode enable */ + + confirm_state aebo_enable; /*!< automatic exit bus-off enable */ + + confirm_state aed_enable; /*!< automatic exit doze mode enable */ + + confirm_state prsf_enable; /*!< prohibit retransmission when sending fails enable */ + + can_msg_discarding_rule_type mdrsel_selection; /*!< message discarding rule select when overflow */ + + can_msg_sending_rule_type mmssr_selection; /*!< multiple message sending sequence rule */ + +} can_base_type; + +/** + * @brief can baudrate structure definition + */ +typedef struct +{ + uint16_t baudrate_div; /*!< baudrate division,this parameter can be 0x001~0x400.*/ + + can_rsaw_type rsaw_size; /*!< resynchronization adjust width */ + + can_bts1_type bts1_size; /*!< bit time segment 1 */ + + can_bts2_type bts2_size; /*!< bit time segment 2 */ + +} can_baudrate_type; + +/** + * @brief can filter init structure definition + */ +typedef struct +{ + confirm_state filter_activate_enable; /*!< enable or disable the filter activate.*/ + + can_filter_mode_type filter_mode; /*!< config the filter mode mask or list.*/ + + can_filter_fifo_type filter_fifo; /*!< config the fifo which will be assigned to the filter. */ + + uint8_t filter_number; /*!< config the filter number, parameter ranges from 0 to 13. */ + + can_filter_bit_width_type filter_bit; /*!< config the filter bit width 16bit or 32bit.*/ + + uint16_t filter_id_high; /*!< config the filter identification, for 32-bit configuration + it's high 16 bits, for 16-bit configuration it's first. */ + + uint16_t filter_id_low; /*!< config the filter identification, for 32-bit configuration + it's low 16 bits, for 16-bit configuration it's second. */ + + uint16_t filter_mask_high; /*!< config the filter mask or identification, according to the filtering mode, + for 32-bit configuration it's high 16 bits, for 16-bit configuration it's first. */ + + uint16_t filter_mask_low; /*!< config the filter mask or identification, according to the filtering mode, + for 32-bit configuration it's low 16 bits, for 16-bit configuration it's second. */ +} can_filter_init_type; + +/** + * @brief can tx message structure definition + */ +typedef struct +{ + uint32_t standard_id; /*!< specifies the 11 bits standard identifier. + this parameter can be a value between 0 to 0x7FF. */ + + uint32_t extended_id; /*!< specifies the 29 bits extended identifier. + this parameter can be a value between 0 to 0x1FFFFFFF. */ + + can_identifier_type id_type; /*!< specifies identifier type for the transmit message.*/ + + can_trans_frame_type frame_type; /*!< specifies frame type for the transmit message.*/ + + uint8_t dlc; /*!< specifies frame data length that will be transmitted. + this parameter can be a value between 0 to 8 */ + + uint8_t data[8]; /*!< contains the transmit data. it ranges from 0 to 0xFF. */ + +} can_tx_message_type; + +/** + * @brief can rx message structure definition + */ +typedef struct +{ + uint32_t standard_id; /*!< specifies the 11 bits standard identifier + this parameter can be a value between 0 to 0x7FF. */ + + uint32_t extended_id; /*!< specifies the 29 bits extended identifier. + this parameter can be a value between 0 to 0x1FFFFFFF. */ + + can_identifier_type id_type; /*!< specifies identifier type for the receive message.*/ + + can_trans_frame_type frame_type; /*!< specifies frame type for the receive message.*/ + + uint8_t dlc; /*!< specifies the frame data length that will be received. + this parameter can be a value between 0 to 8 */ + + uint8_t data[8]; /*!< contains the receive data. it ranges from 0 to 0xFF.*/ + + uint8_t filter_index; /*!< specifies the message stored in which filter + this parameter can be a value between 0 to 0xFF */ +} can_rx_message_type; + +/** + * @brief can controller area network tx mailbox + */ +typedef struct +{ + /** + * @brief can tmi register + */ + union + { + __IO uint32_t tmi; + struct + { + __IO uint32_t tmsr : 1; /* [0] */ + __IO uint32_t tmfrsel : 1; /* [1] */ + __IO uint32_t tmidsel : 1; /* [2] */ + __IO uint32_t tmeid : 18;/* [20:3] */ + __IO uint32_t tmsid : 11;/* [31:21] */ + } tmi_bit; + }; + + /** + * @brief can tmc register + */ + union + { + __IO uint32_t tmc; + struct + { + __IO uint32_t tmdtbl : 4; /* [3:0] */ + __IO uint32_t reserved1 : 4; /* [7:4] */ + __IO uint32_t tmtsten : 1; /* [8] */ + __IO uint32_t reserved2 : 7; /* [15:9] */ + __IO uint32_t tmts : 16;/* [31:16] */ + } tmc_bit; + }; + + /** + * @brief can tmdtl register + */ + union + { + __IO uint32_t tmdtl; + struct + { + __IO uint32_t tmdt0 : 8; /* [7:0] */ + __IO uint32_t tmdt1 : 8; /* [15:8] */ + __IO uint32_t tmdt2 : 8; /* [23:16] */ + __IO uint32_t tmdt3 : 8; /* [31:24] */ + } tmdtl_bit; + }; + + /** + * @brief can tmdth register + */ + union + { + __IO uint32_t tmdth; + struct + { + __IO uint32_t tmdt4 : 8; /* [7:0] */ + __IO uint32_t tmdt5 : 8; /* [15:8] */ + __IO uint32_t tmdt6 : 8; /* [23:16] */ + __IO uint32_t tmdt7 : 8; /* [31:24] */ + } tmdth_bit; + }; +} can_tx_mailbox_type; + +/** + * @brief can controller area network fifo mailbox + */ +typedef struct +{ + /** + * @brief can rfi register + */ + union + { + __IO uint32_t rfi; + struct + { + __IO uint32_t reserved1 : 1; /* [0] */ + __IO uint32_t rffri : 1; /* [1] */ + __IO uint32_t rfidi : 1; /* [2] */ + __IO uint32_t rfeid : 18;/* [20:3] */ + __IO uint32_t rfsid : 11;/* [31:21] */ + } rfi_bit; + }; + + /** + * @brief can rfc register + */ + union + { + __IO uint32_t rfc; + struct + { + __IO uint32_t rfdtl : 4; /* [3:0] */ + __IO uint32_t reserved1 : 4; /* [7:4] */ + __IO uint32_t rffmn : 8; /* [15:8] */ + __IO uint32_t rfts : 16;/* [31:16] */ + } rfc_bit; + }; + + /** + * @brief can rfdtl register + */ + union + { + __IO uint32_t rfdtl; + struct + { + __IO uint32_t rfdt0 : 8; /* [7:0] */ + __IO uint32_t rfdt1 : 8; /* [15:8] */ + __IO uint32_t rfdt2 : 8; /* [23:16] */ + __IO uint32_t rfdt3 : 8; /* [31:24] */ + } rfdtl_bit; + }; + + /** + * @brief can rfdth register + */ + union + { + __IO uint32_t rfdth; + struct + { + __IO uint32_t rfdt4 : 8; /* [7:0] */ + __IO uint32_t rfdt5 : 8; /* [15:8] */ + __IO uint32_t rfdt6 : 8; /* [23:16] */ + __IO uint32_t rfdt7 : 8; /* [31:24] */ + } rfdth_bit; + }; +} can_fifo_mailbox_type; + +/** + * @brief can controller area network filter bit register + */ +typedef struct +{ + __IO uint32_t ffdb1; + __IO uint32_t ffdb2; +} can_filter_register_type; + +/** + * @brief type define can register all + */ +typedef struct +{ + + /** + * @brief can mctrl register, offset:0x00 + */ + union + { + __IO uint32_t mctrl; + struct + { + __IO uint32_t fzen : 1; /* [0] */ + __IO uint32_t dzen : 1; /* [1] */ + __IO uint32_t mmssr : 1; /* [2] */ + __IO uint32_t mdrsel : 1; /* [3] */ + __IO uint32_t prsfen : 1; /* [4] */ + __IO uint32_t aeden : 1; /* [5] */ + __IO uint32_t aeboen : 1; /* [6] */ + __IO uint32_t ttcen : 1; /* [7] */ + __IO uint32_t reserved1 : 7; /* [14:8] */ + __IO uint32_t sprst : 1; /* [15] */ + __IO uint32_t ptd : 1; /* [16] */ + __IO uint32_t reserved2 : 15;/*[31:17] */ + } mctrl_bit; + }; + + /** + * @brief can msts register, offset:0x04 + */ + union + { + __IO uint32_t msts; + struct + { + __IO uint32_t fzc : 1; /* [0] */ + __IO uint32_t dzc : 1; /* [1] */ + __IO uint32_t eoif : 1; /* [2] */ + __IO uint32_t qdzif : 1; /* [3] */ + __IO uint32_t edzif : 1; /* [4] */ + __IO uint32_t reserved1 : 3; /* [7:5] */ + __IO uint32_t cuss : 1; /* [8] */ + __IO uint32_t curs : 1; /* [9] */ + __IO uint32_t lsamprx : 1; /* [10] */ + __IO uint32_t realrx : 1; /* [11] */ + __IO uint32_t reserved2 : 20;/*[31:12] */ + } msts_bit; + }; + + /** + * @brief can tsts register, offset:0x08 + */ + union + { + __IO uint32_t tsts; + struct + { + __IO uint32_t tm0tcf : 1; /* [0] */ + __IO uint32_t tm0tsf : 1; /* [1] */ + __IO uint32_t tm0alf : 1; /* [2] */ + __IO uint32_t tm0tef : 1; /* [3] */ + __IO uint32_t reserved1 : 3; /* [6:4] */ + __IO uint32_t tm0ct : 1; /* [7] */ + __IO uint32_t tm1tcf : 1; /* [8] */ + __IO uint32_t tm1tsf : 1; /* [9] */ + __IO uint32_t tm1alf : 1; /* [10] */ + __IO uint32_t tm1tef : 1; /* [11] */ + __IO uint32_t reserved2 : 3; /* [14:12] */ + __IO uint32_t tm1ct : 1; /* [15] */ + __IO uint32_t tm2tcf : 1; /* [16] */ + __IO uint32_t tm2tsf : 1; /* [17] */ + __IO uint32_t tm2alf : 1; /* [18] */ + __IO uint32_t tm2tef : 1; /* [19] */ + __IO uint32_t reserved3 : 3; /* [22:20] */ + __IO uint32_t tm2ct : 1; /* [23] */ + __IO uint32_t tmnr : 2; /* [25:24] */ + __IO uint32_t tm0ef : 1; /* [26] */ + __IO uint32_t tm1ef : 1; /* [27] */ + __IO uint32_t tm2ef : 1; /* [28] */ + __IO uint32_t tm0lpf : 1; /* [29] */ + __IO uint32_t tm1lpf : 1; /* [30] */ + __IO uint32_t tm2lpf : 1; /* [31] */ + } tsts_bit; + }; + + /** + * @brief can rf0 register, offset:0x0C + */ + union + { + __IO uint32_t rf0; + struct + { + __IO uint32_t rf0mn : 2; /* [1:0] */ + __IO uint32_t reserved1 : 1; /* [2] */ + __IO uint32_t rf0ff : 1; /* [3] */ + __IO uint32_t rf0of : 1; /* [4] */ + __IO uint32_t rf0r : 1; /* [5] */ + __IO uint32_t reserved2 : 26;/* [31:6] */ + } rf0_bit; + }; + + /** + * @brief can rf1 register, offset:0x10 + */ + union + { + __IO uint32_t rf1; + struct + { + __IO uint32_t rf1mn : 2; /* [1:0] */ + __IO uint32_t reserved1 : 1; /* [2] */ + __IO uint32_t rf1ff : 1; /* [3] */ + __IO uint32_t rf1of : 1; /* [4] */ + __IO uint32_t rf1r : 1; /* [5] */ + __IO uint32_t reserved2 : 26;/* [31:6] */ + } rf1_bit; + }; + + /** + * @brief can inten register, offset:0x14 + */ + union + { + __IO uint32_t inten; + struct + { + __IO uint32_t tcien : 1; /* [0] */ + __IO uint32_t rf0mien : 1; /* [1] */ + __IO uint32_t rf0fien : 1; /* [2] */ + __IO uint32_t rf0oien : 1; /* [3] */ + __IO uint32_t rf1mien : 1; /* [4] */ + __IO uint32_t rf1fien : 1; /* [5] */ + __IO uint32_t rf1oien : 1; /* [6] */ + __IO uint32_t reserved1 : 1; /* [7] */ + __IO uint32_t eaien : 1; /* [8] */ + __IO uint32_t epien : 1; /* [9] */ + __IO uint32_t boien : 1; /* [10] */ + __IO uint32_t etrien : 1; /* [11] */ + __IO uint32_t reserved2 : 3; /* [14:12] */ + __IO uint32_t eoien : 1; /* [15] */ + __IO uint32_t qdzien : 1; /* [16] */ + __IO uint32_t edzien : 1; /* [17] */ + __IO uint32_t reserved3 : 14;/* [31:18] */ + } inten_bit; + }; + + /** + * @brief can ests register, offset:0x18 + */ + union + { + __IO uint32_t ests; + struct + { + __IO uint32_t eaf : 1; /* [0] */ + __IO uint32_t epf : 1; /* [1] */ + __IO uint32_t bof : 1; /* [2] */ + __IO uint32_t reserved1 : 1; /* [3] */ + __IO uint32_t etr : 3; /* [6:4] */ + __IO uint32_t reserved2 : 9; /* [15:7] */ + __IO uint32_t tec : 8; /* [23:16] */ + __IO uint32_t rec : 8; /* [31:24] */ + } ests_bit; + }; + + /** + * @brief can btmg register, offset:0x1C + */ + union + { + __IO uint32_t btmg; + struct + { + __IO uint32_t brdiv : 12;/* [11:0] */ + __IO uint32_t reserved1 : 4; /* [15:12] */ + __IO uint32_t bts1 : 4; /* [19:16] */ + __IO uint32_t bts2 : 3; /* [22:20] */ + __IO uint32_t reserved2 : 1; /* [23] */ + __IO uint32_t rsaw : 2; /* [25:24] */ + __IO uint32_t reserved3 : 4; /* [29:26] */ + __IO uint32_t lben : 1; /* [30] */ + __IO uint32_t loen : 1; /* [31] */ + } btmg_bit; + }; + + /** + * @brief can reserved register, offset:0x20~0x17C + */ + __IO uint32_t reserved1[88]; + + /** + * @brief can controller area network tx mailbox register, offset:0x180~0x1AC + */ + can_tx_mailbox_type tx_mailbox[3]; + + /** + * @brief can controller area network fifo mailbox register, offset:0x1B0~0x1CC + */ + can_fifo_mailbox_type fifo_mailbox[2]; + + /** + * @brief can reserved register, offset:0x1D0~0x1FC + */ + __IO uint32_t reserved2[12]; + + /** + * @brief can fctrl register, offset:0x200 + */ + union + { + __IO uint32_t fctrl; + struct + { + __IO uint32_t fcs : 1; /* [0] */ + __IO uint32_t reserved1 : 31;/* [31:1] */ + } fctrl_bit; + }; + + /** + * @brief can fmcfg register, offset:0x204 + */ + union + { + __IO uint32_t fmcfg; + struct + { + __IO uint32_t fmsel0 : 1; /* [0] */ + __IO uint32_t fmsel1 : 1; /* [1] */ + __IO uint32_t fmsel2 : 1; /* [2] */ + __IO uint32_t fmsel3 : 1; /* [3] */ + __IO uint32_t fmsel4 : 1; /* [4] */ + __IO uint32_t fmsel5 : 1; /* [5] */ + __IO uint32_t fmsel6 : 1; /* [6] */ + __IO uint32_t fmsel7 : 1; /* [7] */ + __IO uint32_t fmsel8 : 1; /* [8] */ + __IO uint32_t fmsel9 : 1; /* [9] */ + __IO uint32_t fmsel10 : 1; /* [10] */ + __IO uint32_t fmsel11 : 1; /* [11] */ + __IO uint32_t fmsel12 : 1; /* [12] */ + __IO uint32_t fmsel13 : 1; /* [13] */ + __IO uint32_t reserved1 : 18;/* [31:14] */ + } fmcfg_bit; + }; + + /** + * @brief can reserved register, offset:0x208 + */ + __IO uint32_t reserved3; + + /** + * @brief can fbwcfg register, offset:0x20C + */ + union + { + __IO uint32_t fbwcfg; + struct + { + __IO uint32_t fbwsel0 : 1; /* [0] */ + __IO uint32_t fbwsel1 : 1; /* [1] */ + __IO uint32_t fbwsel2 : 1; /* [2] */ + __IO uint32_t fbwsel3 : 1; /* [3] */ + __IO uint32_t fbwsel4 : 1; /* [4] */ + __IO uint32_t fbwsel5 : 1; /* [5] */ + __IO uint32_t fbwsel6 : 1; /* [6] */ + __IO uint32_t fbwsel7 : 1; /* [7] */ + __IO uint32_t fbwsel8 : 1; /* [8] */ + __IO uint32_t fbwsel9 : 1; /* [9] */ + __IO uint32_t fbwsel10 : 1; /* [10] */ + __IO uint32_t fbwsel11 : 1; /* [11] */ + __IO uint32_t fbwsel12 : 1; /* [12] */ + __IO uint32_t fbwsel13 : 1; /* [13] */ + __IO uint32_t reserved1 : 18;/* [31:14] */ + } fbwcfg_bit; + }; + + /** + * @brief can reserved register, offset:0x210 + */ + __IO uint32_t reserved4; + + /** + * @brief can frf register, offset:0x214 + */ + union + { + __IO uint32_t frf; + struct + { + __IO uint32_t frfsel0 : 1; /* [0] */ + __IO uint32_t frfsel1 : 1; /* [1] */ + __IO uint32_t frfsel2 : 1; /* [2] */ + __IO uint32_t frfsel3 : 1; /* [3] */ + __IO uint32_t frfsel4 : 1; /* [4] */ + __IO uint32_t frfsel5 : 1; /* [5] */ + __IO uint32_t frfsel6 : 1; /* [6] */ + __IO uint32_t frfsel7 : 1; /* [7] */ + __IO uint32_t frfsel8 : 1; /* [8] */ + __IO uint32_t frfsel9 : 1; /* [9] */ + __IO uint32_t frfsel10 : 1; /* [10] */ + __IO uint32_t frfsel11 : 1; /* [11] */ + __IO uint32_t frfsel12 : 1; /* [12] */ + __IO uint32_t frfsel13 : 1; /* [13] */ + __IO uint32_t reserved1 : 18;/* [31:14] */ + } frf_bit; + }; + + /** + * @brief can reserved register, offset:0x218 + */ + __IO uint32_t reserved5; + + /** + * @brief can facfg register, offset:0x21C + */ + union + { + __IO uint32_t facfg; + struct + { + __IO uint32_t faen0 : 1; /* [0] */ + __IO uint32_t faen1 : 1; /* [1] */ + __IO uint32_t faen2 : 1; /* [2] */ + __IO uint32_t faen3 : 1; /* [3] */ + __IO uint32_t faen4 : 1; /* [4] */ + __IO uint32_t faen5 : 1; /* [5] */ + __IO uint32_t faen6 : 1; /* [6] */ + __IO uint32_t faen7 : 1; /* [7] */ + __IO uint32_t faen8 : 1; /* [8] */ + __IO uint32_t faen9 : 1; /* [9] */ + __IO uint32_t faen10 : 1; /* [10] */ + __IO uint32_t faen11 : 1; /* [11] */ + __IO uint32_t faen12 : 1; /* [12] */ + __IO uint32_t faen13 : 1; /* [13] */ + __IO uint32_t reserved1 : 18;/* [31:14] */ + } facfg_bit; + }; + + /** + * @brief can reserved register, offset:0x220~0x23C + */ + __IO uint32_t reserved6[8]; + + /** + * @brief can ffb register, offset:0x240~0x2AC + */ + can_filter_register_type ffb[14]; +} can_type; + +/** + * @} + */ + +#define CAN1 ((can_type *) CAN1_BASE) +#define CAN2 ((can_type *) CAN2_BASE) + +/** @defgroup CAN_exported_functions + * @{ + */ + +void can_reset(can_type* can_x); +void can_baudrate_default_para_init(can_baudrate_type* can_baudrate_struct); +error_status can_baudrate_set(can_type* can_x, can_baudrate_type* can_baudrate_struct); +void can_default_para_init(can_base_type* can_base_struct); +error_status can_base_init(can_type* can_x, can_base_type* can_base_struct); +void can_filter_default_para_init(can_filter_init_type* can_filter_init_struct); +void can_filter_init(can_type* can_x, can_filter_init_type* can_filter_init_struct); +void can_debug_transmission_prohibit(can_type* can_x, confirm_state new_state); +void can_ttc_mode_enable(can_type* can_x, confirm_state new_state); +uint8_t can_message_transmit(can_type* can_x, can_tx_message_type* tx_message_struct); +can_transmit_status_type can_transmit_status_get(can_type* can_x, can_tx_mailbox_num_type transmit_mailbox); +void can_transmit_cancel(can_type* can_x, can_tx_mailbox_num_type transmit_mailbox); +void can_message_receive(can_type* can_x, can_rx_fifo_num_type fifo_number, can_rx_message_type* rx_message_struct); +void can_receive_fifo_release(can_type* can_x, can_rx_fifo_num_type fifo_number); +uint8_t can_receive_message_pending_get(can_type* can_x, can_rx_fifo_num_type fifo_number); +error_status can_operating_mode_set(can_type* can_x, can_operating_mode_type can_operating_mode); +can_enter_doze_status_type can_doze_mode_enter(can_type* can_x); +can_quit_doze_status_type can_doze_mode_exit(can_type* can_x); +can_error_record_type can_error_type_record_get(can_type* can_x); +uint8_t can_receive_error_counter_get(can_type* can_x); +uint8_t can_transmit_error_counter_get(can_type* can_x); +void can_interrupt_enable(can_type* can_x, uint32_t can_int, confirm_state new_state); +flag_status can_flag_get(can_type* can_x, uint32_t can_flag); +void can_flag_clear(can_type* can_x, uint32_t can_flag); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_crc.h b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_crc.h new file mode 100644 index 0000000..99a8157 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_crc.h @@ -0,0 +1,172 @@ +/** + ************************************************************************** + * @file at32f403a_407_crc.h + * @version v2.0.9 + * @date 2022-04-25 + * @brief at32f403a_407 crc header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_CRC_H +#define __AT32F403A_407_CRC_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* includes ------------------------------------------------------------------*/ +#include "at32f403a_407.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @addtogroup CRC + * @{ + */ + +/** @defgroup CRC_exported_types + * @{ + */ + +/** + * @brief crc reverse input data + */ +typedef enum +{ + CRC_REVERSE_INPUT_NO_AFFECTE = 0x00, /*!< input data no reverse */ + CRC_REVERSE_INPUT_BY_BYTE = 0x01, /*!< input data reverse by byte */ + CRC_REVERSE_INPUT_BY_HALFWORD = 0x02, /*!< input data reverse by half word */ + CRC_REVERSE_INPUT_BY_WORD = 0x03 /*!< input data reverse by word */ +} crc_reverse_input_type; + +/** + * @brief crc reverse output data + */ +typedef enum +{ + CRC_REVERSE_OUTPUT_NO_AFFECTE = 0x00, /*!< output data no reverse */ + CRC_REVERSE_OUTPUT_DATA = 0x01 /*!< output data reverse by word */ +} crc_reverse_output_type; + +/** + * @brief type define crc register all + */ +typedef struct +{ + /** + * @brief crc dt register, offset:0x00 + */ + union + { + __IO uint32_t dt; + struct + { + __IO uint32_t dt : 32; /* [31:0] */ + } dt_bit; + }; + + /** + * @brief crc cdt register, offset:0x04 + */ + union + { + __IO uint32_t cdt; + struct + { + __IO uint32_t cdt : 8 ; /* [7:0] */ + __IO uint32_t reserved1 : 24 ;/* [31:8] */ + } cdt_bit; + }; + + /** + * @brief crc ctrl register, offset:0x08 + */ + union + { + __IO uint32_t ctrl; + struct + { + __IO uint32_t rst : 1 ; /* [0] */ + __IO uint32_t reserved1 : 4 ; /* [4:1] */ + __IO uint32_t revid : 2 ; /* [6:5] */ + __IO uint32_t revod : 1 ; /* [7] */ + __IO uint32_t reserved2 : 24 ;/* [31:8] */ + } ctrl_bit; + }; + + /** + * @brief crm reserved1 register, offset:0x0C + */ + __IO uint32_t reserved1; + + /** + * @brief crc idt register, offset:0x10 + */ + union + { + __IO uint32_t idt; + struct + { + __IO uint32_t idt : 32; /* [31:0] */ + } idt_bit; + }; + +} crc_type; + +/** + * @} + */ + +#define CRC ((crc_type *) CRC_BASE) + +/** @defgroup CRC_exported_functions + * @{ + */ + +void crc_data_reset(void); +uint32_t crc_one_word_calculate(uint32_t data); +uint32_t crc_block_calculate(uint32_t *pbuffer, uint32_t length); +uint32_t crc_data_get(void); +void crc_common_data_set(uint8_t cdt_value); +uint8_t crc_common_date_get(void); +void crc_init_data_set(uint32_t value); +void crc_reverse_input_data_set(crc_reverse_input_type value); +void crc_reverse_output_data_set(crc_reverse_output_type value); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_crm.h b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_crm.h new file mode 100644 index 0000000..eaaa59e --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_crm.h @@ -0,0 +1,1142 @@ +/** + ************************************************************************** + * @file at32f403a_407_crm.h + * @version v2.0.9 + * @date 2022-04-25 + * @brief at32f403a_407 crm header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_CRM_H +#define __AT32F403A_407_CRM_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* includes ------------------------------------------------------------------*/ +#include "at32f403a_407.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @addtogroup CRM + * @{ + */ + +#define CRM_REG(value) PERIPH_REG(CRM_BASE, value) +#define CRM_REG_BIT(value) PERIPH_REG_BIT(value) + +/** @defgroup CRM_flags_definition + * @brief crm flag + * @{ + */ + +#define CRM_HICK_STABLE_FLAG MAKE_VALUE(0x00, 1) /*!< high speed internal clock stable flag */ +#define CRM_HEXT_STABLE_FLAG MAKE_VALUE(0x00, 17) /*!< high speed external crystal stable flag */ +#define CRM_PLL_STABLE_FLAG MAKE_VALUE(0x00, 25) /*!< phase locking loop stable flag */ +#define CRM_LEXT_STABLE_FLAG MAKE_VALUE(0x20, 1) /*!< low speed external crystal stable flag */ +#define CRM_LICK_STABLE_FLAG MAKE_VALUE(0x24, 1) /*!< low speed internal clock stable flag */ +#define CRM_ALL_RESET_FLAG MAKE_VALUE(0x24, 24) /*!< all reset flag */ +#define CRM_NRST_RESET_FLAG MAKE_VALUE(0x24, 26) /*!< nrst pin reset flag */ +#define CRM_POR_RESET_FLAG MAKE_VALUE(0x24, 27) /*!< power on reset flag */ +#define CRM_SW_RESET_FLAG MAKE_VALUE(0x24, 28) /*!< software reset flag */ +#define CRM_WDT_RESET_FLAG MAKE_VALUE(0x24, 29) /*!< watchdog timer reset flag */ +#define CRM_WWDT_RESET_FLAG MAKE_VALUE(0x24, 30) /*!< window watchdog timer reset flag */ +#define CRM_LOWPOWER_RESET_FLAG MAKE_VALUE(0x24, 31) /*!< low-power reset flag */ +#define CRM_LICK_READY_INT_FLAG MAKE_VALUE(0x08, 0) /*!< low speed internal clock stable interrupt ready flag */ +#define CRM_LEXT_READY_INT_FLAG MAKE_VALUE(0x08, 1) /*!< low speed external crystal stable interrupt ready flag */ +#define CRM_HICK_READY_INT_FLAG MAKE_VALUE(0x08, 2) /*!< high speed internal clock stable interrupt ready flag */ +#define CRM_HEXT_READY_INT_FLAG MAKE_VALUE(0x08, 3) /*!< high speed external crystal stable interrupt ready flag */ +#define CRM_PLL_READY_INT_FLAG MAKE_VALUE(0x08, 4) /*!< phase locking loop stable interrupt ready flag */ +#define CRM_CLOCK_FAILURE_INT_FLAG MAKE_VALUE(0x08, 7) /*!< clock failure interrupt ready flag */ + +/** + * @} + */ + +/** @defgroup CRM_interrupts_definition + * @brief crm interrupt + * @{ + */ + +#define CRM_LICK_STABLE_INT ((uint32_t)0x00000100) /*!< low speed internal clock stable interrupt */ +#define CRM_LEXT_STABLE_INT ((uint32_t)0x00000200) /*!< low speed external crystal stable interrupt */ +#define CRM_HICK_STABLE_INT ((uint32_t)0x00000400) /*!< high speed internal clock stable interrupt */ +#define CRM_HEXT_STABLE_INT ((uint32_t)0x00000800) /*!< high speed external crystal stable interrupt */ +#define CRM_PLL_STABLE_INT ((uint32_t)0x00001000) /*!< phase locking loop stable interrupt */ +#define CRM_CLOCK_FAILURE_INT ((uint32_t)0x00800000) /*!< clock failure interrupt */ + +/** + * @} + */ + +/** @defgroup CRM_exported_types + * @{ + */ + +/** + * @brief crm periph clock + */ +typedef enum +{ +#if defined (AT32F403Axx) + /* ahb periph */ + CRM_DMA1_PERIPH_CLOCK = MAKE_VALUE(0x14, 0), /*!< dma1 periph clock */ + CRM_DMA2_PERIPH_CLOCK = MAKE_VALUE(0x14, 1), /*!< dma2 periph clock */ + CRM_CRC_PERIPH_CLOCK = MAKE_VALUE(0x14, 6), /*!< crc periph clock */ + CRM_XMC_PERIPH_CLOCK = MAKE_VALUE(0x14, 8), /*!< xmc periph clock */ + CRM_SDIO1_PERIPH_CLOCK = MAKE_VALUE(0x14, 10), /*!< sdio1 periph clock */ + CRM_SDIO2_PERIPH_CLOCK = MAKE_VALUE(0x14, 11), /*!< sdio2 periph clock */ + /* apb2 periph */ + CRM_IOMUX_PERIPH_CLOCK = MAKE_VALUE(0x18, 0), /*!< iomux periph clock */ + CRM_GPIOA_PERIPH_CLOCK = MAKE_VALUE(0x18, 2), /*!< gpioa periph clock */ + CRM_GPIOB_PERIPH_CLOCK = MAKE_VALUE(0x18, 3), /*!< gpiob periph clock */ + CRM_GPIOC_PERIPH_CLOCK = MAKE_VALUE(0x18, 4), /*!< gpioc periph clock */ + CRM_GPIOD_PERIPH_CLOCK = MAKE_VALUE(0x18, 5), /*!< gpiod periph clock */ + CRM_GPIOE_PERIPH_CLOCK = MAKE_VALUE(0x18, 6), /*!< gpioe periph clock */ + CRM_ADC1_PERIPH_CLOCK = MAKE_VALUE(0x18, 9), /*!< adc1 periph clock */ + CRM_ADC2_PERIPH_CLOCK = MAKE_VALUE(0x18, 10), /*!< adc2 periph clock */ + CRM_TMR1_PERIPH_CLOCK = MAKE_VALUE(0x18, 11), /*!< tmr1 periph clock */ + CRM_SPI1_PERIPH_CLOCK = MAKE_VALUE(0x18, 12), /*!< spi1 periph clock */ + CRM_TMR8_PERIPH_CLOCK = MAKE_VALUE(0x18, 13), /*!< tmr8 periph clock */ + CRM_USART1_PERIPH_CLOCK = MAKE_VALUE(0x18, 14), /*!< usart1 periph clock */ + CRM_ADC3_PERIPH_CLOCK = MAKE_VALUE(0x18, 15), /*!< adc3 periph clock */ + CRM_TMR9_PERIPH_CLOCK = MAKE_VALUE(0x18, 19), /*!< tmr9 periph clock */ + CRM_TMR10_PERIPH_CLOCK = MAKE_VALUE(0x18, 20), /*!< tmr10 periph clock */ + CRM_TMR11_PERIPH_CLOCK = MAKE_VALUE(0x18, 21), /*!< tmr11 periph clock */ + CRM_ACC_PERIPH_CLOCK = MAKE_VALUE(0x18, 22), /*!< acc periph clock */ + CRM_I2C3_PERIPH_CLOCK = MAKE_VALUE(0x18, 23), /*!< i2c3 periph clock */ + CRM_USART6_PERIPH_CLOCK = MAKE_VALUE(0x18, 24), /*!< usart6 periph clock */ + CRM_UART7_PERIPH_CLOCK = MAKE_VALUE(0x18, 25), /*!< uart7 periph clock */ + CRM_UART8_PERIPH_CLOCK = MAKE_VALUE(0x18, 26), /*!< uart8 periph clock */ + /* apb1 periph */ + CRM_TMR2_PERIPH_CLOCK = MAKE_VALUE(0x1C, 0), /*!< tmr2 periph clock */ + CRM_TMR3_PERIPH_CLOCK = MAKE_VALUE(0x1C, 1), /*!< tmr3 periph clock */ + CRM_TMR4_PERIPH_CLOCK = MAKE_VALUE(0x1C, 2), /*!< tmr4 periph clock */ + CRM_TMR5_PERIPH_CLOCK = MAKE_VALUE(0x1C, 3), /*!< tmr5 periph clock */ + CRM_TMR6_PERIPH_CLOCK = MAKE_VALUE(0x1C, 4), /*!< tmr6 periph clock */ + CRM_TMR7_PERIPH_CLOCK = MAKE_VALUE(0x1C, 5), /*!< tmr7 periph clock */ + CRM_TMR12_PERIPH_CLOCK = MAKE_VALUE(0x1C, 6), /*!< tmr12 periph clock */ + CRM_TMR13_PERIPH_CLOCK = MAKE_VALUE(0x1C, 7), /*!< tmr13 periph clock */ + CRM_TMR14_PERIPH_CLOCK = MAKE_VALUE(0x1C, 8), /*!< tmr14 periph clock */ + CRM_WWDT_PERIPH_CLOCK = MAKE_VALUE(0x1C, 11), /*!< wwdt periph clock */ + CRM_SPI2_PERIPH_CLOCK = MAKE_VALUE(0x1C, 14), /*!< spi2 periph clock */ + CRM_SPI3_PERIPH_CLOCK = MAKE_VALUE(0x1C, 15), /*!< spi3 periph clock */ + CRM_SPI4_PERIPH_CLOCK = MAKE_VALUE(0x1C, 16), /*!< spi4 periph clock */ + CRM_USART2_PERIPH_CLOCK = MAKE_VALUE(0x1C, 17), /*!< usart2 periph clock */ + CRM_USART3_PERIPH_CLOCK = MAKE_VALUE(0x1C, 18), /*!< usart3 periph clock */ + CRM_UART4_PERIPH_CLOCK = MAKE_VALUE(0x1C, 19), /*!< uart4 periph clock */ + CRM_UART5_PERIPH_CLOCK = MAKE_VALUE(0x1C, 20), /*!< uart5 periph clock */ + CRM_I2C1_PERIPH_CLOCK = MAKE_VALUE(0x1C, 21), /*!< i2c1 periph clock */ + CRM_I2C2_PERIPH_CLOCK = MAKE_VALUE(0x1C, 22), /*!< i2c2 periph clock */ + CRM_USB_PERIPH_CLOCK = MAKE_VALUE(0x1C, 23), /*!< usb periph clock */ + CRM_CAN1_PERIPH_CLOCK = MAKE_VALUE(0x1C, 25), /*!< can1 periph clock */ + CRM_CAN2_PERIPH_CLOCK = MAKE_VALUE(0x1C, 26), /*!< can2 periph clock */ + CRM_BPR_PERIPH_CLOCK = MAKE_VALUE(0x1C, 27), /*!< bpr periph clock */ + CRM_PWC_PERIPH_CLOCK = MAKE_VALUE(0x1C, 28), /*!< pwc periph clock */ + CRM_DAC_PERIPH_CLOCK = MAKE_VALUE(0x1C, 29) /*!< dac periph clock */ +#endif + +#if defined (AT32F407xx) + /* ahb periph */ + CRM_DMA1_PERIPH_CLOCK = MAKE_VALUE(0x14, 0), /*!< dma1 periph clock */ + CRM_DMA2_PERIPH_CLOCK = MAKE_VALUE(0x14, 1), /*!< dma2 periph clock */ + CRM_CRC_PERIPH_CLOCK = MAKE_VALUE(0x14, 6), /*!< crc periph clock */ + CRM_XMC_PERIPH_CLOCK = MAKE_VALUE(0x14, 8), /*!< xmc periph clock */ + CRM_SDIO1_PERIPH_CLOCK = MAKE_VALUE(0x14, 10), /*!< sdio1 periph clock */ + CRM_SDIO2_PERIPH_CLOCK = MAKE_VALUE(0x14, 11), /*!< sdio2 periph clock */ + CRM_EMAC_PERIPH_CLOCK = MAKE_VALUE(0x14, 14), /*!< emac periph clock */ + CRM_EMACTX_PERIPH_CLOCK = MAKE_VALUE(0x14, 15), /*!< emac tx periph clock */ + CRM_EMACRX_PERIPH_CLOCK = MAKE_VALUE(0x14, 16), /*!< emac rx periph clock */ + CRM_EMACPTP_PERIPH_CLOCK = MAKE_VALUE(0x14, 28), /*!< emac ptp periph clock */ + /* apb2 periph */ + CRM_IOMUX_PERIPH_CLOCK = MAKE_VALUE(0x18, 0), /*!< iomux periph clock */ + CRM_GPIOA_PERIPH_CLOCK = MAKE_VALUE(0x18, 2), /*!< gpioa periph clock */ + CRM_GPIOB_PERIPH_CLOCK = MAKE_VALUE(0x18, 3), /*!< gpiob periph clock */ + CRM_GPIOC_PERIPH_CLOCK = MAKE_VALUE(0x18, 4), /*!< gpioc periph clock */ + CRM_GPIOD_PERIPH_CLOCK = MAKE_VALUE(0x18, 5), /*!< gpiod periph clock */ + CRM_GPIOE_PERIPH_CLOCK = MAKE_VALUE(0x18, 6), /*!< gpioe periph clock */ + CRM_ADC1_PERIPH_CLOCK = MAKE_VALUE(0x18, 9), /*!< adc1 periph clock */ + CRM_ADC2_PERIPH_CLOCK = MAKE_VALUE(0x18, 10), /*!< adc2 periph clock */ + CRM_TMR1_PERIPH_CLOCK = MAKE_VALUE(0x18, 11), /*!< tmr1 periph clock */ + CRM_SPI1_PERIPH_CLOCK = MAKE_VALUE(0x18, 12), /*!< spi1 periph clock */ + CRM_TMR8_PERIPH_CLOCK = MAKE_VALUE(0x18, 13), /*!< tmr8 periph clock */ + CRM_USART1_PERIPH_CLOCK = MAKE_VALUE(0x18, 14), /*!< usart1 periph clock */ + CRM_ADC3_PERIPH_CLOCK = MAKE_VALUE(0x18, 15), /*!< adc3 periph clock */ + CRM_TMR9_PERIPH_CLOCK = MAKE_VALUE(0x18, 19), /*!< tmr9 periph clock */ + CRM_TMR10_PERIPH_CLOCK = MAKE_VALUE(0x18, 20), /*!< tmr10 periph clock */ + CRM_TMR11_PERIPH_CLOCK = MAKE_VALUE(0x18, 21), /*!< tmr11 periph clock */ + CRM_ACC_PERIPH_CLOCK = MAKE_VALUE(0x18, 22), /*!< acc periph clock */ + CRM_I2C3_PERIPH_CLOCK = MAKE_VALUE(0x18, 23), /*!< i2c3 periph clock */ + CRM_USART6_PERIPH_CLOCK = MAKE_VALUE(0x18, 24), /*!< usart6 periph clock */ + CRM_UART7_PERIPH_CLOCK = MAKE_VALUE(0x18, 25), /*!< uart7 periph clock */ + CRM_UART8_PERIPH_CLOCK = MAKE_VALUE(0x18, 26), /*!< uart8 periph clock */ + /* apb1 periph */ + CRM_TMR2_PERIPH_CLOCK = MAKE_VALUE(0x1C, 0), /*!< tmr2 periph clock */ + CRM_TMR3_PERIPH_CLOCK = MAKE_VALUE(0x1C, 1), /*!< tmr3 periph clock */ + CRM_TMR4_PERIPH_CLOCK = MAKE_VALUE(0x1C, 2), /*!< tmr4 periph clock */ + CRM_TMR5_PERIPH_CLOCK = MAKE_VALUE(0x1C, 3), /*!< tmr5 periph clock */ + CRM_TMR6_PERIPH_CLOCK = MAKE_VALUE(0x1C, 4), /*!< tmr6 periph clock */ + CRM_TMR7_PERIPH_CLOCK = MAKE_VALUE(0x1C, 5), /*!< tmr7 periph clock */ + CRM_TMR12_PERIPH_CLOCK = MAKE_VALUE(0x1C, 6), /*!< tmr12 periph clock */ + CRM_TMR13_PERIPH_CLOCK = MAKE_VALUE(0x1C, 7), /*!< tmr13 periph clock */ + CRM_TMR14_PERIPH_CLOCK = MAKE_VALUE(0x1C, 8), /*!< tmr14 periph clock */ + CRM_WWDT_PERIPH_CLOCK = MAKE_VALUE(0x1C, 11), /*!< wwdt periph clock */ + CRM_SPI2_PERIPH_CLOCK = MAKE_VALUE(0x1C, 14), /*!< spi2 periph clock */ + CRM_SPI3_PERIPH_CLOCK = MAKE_VALUE(0x1C, 15), /*!< spi3 periph clock */ + CRM_SPI4_PERIPH_CLOCK = MAKE_VALUE(0x1C, 16), /*!< spi4 periph clock */ + CRM_USART2_PERIPH_CLOCK = MAKE_VALUE(0x1C, 17), /*!< usart2 periph clock */ + CRM_USART3_PERIPH_CLOCK = MAKE_VALUE(0x1C, 18), /*!< usart3 periph clock */ + CRM_UART4_PERIPH_CLOCK = MAKE_VALUE(0x1C, 19), /*!< uart4 periph clock */ + CRM_UART5_PERIPH_CLOCK = MAKE_VALUE(0x1C, 20), /*!< uart5 periph clock */ + CRM_I2C1_PERIPH_CLOCK = MAKE_VALUE(0x1C, 21), /*!< i2c1 periph clock */ + CRM_I2C2_PERIPH_CLOCK = MAKE_VALUE(0x1C, 22), /*!< i2c2 periph clock */ + CRM_USB_PERIPH_CLOCK = MAKE_VALUE(0x1C, 23), /*!< usb periph clock */ + CRM_CAN1_PERIPH_CLOCK = MAKE_VALUE(0x1C, 25), /*!< can1 periph clock */ + CRM_CAN2_PERIPH_CLOCK = MAKE_VALUE(0x1C, 26), /*!< can2 periph clock */ + CRM_BPR_PERIPH_CLOCK = MAKE_VALUE(0x1C, 27), /*!< bpr periph clock */ + CRM_PWC_PERIPH_CLOCK = MAKE_VALUE(0x1C, 28), /*!< pwc periph clock */ + CRM_DAC_PERIPH_CLOCK = MAKE_VALUE(0x1C, 29) /*!< dac periph clock */ +#endif + +} crm_periph_clock_type; + +/** + * @brief crm periph reset + */ +typedef enum +{ +#if defined (AT32F403Axx) + /* apb2 periph */ + CRM_IOMUX_PERIPH_RESET = MAKE_VALUE(0x0C, 0), /*!< iomux periph reset */ + CRM_EXINT_PERIPH_RESET = MAKE_VALUE(0x0C, 1), /*!< exint periph reset */ + CRM_GPIOA_PERIPH_RESET = MAKE_VALUE(0x0C, 2), /*!< gpioa periph reset */ + CRM_GPIOB_PERIPH_RESET = MAKE_VALUE(0x0C, 3), /*!< gpiob periph reset */ + CRM_GPIOC_PERIPH_RESET = MAKE_VALUE(0x0C, 4), /*!< gpioc periph reset */ + CRM_GPIOD_PERIPH_RESET = MAKE_VALUE(0x0C, 5), /*!< gpiod periph reset */ + CRM_GPIOE_PERIPH_RESET = MAKE_VALUE(0x0C, 6), /*!< gpioe periph reset */ + CRM_ADC1_PERIPH_RESET = MAKE_VALUE(0x0C, 9), /*!< adc1 periph reset */ + CRM_ADC2_PERIPH_RESET = MAKE_VALUE(0x0C, 10), /*!< adc2 periph reset */ + CRM_TMR1_PERIPH_RESET = MAKE_VALUE(0x0C, 11), /*!< tmr1 periph reset */ + CRM_SPI1_PERIPH_RESET = MAKE_VALUE(0x0C, 12), /*!< spi2 periph reset */ + CRM_TMR8_PERIPH_RESET = MAKE_VALUE(0x0C, 13), /*!< tmr8 periph reset */ + CRM_USART1_PERIPH_RESET = MAKE_VALUE(0x0C, 14), /*!< usart1 periph reset */ + CRM_ADC3_PERIPH_RESET = MAKE_VALUE(0x0C, 15), /*!< adc3 periph reset */ + CRM_TMR9_PERIPH_RESET = MAKE_VALUE(0x0C, 19), /*!< tmr9 periph reset */ + CRM_TMR10_PERIPH_RESET = MAKE_VALUE(0x0C, 20), /*!< tmr10 periph reset */ + CRM_TMR11_PERIPH_RESET = MAKE_VALUE(0x0C, 21), /*!< tmr11 periph reset */ + CRM_ACC_PERIPH_RESET = MAKE_VALUE(0x0C, 22), /*!< acc periph reset */ + CRM_I2C3_PERIPH_RESET = MAKE_VALUE(0x0C, 23), /*!< i2c3 periph reset */ + CRM_USART6_PERIPH_RESET = MAKE_VALUE(0x0C, 24), /*!< usart6 periph reset */ + CRM_UART7_PERIPH_RESET = MAKE_VALUE(0x0C, 25), /*!< uart7 periph reset */ + CRM_UART8_PERIPH_RESET = MAKE_VALUE(0x0C, 26), /*!< uart8 periph reset */ + /* apb1 periph */ + CRM_TMR2_PERIPH_RESET = MAKE_VALUE(0x10, 0), /*!< tmr2 periph reset */ + CRM_TMR3_PERIPH_RESET = MAKE_VALUE(0x10, 1), /*!< tmr3 periph reset */ + CRM_TMR4_PERIPH_RESET = MAKE_VALUE(0x10, 2), /*!< tmr4 periph reset */ + CRM_TMR5_PERIPH_RESET = MAKE_VALUE(0x10, 3), /*!< tmr5 periph reset */ + CRM_TMR6_PERIPH_RESET = MAKE_VALUE(0x10, 4), /*!< tmr6 periph reset */ + CRM_TMR7_PERIPH_RESET = MAKE_VALUE(0x10, 5), /*!< tmr7 periph reset */ + CRM_TMR12_PERIPH_RESET = MAKE_VALUE(0x10, 6), /*!< tmr12 periph reset */ + CRM_TMR13_PERIPH_RESET = MAKE_VALUE(0x10, 7), /*!< tmr13 periph reset */ + CRM_TMR14_PERIPH_RESET = MAKE_VALUE(0x10, 8), /*!< tmr14 periph reset */ + CRM_WWDT_PERIPH_RESET = MAKE_VALUE(0x10, 11), /*!< wwdt periph reset */ + CRM_SPI2_PERIPH_RESET = MAKE_VALUE(0x10, 14), /*!< spi2 periph reset */ + CRM_SPI3_PERIPH_RESET = MAKE_VALUE(0x10, 15), /*!< spi3 periph reset */ + CRM_SPI4_PERIPH_RESET = MAKE_VALUE(0x10, 16), /*!< spi4 periph reset */ + CRM_USART2_PERIPH_RESET = MAKE_VALUE(0x10, 17), /*!< usart2 periph reset */ + CRM_USART3_PERIPH_RESET = MAKE_VALUE(0x10, 18), /*!< usart3 periph reset */ + CRM_UART4_PERIPH_RESET = MAKE_VALUE(0x10, 19), /*!< uart4 periph reset */ + CRM_UART5_PERIPH_RESET = MAKE_VALUE(0x10, 20), /*!< uart5 periph reset */ + CRM_I2C1_PERIPH_RESET = MAKE_VALUE(0x10, 21), /*!< i2c1 periph reset */ + CRM_I2C2_PERIPH_RESET = MAKE_VALUE(0x10, 22), /*!< i2c2 periph reset */ + CRM_USB_PERIPH_RESET = MAKE_VALUE(0x10, 23), /*!< usb periph reset */ + CRM_CAN1_PERIPH_RESET = MAKE_VALUE(0x10, 25), /*!< can1 periph reset */ + CRM_CAN2_PERIPH_RESET = MAKE_VALUE(0x10, 26), /*!< can2 periph reset */ + CRM_BPR_PERIPH_RESET = MAKE_VALUE(0x10, 27), /*!< bpr periph reset */ + CRM_PWC_PERIPH_RESET = MAKE_VALUE(0x10, 28), /*!< pwc periph reset */ + CRM_DAC_PERIPH_RESET = MAKE_VALUE(0x10, 29) /*!< dac periph reset */ +#endif + +#if defined (AT32F407xx) + /* ahb periph */ + CRM_EMAC_PERIPH_RESET = MAKE_VALUE(0x28, 14), /*!< emac periph reset */ + /* apb2 periph */ + CRM_IOMUX_PERIPH_RESET = MAKE_VALUE(0x0C, 0), /*!< iomux periph reset */ + CRM_EXINT_PERIPH_RESET = MAKE_VALUE(0x0C, 1), /*!< exint periph reset */ + CRM_GPIOA_PERIPH_RESET = MAKE_VALUE(0x0C, 2), /*!< gpioa periph reset */ + CRM_GPIOB_PERIPH_RESET = MAKE_VALUE(0x0C, 3), /*!< gpiob periph reset */ + CRM_GPIOC_PERIPH_RESET = MAKE_VALUE(0x0C, 4), /*!< gpioc periph reset */ + CRM_GPIOD_PERIPH_RESET = MAKE_VALUE(0x0C, 5), /*!< gpiod periph reset */ + CRM_GPIOE_PERIPH_RESET = MAKE_VALUE(0x0C, 6), /*!< gpioe periph reset */ + CRM_ADC1_PERIPH_RESET = MAKE_VALUE(0x0C, 9), /*!< adc1 periph reset */ + CRM_ADC2_PERIPH_RESET = MAKE_VALUE(0x0C, 10), /*!< adc2 periph reset */ + CRM_TMR1_PERIPH_RESET = MAKE_VALUE(0x0C, 11), /*!< tmr1 periph reset */ + CRM_SPI1_PERIPH_RESET = MAKE_VALUE(0x0C, 12), /*!< spi2 periph reset */ + CRM_TMR8_PERIPH_RESET = MAKE_VALUE(0x0C, 13), /*!< tmr8 periph reset */ + CRM_USART1_PERIPH_RESET = MAKE_VALUE(0x0C, 14), /*!< usart1 periph reset */ + CRM_ADC3_PERIPH_RESET = MAKE_VALUE(0x0C, 15), /*!< adc3 periph reset */ + CRM_TMR9_PERIPH_RESET = MAKE_VALUE(0x0C, 19), /*!< tmr9 periph reset */ + CRM_TMR10_PERIPH_RESET = MAKE_VALUE(0x0C, 20), /*!< tmr10 periph reset */ + CRM_TMR11_PERIPH_RESET = MAKE_VALUE(0x0C, 21), /*!< tmr11 periph reset */ + CRM_ACC_PERIPH_RESET = MAKE_VALUE(0x0C, 22), /*!< acc periph reset */ + CRM_I2C3_PERIPH_RESET = MAKE_VALUE(0x0C, 23), /*!< i2c3 periph reset */ + CRM_USART6_PERIPH_RESET = MAKE_VALUE(0x0C, 24), /*!< usart6 periph reset */ + CRM_UART7_PERIPH_RESET = MAKE_VALUE(0x0C, 25), /*!< uart7 periph reset */ + CRM_UART8_PERIPH_RESET = MAKE_VALUE(0x0C, 26), /*!< uart8 periph reset */ + /* apb1 periph */ + CRM_TMR2_PERIPH_RESET = MAKE_VALUE(0x10, 0), /*!< tmr2 periph reset */ + CRM_TMR3_PERIPH_RESET = MAKE_VALUE(0x10, 1), /*!< tmr3 periph reset */ + CRM_TMR4_PERIPH_RESET = MAKE_VALUE(0x10, 2), /*!< tmr4 periph reset */ + CRM_TMR5_PERIPH_RESET = MAKE_VALUE(0x10, 3), /*!< tmr5 periph reset */ + CRM_TMR6_PERIPH_RESET = MAKE_VALUE(0x10, 4), /*!< tmr6 periph reset */ + CRM_TMR7_PERIPH_RESET = MAKE_VALUE(0x10, 5), /*!< tmr7 periph reset */ + CRM_TMR12_PERIPH_RESET = MAKE_VALUE(0x10, 6), /*!< tmr12 periph reset */ + CRM_TMR13_PERIPH_RESET = MAKE_VALUE(0x10, 7), /*!< tmr13 periph reset */ + CRM_TMR14_PERIPH_RESET = MAKE_VALUE(0x10, 8), /*!< tmr14 periph reset */ + CRM_WWDT_PERIPH_RESET = MAKE_VALUE(0x10, 11), /*!< wwdt periph reset */ + CRM_SPI2_PERIPH_RESET = MAKE_VALUE(0x10, 14), /*!< spi2 periph reset */ + CRM_SPI3_PERIPH_RESET = MAKE_VALUE(0x10, 15), /*!< spi3 periph reset */ + CRM_SPI4_PERIPH_RESET = MAKE_VALUE(0x10, 16), /*!< spi4 periph reset */ + CRM_USART2_PERIPH_RESET = MAKE_VALUE(0x10, 17), /*!< usart2 periph reset */ + CRM_USART3_PERIPH_RESET = MAKE_VALUE(0x10, 18), /*!< usart3 periph reset */ + CRM_UART4_PERIPH_RESET = MAKE_VALUE(0x10, 19), /*!< uart4 periph reset */ + CRM_UART5_PERIPH_RESET = MAKE_VALUE(0x10, 20), /*!< uart5 periph reset */ + CRM_I2C1_PERIPH_RESET = MAKE_VALUE(0x10, 21), /*!< i2c1 periph reset */ + CRM_I2C2_PERIPH_RESET = MAKE_VALUE(0x10, 22), /*!< i2c2 periph reset */ + CRM_USB_PERIPH_RESET = MAKE_VALUE(0x10, 23), /*!< usb periph reset */ + CRM_CAN1_PERIPH_RESET = MAKE_VALUE(0x10, 25), /*!< can1 periph reset */ + CRM_CAN2_PERIPH_RESET = MAKE_VALUE(0x10, 26), /*!< can2 periph reset */ + CRM_BPR_PERIPH_RESET = MAKE_VALUE(0x10, 27), /*!< bpr periph reset */ + CRM_PWC_PERIPH_RESET = MAKE_VALUE(0x10, 28), /*!< pwc periph reset */ + CRM_DAC_PERIPH_RESET = MAKE_VALUE(0x10, 29) /*!< dac periph reset */ +#endif + +} crm_periph_reset_type; + +/** + * @brief crm periph clock in sleep mode + */ +typedef enum +{ + /* ahb periph */ + CRM_SRAM_PERIPH_CLOCK_SLEEP_MODE = MAKE_VALUE(0x14, 2), /*!< sram sleep mode periph clock */ + CRM_FLASH_PERIPH_CLOCK_SLEEP_MODE = MAKE_VALUE(0x14, 4) /*!< flash sleep mode periph clock */ +} crm_periph_clock_sleepmd_type; + +/** + * @brief crm pll mult_x + */ +typedef enum +{ + CRM_PLL_MULT_2 = 0, /*!< pll multiplication factor 2 */ + CRM_PLL_MULT_3 = 1, /*!< pll multiplication factor 3 */ + CRM_PLL_MULT_4 = 2, /*!< pll multiplication factor 4 */ + CRM_PLL_MULT_5 = 3, /*!< pll multiplication factor 5 */ + CRM_PLL_MULT_6 = 4, /*!< pll multiplication factor 6 */ + CRM_PLL_MULT_7 = 5, /*!< pll multiplication factor 7 */ + CRM_PLL_MULT_8 = 6, /*!< pll multiplication factor 8 */ + CRM_PLL_MULT_9 = 7, /*!< pll multiplication factor 9 */ + CRM_PLL_MULT_10 = 8, /*!< pll multiplication factor 10 */ + CRM_PLL_MULT_11 = 9, /*!< pll multiplication factor 11 */ + CRM_PLL_MULT_12 = 10, /*!< pll multiplication factor 12 */ + CRM_PLL_MULT_13 = 11, /*!< pll multiplication factor 13 */ + CRM_PLL_MULT_14 = 12, /*!< pll multiplication factor 14 */ + CRM_PLL_MULT_15 = 13, /*!< pll multiplication factor 15 */ + CRM_PLL_MULT_16 = 15, /*!< pll multiplication factor 16 */ + CRM_PLL_MULT_17 = 16, /*!< pll multiplication factor 17 */ + CRM_PLL_MULT_18 = 17, /*!< pll multiplication factor 18 */ + CRM_PLL_MULT_19 = 18, /*!< pll multiplication factor 19 */ + CRM_PLL_MULT_20 = 19, /*!< pll multiplication factor 20 */ + CRM_PLL_MULT_21 = 20, /*!< pll multiplication factor 21 */ + CRM_PLL_MULT_22 = 21, /*!< pll multiplication factor 22 */ + CRM_PLL_MULT_23 = 22, /*!< pll multiplication factor 23 */ + CRM_PLL_MULT_24 = 23, /*!< pll multiplication factor 24 */ + CRM_PLL_MULT_25 = 24, /*!< pll multiplication factor 25 */ + CRM_PLL_MULT_26 = 25, /*!< pll multiplication factor 26 */ + CRM_PLL_MULT_27 = 26, /*!< pll multiplication factor 27 */ + CRM_PLL_MULT_28 = 27, /*!< pll multiplication factor 28 */ + CRM_PLL_MULT_29 = 28, /*!< pll multiplication factor 29 */ + CRM_PLL_MULT_30 = 29, /*!< pll multiplication factor 30 */ + CRM_PLL_MULT_31 = 30, /*!< pll multiplication factor 31 */ + CRM_PLL_MULT_32 = 31, /*!< pll multiplication factor 32 */ + CRM_PLL_MULT_33 = 32, /*!< pll multiplication factor 33 */ + CRM_PLL_MULT_34 = 33, /*!< pll multiplication factor 34 */ + CRM_PLL_MULT_35 = 34, /*!< pll multiplication factor 35 */ + CRM_PLL_MULT_36 = 35, /*!< pll multiplication factor 36 */ + CRM_PLL_MULT_37 = 36, /*!< pll multiplication factor 37 */ + CRM_PLL_MULT_38 = 37, /*!< pll multiplication factor 38 */ + CRM_PLL_MULT_39 = 38, /*!< pll multiplication factor 39 */ + CRM_PLL_MULT_40 = 39, /*!< pll multiplication factor 40 */ + CRM_PLL_MULT_41 = 40, /*!< pll multiplication factor 41 */ + CRM_PLL_MULT_42 = 41, /*!< pll multiplication factor 42 */ + CRM_PLL_MULT_43 = 42, /*!< pll multiplication factor 43 */ + CRM_PLL_MULT_44 = 43, /*!< pll multiplication factor 44 */ + CRM_PLL_MULT_45 = 44, /*!< pll multiplication factor 45 */ + CRM_PLL_MULT_46 = 45, /*!< pll multiplication factor 46 */ + CRM_PLL_MULT_47 = 46, /*!< pll multiplication factor 47 */ + CRM_PLL_MULT_48 = 47, /*!< pll multiplication factor 48 */ + CRM_PLL_MULT_49 = 48, /*!< pll multiplication factor 49 */ + CRM_PLL_MULT_50 = 49, /*!< pll multiplication factor 50 */ + CRM_PLL_MULT_51 = 50, /*!< pll multiplication factor 51 */ + CRM_PLL_MULT_52 = 51, /*!< pll multiplication factor 52 */ + CRM_PLL_MULT_53 = 52, /*!< pll multiplication factor 53 */ + CRM_PLL_MULT_54 = 53, /*!< pll multiplication factor 54 */ + CRM_PLL_MULT_55 = 54, /*!< pll multiplication factor 55 */ + CRM_PLL_MULT_56 = 55, /*!< pll multiplication factor 56 */ + CRM_PLL_MULT_57 = 56, /*!< pll multiplication factor 57 */ + CRM_PLL_MULT_58 = 57, /*!< pll multiplication factor 58 */ + CRM_PLL_MULT_59 = 58, /*!< pll multiplication factor 59 */ + CRM_PLL_MULT_60 = 59, /*!< pll multiplication factor 60 */ + CRM_PLL_MULT_61 = 60, /*!< pll multiplication factor 61 */ + CRM_PLL_MULT_62 = 61, /*!< pll multiplication factor 62 */ + CRM_PLL_MULT_63 = 62, /*!< pll multiplication factor 63 */ + CRM_PLL_MULT_64 = 63 /*!< pll multiplication factor 64 */ +} crm_pll_mult_type; + +/** + * @brief crm pll clock source + */ +typedef enum +{ + CRM_PLL_SOURCE_HICK = 0x00, /*!< high speed internal clock as pll reference clock source */ + CRM_PLL_SOURCE_HEXT = 0x01, /*!< high speed external crystal as pll reference clock source */ + CRM_PLL_SOURCE_HEXT_DIV = 0x02 /*!< high speed external crystal div as pll reference clock source */ +} crm_pll_clock_source_type; + +/** + * @brief crm pll clock output range + */ +typedef enum +{ + CRM_PLL_OUTPUT_RANGE_LE72MHZ = 0x00, /*!< pll clock output range less than or equal to 72mhz */ + CRM_PLL_OUTPUT_RANGE_GT72MHZ = 0x01 /*!< pll clock output range greater than 72mhz */ +} crm_pll_output_range_type; + +/** + * @brief crm clock source + */ +typedef enum +{ + CRM_CLOCK_SOURCE_HICK = 0x00, /*!< high speed internal clock */ + CRM_CLOCK_SOURCE_HEXT = 0x01, /*!< high speed external crystal */ + CRM_CLOCK_SOURCE_PLL = 0x02, /*!< phase locking loop */ + CRM_CLOCK_SOURCE_LEXT = 0x03, /*!< low speed external crystal */ + CRM_CLOCK_SOURCE_LICK = 0x04 /*!< low speed internal clock */ +} crm_clock_source_type; + +/** + * @brief crm ahb division + */ +typedef enum +{ + CRM_AHB_DIV_1 = 0x00, /*!< sclk div1 to ahbclk */ + CRM_AHB_DIV_2 = 0x08, /*!< sclk div2 to ahbclk */ + CRM_AHB_DIV_4 = 0x09, /*!< sclk div4 to ahbclk */ + CRM_AHB_DIV_8 = 0x0A, /*!< sclk div8 to ahbclk */ + CRM_AHB_DIV_16 = 0x0B, /*!< sclk div16 to ahbclk */ + CRM_AHB_DIV_64 = 0x0C, /*!< sclk div64 to ahbclk */ + CRM_AHB_DIV_128 = 0x0D, /*!< sclk div128 to ahbclk */ + CRM_AHB_DIV_256 = 0x0E, /*!< sclk div256 to ahbclk */ + CRM_AHB_DIV_512 = 0x0F /*!< sclk div512 to ahbclk */ +} crm_ahb_div_type; + +/** + * @brief crm apb1 division + */ +typedef enum +{ + CRM_APB1_DIV_1 = 0x00, /*!< ahbclk div1 to apb1clk */ + CRM_APB1_DIV_2 = 0x04, /*!< ahbclk div2 to apb1clk */ + CRM_APB1_DIV_4 = 0x05, /*!< ahbclk div4 to apb1clk */ + CRM_APB1_DIV_8 = 0x06, /*!< ahbclk div8 to apb1clk */ + CRM_APB1_DIV_16 = 0x07 /*!< ahbclk div16 to apb1clk */ +} crm_apb1_div_type; + +/** + * @brief crm apb2 division + */ +typedef enum +{ + CRM_APB2_DIV_1 = 0x00, /*!< ahbclk div1 to apb2clk */ + CRM_APB2_DIV_2 = 0x04, /*!< ahbclk div2 to apb2clk */ + CRM_APB2_DIV_4 = 0x05, /*!< ahbclk div4 to apb2clk */ + CRM_APB2_DIV_8 = 0x06, /*!< ahbclk div8 to apb2clk */ + CRM_APB2_DIV_16 = 0x07 /*!< ahbclk div16 to apb2clk */ +} crm_apb2_div_type; + +/** + * @brief crm adc division + */ +typedef enum +{ + CRM_ADC_DIV_2 = 0x00, /*!< apb2clk div2 to adcclk */ + CRM_ADC_DIV_4 = 0x01, /*!< apb2clk div4 to adcclk */ + CRM_ADC_DIV_6 = 0x02, /*!< apb2clk div6 to adcclk */ + CRM_ADC_DIV_8 = 0x03, /*!< apb2clk div8 to adcclk */ + CRM_ADC_DIV_12 = 0x05, /*!< apb2clk div12 to adcclk */ + CRM_ADC_DIV_16 = 0x07 /*!< apb2clk div16 to adcclk */ +} crm_adc_div_type; + +/** + * @brief crm usb division + */ +typedef enum +{ + CRM_USB_DIV_1_5 = 0x00, /*!< pllclk div1.5 to usbclk */ + CRM_USB_DIV_1 = 0x01, /*!< pllclk div1 to usbclk */ + CRM_USB_DIV_2_5 = 0x02, /*!< pllclk div2.5 to usbclk */ + CRM_USB_DIV_2 = 0x03, /*!< pllclk div2 to usbclk */ + CRM_USB_DIV_3_5 = 0x04, /*!< pllclk div3.5 to usbclk */ + CRM_USB_DIV_3 = 0x05, /*!< pllclk div3 to usbclk */ + CRM_USB_DIV_4 = 0x06 /*!< pllclk div4 to usbclk */ +} crm_usb_div_type; + +/** + * @brief crm rtc clock + */ +typedef enum +{ + CRM_RTC_CLOCK_NOCLK = 0x00, /*!< no clock as rtc clock source */ + CRM_RTC_CLOCK_LEXT = 0x01, /*!< low speed external crystal as rtc clock source */ + CRM_RTC_CLOCK_LICK = 0x02, /*!< low speed internal clock as rtc clock source */ + CRM_RTC_CLOCK_HEXT_DIV = 0x03 /*!< high speed external crystal div as rtc clock source */ +} crm_rtc_clock_type; + +/** + * @brief crm hick 48mhz division + */ +typedef enum +{ + CRM_HICK48_DIV6 = 0x00, /*!< high speed internal clock (48 mhz) div6 */ + CRM_HICK48_NODIV = 0x01 /*!< high speed internal clock (48 mhz) no div */ +} crm_hick_div_6_type; + +/** + * @brief crm hext division + */ +typedef enum +{ + CRM_HEXT_DIV_2 = 0x00, /*!< high speed external crystal div2 */ + CRM_HEXT_DIV_3 = 0x01, /*!< high speed external crystal div3 */ + CRM_HEXT_DIV_4 = 0x02, /*!< high speed external crystal div4 */ + CRM_HEXT_DIV_5 = 0x03 /*!< high speed external crystal div5 */ +} crm_hext_div_type; + +/** + * @brief crm sclk select + */ +typedef enum +{ + CRM_SCLK_HICK = 0x00, /*!< select high speed internal clock as sclk */ + CRM_SCLK_HEXT = 0x01, /*!< select high speed external crystal as sclk */ + CRM_SCLK_PLL = 0x02 /*!< select phase locking loop clock as sclk */ +} crm_sclk_type; + +/** + * @brief crm clkout select + */ +typedef enum +{ + CRM_CLKOUT_NOCLK = 0x00, /*!< output no clock to clkout pin */ + CRM_CLKOUT_LICK = 0x02, /*!< output low speed internal clock to clkout pin */ + CRM_CLKOUT_LEXT = 0x03, /*!< output low speed external crystal to clkout pin */ + CRM_CLKOUT_SCLK = 0x04, /*!< output system clock to clkout pin */ + CRM_CLKOUT_HICK = 0x05, /*!< output high speed internal clock to clkout pin */ + CRM_CLKOUT_HEXT = 0x06, /*!< output high speed external crystal to clkout pin */ + CRM_CLKOUT_PLL_DIV_2 = 0x07, /*!< output phase locking loop clock div2 to clkout pin */ + CRM_CLKOUT_PLL_DIV_4 = 0x0C, /*!< output phase locking loop clock div4 to clkout pin */ + CRM_CLKOUT_USB = 0x0D, /*!< output usbclk to clkout pin */ + CRM_CLKOUT_ADC = 0x0E /*!< output adcclk to clkout pin */ +} crm_clkout_select_type; + +/** + * @brief crm clkout division + */ +typedef enum +{ + CRM_CLKOUT_DIV_1 = 0x00, /*!< clkout div1 */ + CRM_CLKOUT_DIV_2 = 0x08, /*!< clkout div2 */ + CRM_CLKOUT_DIV_4 = 0x09, /*!< clkout div4 */ + CRM_CLKOUT_DIV_8 = 0x0A, /*!< clkout div8 */ + CRM_CLKOUT_DIV_16 = 0x0B, /*!< clkout div16 */ + CRM_CLKOUT_DIV_64 = 0x0C, /*!< clkout div64 */ + CRM_CLKOUT_DIV_128 = 0x0D, /*!< clkout div128 */ + CRM_CLKOUT_DIV_256 = 0x0E, /*!< clkout div256 */ + CRM_CLKOUT_DIV_512 = 0x0F /*!< clkout div512 */ +} crm_clkout_div_type; + +/** + * @brief crm auto step mode + */ +typedef enum +{ + CRM_AUTO_STEP_MODE_DISABLE = 0x00, /*!< disable auto step mode */ + CRM_AUTO_STEP_MODE_ENABLE = 0x03 /*!< enable auto step mode */ +} crm_auto_step_mode_type; + +/** + * @brief crm usbdev interrupt remap + */ +typedef enum +{ + CRM_USB_INT19_INT20 = 0x00, /*!< usb high and low priority irq numer use 19 and 20 */ + CRM_USB_INT73_INT74 = 0x01 /*!< usb high and low priority irq numer use 73 and 74 */ +} crm_usb_int_map_type; + +/** + * @brief crm usb 48 mhz clock source select + */ +typedef enum +{ + CRM_USB_CLOCK_SOURCE_PLL = 0x00, /*!< select phase locking loop clock as usb clock source */ + CRM_USB_CLOCK_SOURCE_HICK = 0x01 /*!< select high speed internal clock as usb clock source */ +} crm_usb_clock_source_type; + +/** + * @brief crm hick as system clock frequency select + */ +typedef enum +{ + CRM_HICK_SCLK_8MHZ = 0x00, /*!< fixed 8 mhz when hick is selected as sclk */ + CRM_HICK_SCLK_48MHZ = 0x01 /*!< 8 mhz or 48 mhz depend on hickdiv when hick is selected as sclk */ +} crm_hick_sclk_frequency_type; + +/** + * @brief crm emac output pulse width + */ +typedef enum +{ + CRM_EMAC_PULSE_125MS = 0x00, /*!< emac output pulse width 125ms */ + CRM_EMAC_PULSE_1SCLK = 0x01 /*!< emac output pulse width 1 system clock */ +} crm_emac_output_pulse_type; + +/** + * @brief crm clocks freqency structure + */ +typedef struct +{ + uint32_t sclk_freq; /*!< system clock frequency */ + uint32_t ahb_freq; /*!< ahb bus clock frequency */ + uint32_t apb2_freq; /*!< apb2 bus clock frequency */ + uint32_t apb1_freq; /*!< apb1 bus clock frequency */ + uint32_t adc_freq; /*!< adc clock frequency */ +} crm_clocks_freq_type; + +/** + * @brief type define crm register all + */ +typedef struct +{ + /** + * @brief crm ctrl register, offset:0x00 + */ + union + { + __IO uint32_t ctrl; + struct + { + __IO uint32_t hicken : 1; /* [0] */ + __IO uint32_t hickstbl : 1; /* [1] */ + __IO uint32_t hicktrim : 6; /* [7:2] */ + __IO uint32_t hickcal : 8; /* [15:8] */ + __IO uint32_t hexten : 1; /* [16] */ + __IO uint32_t hextstbl : 1; /* [17] */ + __IO uint32_t hextbyps : 1; /* [18] */ + __IO uint32_t cfden : 1; /* [19] */ + __IO uint32_t reserved1 : 4; /* [23:20] */ + __IO uint32_t pllen : 1; /* [24] */ + __IO uint32_t pllstbl : 1; /* [25] */ + __IO uint32_t reserved2 : 6; /* [31:26] */ + } ctrl_bit; + }; + + /** + * @brief crm cfg register, offset:0x04 + */ + union + { + __IO uint32_t cfg; + struct + { + __IO uint32_t sclksel : 2; /* [1:0] */ + __IO uint32_t sclksts : 2; /* [3:2] */ + __IO uint32_t ahbdiv : 4; /* [7:4] */ + __IO uint32_t apb1div : 3; /* [10:8] */ + __IO uint32_t apb2div : 3; /* [13:11] */ + __IO uint32_t adcdiv_l : 2; /* [15:14] */ + __IO uint32_t pllrcs : 1; /* [16] */ + __IO uint32_t pllhextdiv : 1; /* [17] */ + __IO uint32_t pllmult_l : 4; /* [21:18] */ + __IO uint32_t usbdiv_l : 2; /* [23:22] */ + __IO uint32_t clkout_sel : 3; /* [26:24] */ + __IO uint32_t usbdiv_h : 1; /* [27] */ + __IO uint32_t adcdiv_h : 1; /* [28] */ + __IO uint32_t pllmult_h : 2; /* [30:29] */ + __IO uint32_t pllrange : 1; /* [31] */ + } cfg_bit; + }; + + /** + * @brief crm clkint register, offset:0x08 + */ + union + { + __IO uint32_t clkint; + struct + { + __IO uint32_t lickstblf : 1; /* [0] */ + __IO uint32_t lextstblf : 1; /* [1] */ + __IO uint32_t hickstblf : 1; /* [2] */ + __IO uint32_t hextstblf : 1; /* [3] */ + __IO uint32_t pllstblf : 1; /* [4] */ + __IO uint32_t reserved1 : 2; /* [6:5] */ + __IO uint32_t cfdf : 1; /* [7] */ + __IO uint32_t lickstblien : 1; /* [8] */ + __IO uint32_t lextstblien : 1; /* [9] */ + __IO uint32_t hickstblien : 1; /* [10] */ + __IO uint32_t hextstblien : 1; /* [11] */ + __IO uint32_t pllstblien : 1; /* [12] */ + __IO uint32_t reserved2 : 3; /* [15:13] */ + __IO uint32_t lickstblfc : 1; /* [16] */ + __IO uint32_t lextstblfc : 1; /* [17] */ + __IO uint32_t hickstblfc : 1; /* [18] */ + __IO uint32_t hextstblfc : 1; /* [19] */ + __IO uint32_t pllstblfc : 1; /* [20] */ + __IO uint32_t reserved3 : 2; /* [22:21] */ + __IO uint32_t cfdfc : 1; /* [23] */ + __IO uint32_t reserved4 : 8; /* [31:24] */ + } clkint_bit; + }; + + /** + * @brief crm apb2rst register, offset:0x0C + */ + union + { + __IO uint32_t apb2rst; + struct + { + __IO uint32_t iomuxrst : 1; /* [0] */ + __IO uint32_t exintrst : 1; /* [1] */ + __IO uint32_t gpioarst : 1; /* [2] */ + __IO uint32_t gpiobrst : 1; /* [3] */ + __IO uint32_t gpiocrst : 1; /* [4] */ + __IO uint32_t gpiodrst : 1; /* [5] */ + __IO uint32_t gpioerst : 1; /* [6] */ + __IO uint32_t reserved1 : 2; /* [8:7] */ + __IO uint32_t adc1rst : 1; /* [9] */ + __IO uint32_t adc2rst : 1; /* [10] */ + __IO uint32_t tmr1rst : 1; /* [11] */ + __IO uint32_t spi1rst : 1; /* [12] */ + __IO uint32_t tmr8rst : 1; /* [13] */ + __IO uint32_t usart1rst : 1; /* [14] */ + __IO uint32_t adc3rst : 1; /* [15] */ + __IO uint32_t reserved2 : 3; /* [18:16] */ + __IO uint32_t tmr9rst : 1; /* [19] */ + __IO uint32_t tmr10rst : 1; /* [20] */ + __IO uint32_t tmr11rst : 1; /* [21] */ + __IO uint32_t accrst : 1; /* [22] */ + __IO uint32_t i2c3rst : 1; /* [23] */ + __IO uint32_t usart6rst : 1; /* [24] */ + __IO uint32_t uart7rst : 1; /* [25] */ + __IO uint32_t uart8rst : 1; /* [26] */ + __IO uint32_t reserved3 : 5; /* [31:27] */ + } apb2rst_bit; + }; + + /** + * @brief crm apb1rst register, offset:0x10 + */ + union + { + __IO uint32_t apb1rst; + struct + { + __IO uint32_t tmr2rst : 1; /* [0] */ + __IO uint32_t tmr3rst : 1; /* [1] */ + __IO uint32_t tmr4rst : 1; /* [2] */ + __IO uint32_t tmr5rst : 1; /* [3] */ + __IO uint32_t tmr6rst : 1; /* [4] */ + __IO uint32_t tmr7rst : 1; /* [5] */ + __IO uint32_t tmr12rst : 1; /* [6] */ + __IO uint32_t tmr13rst : 1; /* [7] */ + __IO uint32_t tmr14rst : 1; /* [8] */ + __IO uint32_t reserved1 : 2; /* [10:9] */ + __IO uint32_t wwdtrst : 1; /* [11] */ + __IO uint32_t reserved2 : 2; /* [13:12] */ + __IO uint32_t spi2rst : 1; /* [14] */ + __IO uint32_t spi3rst : 1; /* [15] */ + __IO uint32_t spi4rst : 1; /* [16] */ + __IO uint32_t usart2rst : 1; /* [17] */ + __IO uint32_t usart3rst : 1; /* [18] */ + __IO uint32_t uart4rst : 1; /* [19] */ + __IO uint32_t uart5rst : 1; /* [20] */ + __IO uint32_t i2c1rst : 1; /* [21] */ + __IO uint32_t i2c2rst : 1; /* [22] */ + __IO uint32_t usbrst : 1; /* [23] */ + __IO uint32_t reserved3 : 1; /* [24] */ + __IO uint32_t can1rst : 1; /* [25] */ + __IO uint32_t can2rst : 1; /* [26] */ + __IO uint32_t bprrst : 1; /* [27] */ + __IO uint32_t pwcrst : 1; /* [28] */ + __IO uint32_t dacrst : 1; /* [29] */ + __IO uint32_t reserved4 : 2; /* [31:30] */ + } apb1rst_bit; + }; + + /** + * @brief crm ahben register, offset:0x14 + */ + union + { + __IO uint32_t ahben; +#if defined (AT32F403Axx) + struct + { + __IO uint32_t dma1en : 1; /* [0] */ + __IO uint32_t dma2en : 1; /* [1] */ + __IO uint32_t sramen : 1; /* [2] */ + __IO uint32_t reserved1 : 1; /* [3] */ + __IO uint32_t flashen : 1; /* [4] */ + __IO uint32_t reserved2 : 1; /* [5] */ + __IO uint32_t crcen : 1; /* [6] */ + __IO uint32_t reserved3 : 1; /* [7] */ + __IO uint32_t xmcen : 1; /* [8] */ + __IO uint32_t reserved4 : 1; /* [9] */ + __IO uint32_t sdio1en : 1; /* [10] */ + __IO uint32_t sdio2en : 1; /* [11] */ + __IO uint32_t reserved5 : 20;/* [31:12] */ + } ahben_bit; +#endif +#if defined (AT32F407xx) + struct + { + __IO uint32_t dma1en : 1; /* [0] */ + __IO uint32_t dma2en : 1; /* [1] */ + __IO uint32_t sramen : 1; /* [2] */ + __IO uint32_t reserved1 : 1; /* [3] */ + __IO uint32_t flashen : 1; /* [4] */ + __IO uint32_t reserved2 : 1; /* [5] */ + __IO uint32_t crcen : 1; /* [6] */ + __IO uint32_t reserved3 : 1; /* [7] */ + __IO uint32_t xmcen : 1; /* [8] */ + __IO uint32_t reserved4 : 1; /* [9] */ + __IO uint32_t sdio1en : 1; /* [10] */ + __IO uint32_t sdio2en : 1; /* [11] */ + __IO uint32_t reserved5 : 2; /* [13:12] */ + __IO uint32_t emacen : 1; /* [14] */ + __IO uint32_t emactxen : 1; /* [15] */ + __IO uint32_t emacrxen : 1; /* [16] */ + __IO uint32_t reserved6 : 11;/* [27:17] */ + __IO uint32_t emacptpen : 1; /* [28] */ + __IO uint32_t reserved7 : 3; /* [31:29] */ + } ahben_bit; +#endif + }; + + /** + * @brief crm apb2en register, offset:0x18 + */ + union + { + __IO uint32_t apb2en; + struct + { + __IO uint32_t iomuxen : 1; /* [0] */ + __IO uint32_t reserved1 : 1; /* [1] */ + __IO uint32_t gpioaen : 1; /* [2] */ + __IO uint32_t gpioben : 1; /* [3] */ + __IO uint32_t gpiocen : 1; /* [4] */ + __IO uint32_t gpioden : 1; /* [5] */ + __IO uint32_t gpioeen : 1; /* [6] */ + __IO uint32_t reserved2 : 2; /* [8:7] */ + __IO uint32_t adc1en : 1; /* [9] */ + __IO uint32_t adc2en : 1; /* [10] */ + __IO uint32_t tmr1en : 1; /* [11] */ + __IO uint32_t spi1en : 1; /* [12] */ + __IO uint32_t tmr8en : 1; /* [13] */ + __IO uint32_t usart1en : 1; /* [14] */ + __IO uint32_t adc3en : 1; /* [15] */ + __IO uint32_t reserved3 : 3; /* [18:16] */ + __IO uint32_t tmr9en : 1; /* [19] */ + __IO uint32_t tmr10en : 1; /* [20] */ + __IO uint32_t tmr11en : 1; /* [21] */ + __IO uint32_t accen : 1; /* [22] */ + __IO uint32_t i2c3en : 1; /* [23] */ + __IO uint32_t usart6en : 1; /* [24] */ + __IO uint32_t uart7en : 1; /* [25] */ + __IO uint32_t uart8en : 1; /* [26] */ + __IO uint32_t reserved4 : 5; /* [31:27] */ + } apb2en_bit; + }; + + /** + * @brief crm apb1en register, offset:0x1C + */ + union + { + __IO uint32_t apb1en; + struct + { + __IO uint32_t tmr2en : 1; /* [0] */ + __IO uint32_t tmr3en : 1; /* [1] */ + __IO uint32_t tmr4en : 1; /* [2] */ + __IO uint32_t tmr5en : 1; /* [3] */ + __IO uint32_t tmr6en : 1; /* [4] */ + __IO uint32_t tmr7en : 1; /* [5] */ + __IO uint32_t tmr12en : 1; /* [6] */ + __IO uint32_t tmr13en : 1; /* [7] */ + __IO uint32_t tmr14en : 1; /* [8] */ + __IO uint32_t reserved1 : 2; /* [10:9] */ + __IO uint32_t wwdten : 1; /* [11] */ + __IO uint32_t reserved2 : 2; /* [13:12] */ + __IO uint32_t spi2en : 1; /* [14] */ + __IO uint32_t spi3en : 1; /* [15] */ + __IO uint32_t spi4en : 1; /* [16] */ + __IO uint32_t usart2en : 1; /* [17] */ + __IO uint32_t usart3en : 1; /* [18] */ + __IO uint32_t uart4en : 1; /* [19] */ + __IO uint32_t uart5en : 1; /* [20] */ + __IO uint32_t i2c1en : 1; /* [21] */ + __IO uint32_t i2c2en : 1; /* [22] */ + __IO uint32_t usben : 1; /* [23] */ + __IO uint32_t reserved3 : 1; /* [24] */ + __IO uint32_t can1en : 1; /* [25] */ + __IO uint32_t can2en : 1; /* [26] */ + __IO uint32_t bpren : 1; /* [27] */ + __IO uint32_t pwcen : 1; /* [28] */ + __IO uint32_t dacen : 1; /* [29] */ + __IO uint32_t reserved4 : 2; /* [31:30] */ + } apb1en_bit; + }; + + /** + * @brief crm bpdc register, offset:0x20 + */ + union + { + __IO uint32_t bpdc; + struct + { + __IO uint32_t lexten : 1; /* [0] */ + __IO uint32_t lextstbl : 1; /* [1] */ + __IO uint32_t lextbyps : 1; /* [2] */ + __IO uint32_t reserved1 : 5; /* [7:3] */ + __IO uint32_t rtcsel : 2; /* [9:8] */ + __IO uint32_t reserved2 : 5; /* [14:10] */ + __IO uint32_t rtcen : 1; /* [15] */ + __IO uint32_t bpdrst : 1; /* [16] */ + __IO uint32_t reserved3 : 15;/* [31:17] */ + } bpdc_bit; + }; + + /** + * @brief crm ctrlsts register, offset:0x24 + */ + union + { + __IO uint32_t ctrlsts; + struct + { + __IO uint32_t licken : 1; /* [0] */ + __IO uint32_t lickstbl : 1; /* [1] */ + __IO uint32_t reserved1 : 22;/* [23:2] */ + __IO uint32_t rstfc : 1; /* [24] */ + __IO uint32_t reserved2 : 1; /* [25] */ + __IO uint32_t nrstf : 1; /* [26] */ + __IO uint32_t porrstf : 1; /* [27] */ + __IO uint32_t swrstf : 1; /* [28] */ + __IO uint32_t wdtrstf : 1; /* [29] */ + __IO uint32_t wwdtrstf : 1; /* [30] */ + __IO uint32_t lprstf : 1; /* [31] */ + } ctrlsts_bit; + }; + + /** + * @brief crm ahbrst register, offset:0x28 + */ + union + { + __IO uint32_t ahbrst; +#if defined (AT32F407xx) + struct + { + __IO uint32_t reserved1 : 14;/* [13:0] */ + __IO uint32_t emacrst : 1; /* [14] */ + __IO uint32_t reserved2 : 17;/* [31:15] */ + } ahbrst_bit; +#endif + }; + + /** + * @brief crm reserved1 register, offset:0x2C + */ + __IO uint32_t reserved1; + + /** + * @brief crm misc1 register, offset:0x30 + */ + union + { + __IO uint32_t misc1; + struct + { + __IO uint32_t hickcal_key : 8; /* [7:0] */ + __IO uint32_t reserved1 : 8; /* [15:8] */ + __IO uint32_t clkout_sel : 1; /* [16] */ + __IO uint32_t reserved2 : 7; /* [23:17] */ + __IO uint32_t usbbufs : 1; /* [24] */ + __IO uint32_t hickdiv : 1; /* [25] */ + __IO uint32_t reserved3 : 2; /* [27:26] */ + __IO uint32_t clkoutdiv : 4; /* [31:28] */ + } misc1_bit; + }; + + /** + * @brief crm reserved2 register, offset:0x4C~0x34 + */ + __IO uint32_t reserved2[7]; + + /** + * @brief crm misc2 register, offset:0x50 + */ + union + { + __IO uint32_t misc2; + struct + { + __IO uint32_t reserved1 : 16;/* [15:0] */ + __IO uint32_t clk_to_tmr : 1; /* [16] */ + __IO uint32_t reserved2 : 15;/* [31:17] */ + } misc2_bit; + }; + + /** + * @brief crm misc3 register, offset:0x54 + */ + union + { + __IO uint32_t misc3; + struct + { + __IO uint32_t reserved1 : 4; /* [3:0] */ + __IO uint32_t auto_step_en : 2; /* [5:4] */ + __IO uint32_t reserved2 : 2; /* [7:6] */ + __IO uint32_t hick_to_usb : 1; /* [8] */ + __IO uint32_t hick_to_sclk : 1; /* [9] */ + __IO uint32_t reserved3 : 2; /* [11:10] */ + __IO uint32_t hextdiv : 2; /* [13:12] */ + __IO uint32_t reserved4 : 1; /* [14] */ + __IO uint32_t emac_pps_sel : 1; /* [15] */ + __IO uint32_t reserved5 : 16;/* [31:16] */ + } misc3_bit; + }; + + /** + * @brief crm reserved3 register, offset:0x58 + */ + __IO uint32_t reserved3; + + /** + * @brief crm intmap register, offset:0x5C + */ + union + { + __IO uint32_t intmap; + struct + { + __IO uint32_t usbintmap : 1; /* [0] */ + __IO uint32_t reserved1 : 31;/* [31:1] */ + } intmap_bit; + }; + +} crm_type; + +/** + * @} + */ + +#define CRM ((crm_type *) CRM_BASE) + +/** @defgroup CRM_exported_functions + * @{ + */ + +void crm_reset(void); +void crm_lext_bypass(confirm_state new_state); +void crm_hext_bypass(confirm_state new_state); +flag_status crm_flag_get(uint32_t flag); +error_status crm_hext_stable_wait(void); +void crm_hick_clock_trimming_set(uint8_t trim_value); +void crm_hick_clock_calibration_set(uint8_t cali_value); +void crm_periph_clock_enable(crm_periph_clock_type value, confirm_state new_state); +void crm_periph_reset(crm_periph_reset_type value, confirm_state new_state); +void crm_periph_sleep_mode_clock_enable(crm_periph_clock_sleepmd_type value, confirm_state new_state); +void crm_clock_source_enable(crm_clock_source_type source, confirm_state new_state); +void crm_flag_clear(uint32_t flag); +void crm_rtc_clock_select(crm_rtc_clock_type value); +void crm_rtc_clock_enable(confirm_state new_state); +void crm_ahb_div_set(crm_ahb_div_type value); +void crm_apb1_div_set(crm_apb1_div_type value); +void crm_apb2_div_set(crm_apb2_div_type value); +void crm_adc_clock_div_set(crm_adc_div_type div_value); +void crm_usb_clock_div_set(crm_usb_div_type div_value); +void crm_clock_failure_detection_enable(confirm_state new_state); +void crm_battery_powered_domain_reset(confirm_state new_state); +void crm_pll_config(crm_pll_clock_source_type clock_source, crm_pll_mult_type mult_value, crm_pll_output_range_type pll_range); +void crm_sysclk_switch(crm_sclk_type value); +crm_sclk_type crm_sysclk_switch_status_get(void); +void crm_clocks_freq_get(crm_clocks_freq_type *clocks_struct); +void crm_clock_out_set(crm_clkout_select_type clkout); +void crm_interrupt_enable(uint32_t crm_int, confirm_state new_state); +void crm_auto_step_mode_enable(confirm_state new_state); +void crm_usb_interrupt_remapping_set(crm_usb_int_map_type int_remap); +void crm_hick_divider_select(crm_hick_div_6_type value); +void crm_hick_sclk_frequency_select(crm_hick_sclk_frequency_type value); +void crm_usb_clock_source_select(crm_usb_clock_source_type value); +void crm_clkout_to_tmr10_enable(confirm_state new_state); +void crm_hext_clock_div_set(crm_hext_div_type value); +void crm_clkout_div_set(crm_clkout_div_type clkout_div); +#if defined (AT32F407xx) +void crm_emac_output_pulse_set(crm_emac_output_pulse_type width); +#endif + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_dac.h b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_dac.h new file mode 100644 index 0000000..6b80067 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_dac.h @@ -0,0 +1,374 @@ +/** + ************************************************************************** + * @file at32f403a_407_dac.h + * @version v2.0.9 + * @date 2022-04-25 + * @brief at32f403a_407 dac header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_DAC_H +#define __AT32F403A_407_DAC_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f403a_407.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @addtogroup DAC + * @{ + */ + +#define DAC1_D1DMAUDRF ((uint32_t)(0x00002000)) +#define DAC2_D2DMAUDRF ((uint32_t)(0x20000000)) + +/** @defgroup DAC_exported_types + * @{ + */ + +/** + * @brief dac select type + */ +typedef enum +{ + DAC1_SELECT = 0x01, /*!< dac1 select */ + DAC2_SELECT = 0x02 /*!< dac2 select */ +} dac_select_type; + +/** + * @brief dac trigger type + */ +typedef enum +{ + DAC_TMR6_TRGOUT_EVENT = 0x00, /*!< dac trigger selection:timer6 trgout event */ + DAC_TMR8_TRGOUT_EVENT = 0x01, /*!< dac trigger selection:timer8 trgout event */ + DAC_TMR7_TRGOUT_EVENT = 0x02, /*!< dac trigger selection:timer7 trgout event */ + DAC_TMR5_TRGOUT_EVENT = 0x03, /*!< dac trigger selection:timer5 trgout event */ + DAC_TMR2_TRGOUT_EVENT = 0x04, /*!< dac trigger selection:timer2 trgout event */ + DAC_TMR4_TRGOUT_EVENT = 0x05, /*!< dac trigger selection:timer4 trgout event */ + DAC_EXTERNAL_INTERRUPT_LINE_9 = 0x06, /*!< dac trigger selection:external line9 */ + DAC_SOFTWARE_TRIGGER = 0x07 /*!< dac trigger selection:software trigger */ +} dac_trigger_type; + +/** + * @brief dac wave type + */ +typedef enum +{ + DAC_WAVE_GENERATE_NONE = 0x00, /*!< dac wave generation disabled */ + DAC_WAVE_GENERATE_NOISE = 0x01, /*!< dac noise wave generation enabled */ + DAC_WAVE_GENERATE_TRIANGLE = 0x02 /*!< dac triangle wave generation enabled */ +} dac_wave_type; + +/** + * @brief dac mask amplitude type + */ +typedef enum +{ + DAC_LSFR_BIT0_AMPLITUDE_1 = 0x00, /*!< unmask bit0/ triangle amplitude equal to 1 */ + DAC_LSFR_BIT10_AMPLITUDE_3 = 0x01, /*!< unmask bit[1:0]/ triangle amplitude equal to 3 */ + DAC_LSFR_BIT20_AMPLITUDE_7 = 0x02, /*!< unmask bit[2:0]/ triangle amplitude equal to 7 */ + DAC_LSFR_BIT30_AMPLITUDE_15 = 0x03, /*!< unmask bit[3:0]/ triangle amplitude equal to 15 */ + DAC_LSFR_BIT40_AMPLITUDE_31 = 0x04, /*!< unmask bit[4:0]/ triangle amplitude equal to 31 */ + DAC_LSFR_BIT50_AMPLITUDE_63 = 0x05, /*!< unmask bit[5:0]/ triangle amplitude equal to 63 */ + DAC_LSFR_BIT60_AMPLITUDE_127 = 0x06, /*!< unmask bit[6:0]/ triangle amplitude equal to 127 */ + DAC_LSFR_BIT70_AMPLITUDE_255 = 0x07, /*!< unmask bit[7:0]/ triangle amplitude equal to 255 */ + DAC_LSFR_BIT80_AMPLITUDE_511 = 0x08, /*!< unmask bit[8:0]/ triangle amplitude equal to 511 */ + DAC_LSFR_BIT90_AMPLITUDE_1023 = 0x09, /*!< unmask bit[9:0]/ triangle amplitude equal to 1023 */ + DAC_LSFR_BITA0_AMPLITUDE_2047 = 0x0A, /*!< unmask bit[10:0]/ triangle amplitude equal to 2047 */ + DAC_LSFR_BITB0_AMPLITUDE_4095 = 0x0B /*!< unmask bit[11:0]/ triangle amplitude equal to 4095 */ +} dac_mask_amplitude_type; + +/** + * @brief dac1 aligned data type + */ +typedef enum +{ + DAC1_12BIT_RIGHT = 0x40007408, /*!< dac1 12-bit data right-aligned */ + DAC1_12BIT_LEFT = 0x4000740C, /*!< dac1 12-bit data left-aligned */ + DAC1_8BIT_RIGHT = 0x40007410 /*!< dac1 8-bit data right-aligned */ +} dac1_aligned_data_type; + +/** + * @brief dac2 aligned data type + */ +typedef enum +{ + DAC2_12BIT_RIGHT = 0x40007414, /*!< dac2 12-bit data right-aligned */ + DAC2_12BIT_LEFT = 0x40007418, /*!< dac2 12-bit data left-aligned */ + DAC2_8BIT_RIGHT = 0x4000741C /*!< dac2 8-bit data right-aligned */ +} dac2_aligned_data_type; + +/** + * @brief dac dual data type + */ +typedef enum +{ + DAC_DUAL_12BIT_RIGHT = 0x40007420, /*!ept[ept_num]) & USB_TX_MASK; \ + if((new_sts & USB_TXDTS0) != 0) \ + epsts ^= USB_TXDTS0; \ + if((new_sts & USB_TXDTS1) != 0) \ + epsts ^= USB_TXDTS1; \ + USB->ept[ept_num] = epsts | USB_RXTC | USB_TXTC; \ +} + +/** + * @brief set usb endpoint rx status + * @param ept_num: endpoint number + * @param new_sts: the new rx status of this endpoint number + * @retval none + */ +#define USB_SET_RXSTS(ept_num, new_sts) { \ + register uint16_t epsts = (USB->ept[ept_num]) & USB_RX_MASK; \ + if((new_sts & USB_RXDTS0) != 0) \ + epsts ^= USB_RXDTS0; \ + if((new_sts & USB_RXDTS1) != 0) \ + epsts ^= USB_RXDTS1; \ + USB->ept[ept_num] = epsts | USB_RXTC | USB_TXTC; \ +} + +/** + * @brief get usb endpoint tx/rx length address + * @param eptn: endpoint number + * @retval the length address of tx/rx + */ +#define GET_TX_LEN_ADDR(eptn) (uint32_t *)((USB->buftbl + eptn * 8 + 2) * 2 + g_usb_packet_address) +#define GET_RX_LEN_ADDR(eptn) (uint32_t *)((USB->buftbl + eptn * 8 + 6) * 2 + g_usb_packet_address) + +/** + * @brief get usb endpoint tx/rx data length + * @param eptn: endpoint number + * @retval the length of tx/rx + */ +#define USB_GET_TX_LEN(eptn) ((uint16_t)(*GET_TX_LEN_ADDR(eptn)) & 0x3ff) +#define USB_GET_RX_LEN(eptn) ((uint16_t)(*GET_RX_LEN_ADDR(eptn)) & 0x3ff) + +/** + * @brief double buffer mode get endpoint buf0/buf1 data length + * @param eptn: endpoint number + * @retval the length of buf0/buf1 + */ +#define USB_DBUF0_GET_LEN(eptn) USB_GET_TX_LEN(eptn) +#define USB_DBUF1_GET_LEN(eptn) USB_GET_RX_LEN(eptn) + +/** + * @brief set usb length of rx buffer + * @param reg: usb rx length register + * @param len: rx max length + * @param blks: number of blocks + */ +#define BLK32(reg, len, blks) { \ + blks = (len) >> 5; \ + if(((len) & 0x1F) == 0) \ + blks --; \ + *reg = ((uint16_t)((blks) << 10) | 0x8000); \ +} + +#define BLK2(reg, len, blks) { \ + blks = (len) >> 1; \ + if(((len) & 0x1) == 0) \ + blks ++; \ + *reg = (uint16_t)((blks) << 10); \ +} + +#define USB_SET_RXLEN_REG(reg, len) { \ + uint16_t blks; \ + if(len > 62) \ + { \ + BLK32(reg, len, blks); \ + } \ + else \ + { \ + BLK2(reg, len, blks); \ + } \ +} + +/** + * @brief set endpoint tx/rx transfer length + * @param eptn: endpoint number + * @param len: transfer length + * @retval none + */ +#define USB_SET_TXLEN(eptn, len) (*(GET_TX_LEN_ADDR(eptn)) = (len)) +#define USB_SET_RXLEN(eptn, len) { \ + uint32_t *rx_reg = GET_RX_LEN_ADDR(eptn); \ + USB_SET_RXLEN_REG(rx_reg, (len)); \ +} + +/** + * @brief double buffer mode set endpoint rx buf0 length + * @param eptn: endpoint number + * @param len: transfer length + * @retval none + */ +#define USB_OUT_EPT_DOUBLE_BUF0(eptn, len) { \ + uint32_t *rx_reg = GET_TX_LEN_ADDR(eptn); \ + USB_SET_RXLEN_REG(rx_reg, (len)); \ +} + +/** + * @brief double buffer mode set endpoint buf0 length + * @param eptn: endpoint number + * @param len: transfer length + * @param dir: transfer direction(in/out) + * @retval none + */ +#define USB_SET_EPT_DOUBLE_BUF0_LEN(eptn, len, dir) { \ + if(dir == DATA_TRANS_OUT) \ + { \ + USB_OUT_EPT_DOUBLE_BUF0(eptn, len); \ + } \ + else \ + { \ + *(GET_TX_LEN_ADDR(eptn)) = (len); \ + } \ +} + +/** + * @brief double buffer mode set endpoint buf1 length + * @param eptn: endpoint number + * @param len: transfer length + * @param dir: transfer direction(in/out) + * @retval none + */ +#define USB_SET_EPT_DOUBLE_BUF1_LEN(eptn, len, dir) { \ + if(dir == DATA_TRANS_OUT) \ + { \ + USB_SET_RXLEN(eptn, len); \ + } \ + else \ + { \ + *(GET_RX_LEN_ADDR(eptn)) = (len); \ + } \ +} + +/** + * @brief set usb endpoint tx/rx fifo address + * @param eptn: endpoint number + * @param address: offset of the fifo address + * @retval none + */ +#define USB_SET_TX_ADDRESS(eptn, address) (*(uint32_t *)((USB->buftbl + eptn * 8) * 2 + g_usb_packet_address) = address) +#define USB_SET_RX_ADDRESS(eptn, address) (*(uint32_t *)((USB->buftbl + eptn * 8 + 4) * 2 + g_usb_packet_address) = address) + +/** + * @brief set double buffer mode usb endpoint buf0/buf1 fifo address + * @param eptn: endpoint number + * @param address: offset of the fifo address + * @retval none + */ +#define USB_SET_DOUBLE_BUFF0_ADDRESS(eptn, address) (USB_SET_TX_ADDRESS(eptn, address)) +#define USB_SET_DOUBLE_BUFF1_ADDRESS(eptn, address) (USB_SET_RX_ADDRESS(eptn, address)) + +/** + * @brief set usb tx/rx toggle + * @param eptn: endpoint number + * @retval none + */ +#define USB_TOGGLE_TXDTS(eptn) (USB->ept[eptn] = ((USB->ept[eptn] & USB_EPT_BIT_MASK) | USB_TXDTS | USB_RXTC | USB_TXTC)) +#define USB_TOGGLE_RXDTS(eptn) (USB->ept[eptn] = ((USB->ept[eptn] & USB_EPT_BIT_MASK) | USB_RXDTS | USB_RXTC | USB_TXTC)) + +/** + * @brief clear usb tx/rx toggle + * @param eptn: endpoint number + * @retval none + */ +#define USB_CLEAR_TXDTS(eptn) { \ + if(USB->ept_bit[eptn].txdts != 0) \ + USB_TOGGLE_TXDTS(eptn); \ +} +#define USB_CLEAR_RXDTS(eptn) { \ + if(USB->ept_bit[eptn].rxdts != 0) \ + USB_TOGGLE_RXDTS(eptn); \ +} + +/** + * @brief set usb endpoint type + */ + +/** + * @brief set usb transfer type + * @param eptn: endpoint number + * @param type: transfer type + * @retval none + */ +#define USB_SET_TRANS_TYPE(eptn, type) (USB->ept[eptn] = (USB->ept[eptn] & USB_EPT_BIT_MASK & (~USB_TRANS_TYPE)) | type) + +/** + * @brief set/clear usb extend function + * @param eptn: endpoint number + * @retval none + */ +#define USB_SET_EXF(eptn) (USB->ept[eptn] = USB_TXTC | USB_RXTC | ((USB->ept[eptn] | USB_EXF) & USB_EPT_BIT_MASK)) +#define USB_CLEAR_EXF(eptn) (USB->ept[eptn] = USB_TXTC | USB_RXTC | (USB->ept[eptn] & ((~USB_EXF) & USB_EPT_BIT_MASK))) + +/** + * @brief set usb device address + * @param eptn: endpoint number + * @param address: device address + * @retval none + */ +#define USB_SET_EPT_ADDRESS(eptn, address) (USB->ept[eptn] = ((USB->ept[eptn] & USB_EPT_BIT_MASK & (~USB_EPTADDR)) | address)) + +/** + * @brief free buffer used by application + * @param eptn: endpoint number + * @param inout: transfer direction + * @retval none + */ +#define USB_FREE_DB_USER_BUFFER(eptn, inout) { \ + if(inout == DATA_TRANS_IN) \ + { \ + USB_TOGGLE_RXDTS(eptn); \ + } \ + else \ + { \ + USB_TOGGLE_TXDTS(eptn); \ + } \ +} + +/** + * @brief clear tx/rx transfer completed flag + * @param eptn: endpoint number + * @retval none + */ +#define USB_CLEAR_TXTC(eptn) (USB->ept[eptn] &= 0xFF7F & USB_EPT_BIT_MASK) +#define USB_CLEAR_RXTC(eptn) (USB->ept[eptn] &= 0x7FFF & USB_EPT_BIT_MASK) + +/** + * @brief set/clear endpoint double buffer mode + * @param eptn: endpoint number + * @retval none + */ +#define USB_SET_EPT_DOUBLE_BUFFER(eptn) USB_SET_EXF(eptn) +#define USB_CLEAR_EPT_DOUBLE_BUFFER(eptn) USB_CLEAR_EXF(eptn) + +/** + * @} + */ + +/** @defgroup USB_exported_types + * @{ + */ + +/** + * @brief usb endpoint infomation structure definition + */ +typedef struct +{ + uint8_t eptn; /*!< endpoint register number (0~7) */ + uint8_t ept_address; /*!< endpoint address */ + uint8_t inout; /*!< endpoint dir DATA_TRANS_IN or DATA_TRANS_OUT */ + uint8_t trans_type; /*!< endpoint type: + EPT_CONTROL_TYPE, EPT_BULK_TYPE, EPT_INT_TYPE, EPT_ISO_TYPE*/ + uint16_t tx_addr; /*!< endpoint tx buffer offset address */ + uint16_t rx_addr; /*!< endpoint rx buffer offset address */ + uint16_t maxpacket; /*!< endpoint max packet*/ + uint8_t is_double_buffer; /*!< endpoint double buffer flag */ + uint8_t stall; /*!< endpoint is stall state */ + uint16_t status; /*!< endpoint status */ + + /* transmission buffer and count */ + uint16_t total_len; /*!< endpoint transmission total length */ + uint16_t trans_len; /*!< endpoint transmission length*/ + uint8_t *trans_buf; /*!< endpoint transmission buffer */ + + uint16_t last_len; /*!< last transfer length */ + uint16_t rem0_len; /*!< rem transfer length */ + uint16_t ept0_slen; /*!< endpoint 0 transfer sum length */ +}usb_ept_info; + +/** + * @brief type define usb register all + */ +typedef struct +{ + /** + * @brief usb endpoint register, offset:0x00 + */ + union + { + __IO uint32_t ept[8]; + struct + { + __IO uint32_t eptaddr : 4; /* [3:0] */ + __IO uint32_t txsts : 2; /* [5:4] */ + __IO uint32_t txdts : 1; /* [6] */ + __IO uint32_t txtc : 1; /* [7] */ + __IO uint32_t exf : 1; /* [8] */ + __IO uint32_t trans_type : 2; /* [10:9] */ + __IO uint32_t setuptc : 1; /* [11] */ + __IO uint32_t rxsts : 2; /* [13:12] */ + __IO uint32_t rxdts : 1; /* [14] */ + __IO uint32_t rxtc : 1; /* [15] */ + __IO uint32_t reserved1 : 16; /* [31:16] */ + } ept_bit[8]; + }; + + __IO uint32_t reserved1[8]; + + /** + * @brief usb control register, offset:0x40 + */ + union + { + __IO uint32_t ctrl; + struct + { + __IO uint32_t csrst : 1; /* [0] */ + __IO uint32_t disusb : 1; /* [1] */ + __IO uint32_t lpm : 1; /* [2] */ + __IO uint32_t ssp : 1; /* [3] */ + __IO uint32_t gresume : 1; /* [4] */ + __IO uint32_t reserved1 : 3; /* [7:5] */ + __IO uint32_t lsofien : 1; /* [8] */ + __IO uint32_t sofien : 1; /* [9] */ + __IO uint32_t rstien : 1; /* [10] */ + __IO uint32_t spien : 1; /* [11] */ + __IO uint32_t wkien : 1; /* [12] */ + __IO uint32_t beien : 1; /* [13] */ + __IO uint32_t ucforien : 1; /* [14] */ + __IO uint32_t tcien : 1; /* [15] */ + __IO uint32_t reserved2 : 16; /* [31:16] */ + } ctrl_bit; + }; + + /** + * @brief usb interrupt status register, offset:0x44 + */ + union + { + __IO uint32_t intsts; + struct + { + __IO uint32_t ept_num : 4; /* [3:0] */ + __IO uint32_t inout : 1; /* [4] */ + __IO uint32_t reserved1 : 3; /* [7:5] */ + __IO uint32_t lsof : 1; /* [8] */ + __IO uint32_t sof : 1; /* [9] */ + __IO uint32_t rst : 1; /* [10] */ + __IO uint32_t sp : 1; /* [11] */ + __IO uint32_t wk : 1; /* [12] */ + __IO uint32_t be : 1; /* [13] */ + __IO uint32_t ucfor : 1; /* [14] */ + __IO uint32_t tc : 1; /* [15] */ + __IO uint32_t reserved2 : 16; /* [31:16] */ + } intsts_bit; + }; + + /** + * @brief usb frame number register, offset:0x48 + */ + union + { + __IO uint32_t sofrnum; + struct + { + __IO uint32_t sofnum : 11; /* [10:0] */ + __IO uint32_t lsofnum : 2; /* [12:11] */ + __IO uint32_t clck : 1; /* [13] */ + __IO uint32_t dmsts : 1; /* [14] */ + __IO uint32_t dpsts : 1; /* [15] */ + __IO uint32_t reserved1 : 16; /* [31:16] */ + } sofrnum_bit; + }; + + /** + * @brief usb device address register, offset:0x4c + */ + union + { + __IO uint32_t devaddr; + struct + { + __IO uint32_t addr : 7; /* [6:0] */ + __IO uint32_t cen : 1; /* [7] */ + __IO uint32_t reserved1 : 24; /* [31:8] */ + } devaddr_bit; + }; + + /** + * @brief usb buffer address register, offset:0x50 + */ + union + { + __IO uint32_t buftbl; + struct + { + __IO uint32_t reserved1 : 3; /* [2:0] */ + __IO uint32_t btaddr : 13; /* [15:3] */ + __IO uint32_t reserved2 : 16; /* [31:16] */ + } buftbl_bit; + }; + __IO uint32_t reserved2[3]; + /** + * @brief usb cfg control register, offset:0x60 + */ + union + { + __IO uint32_t cfg; + struct + { + __IO uint32_t sofouten : 1; /* [0] */ + __IO uint32_t puo : 1; /* [1] */ + __IO uint32_t reserved1 : 30; /* [31:2] */ + } cfg_bit; + }; + +} usbd_type; + +/** + * @} + */ + +#define USB ((usbd_type *) USBFS_BASE) + +typedef usbd_type usb_reg_type; +extern uint32_t g_usb_packet_address; + +/** @defgroup USB_exported_functions + * @{ + */ + +void usb_dev_init(usbd_type *usbx); +void usb_connect(usbd_type *usbx); +void usb_disconnect(usbd_type *usbx); +void usb_usbbufs_enable(usbd_type *usbx, confirm_state state); +void usb_ept_open(usbd_type *usbx, usb_ept_info *ept_info); +void usb_ept_close(usbd_type *usbx, usb_ept_info *ept_info); +void usb_write_packet(uint8_t *pusr_buf, uint16_t offset_addr, uint16_t nbytes); +void usb_read_packet(uint8_t *pusr_buf, uint16_t offset_addr, uint16_t nbytes); +void usb_interrupt_enable(usbd_type *usbx, uint16_t interrupt, confirm_state new_state); +void usb_set_address(usbd_type *usbx, uint8_t address); +void usb_ept_stall(usbd_type *usbx, usb_ept_info *ept_info); +void usb_enter_suspend(usbd_type *usbx); +void usb_exit_suspend(usbd_type *usbx); +void usb_remote_wkup_set(usbd_type *usbx); +void usb_remote_wkup_clear(usbd_type *usbx); +uint16_t usb_buffer_malloc(uint16_t maxpacket); +void usb_buffer_free(void); +flag_status usb_flag_get(usbd_type *usbx, uint16_t flag); +void usb_flag_clear(usbd_type *usbx, uint16_t flag); + + +#ifdef __cplusplus +} +#endif + +#endif +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_wdt.h b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_wdt.h new file mode 100644 index 0000000..f870840 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_wdt.h @@ -0,0 +1,183 @@ +/** + ************************************************************************** + * @file at32f403a_407_wdt.h + * @version v2.0.9 + * @date 2022-04-25 + * @brief at32f403a_407 wdt header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_WDT_H +#define __AT32F403A_407_WDT_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f403a_407.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @addtogroup WDT + * @{ + */ + + +/** @defgroup WDT_flags_definition + * @brief wdt flag + * @{ + */ + +#define WDT_DIVF_UPDATE_FLAG ((uint16_t)0x0001) /*!< wdt division value update complete flag */ +#define WDT_RLDF_UPDATE_FLAG ((uint16_t)0x0002) /*!< wdt reload value update complete flag */ + +/** + * @} + */ + +/** @defgroup WDT_exported_types + * @{ + */ + +/** + * @brief wdt division value type + */ +typedef enum +{ + WDT_CLK_DIV_4 = 0x00, /*!< wdt clock divider value is 4 */ + WDT_CLK_DIV_8 = 0x01, /*!< wdt clock divider value is 8 */ + WDT_CLK_DIV_16 = 0x02, /*!< wdt clock divider value is 16 */ + WDT_CLK_DIV_32 = 0x03, /*!< wdt clock divider value is 32 */ + WDT_CLK_DIV_64 = 0x04, /*!< wdt clock divider value is 64 */ + WDT_CLK_DIV_128 = 0x05, /*!< wdt clock divider value is 128 */ + WDT_CLK_DIV_256 = 0x06 /*!< wdt clock divider value is 256 */ +} wdt_division_type; + +/** + * @brief wdt cmd value type + */ +typedef enum +{ + WDT_CMD_LOCK = 0x0000, /*!< disable write protection command */ + WDT_CMD_UNLOCK = 0x5555, /*!< enable write protection command */ + WDT_CMD_ENABLE = 0xCCCC, /*!< enable wdt command */ + WDT_CMD_RELOAD = 0xAAAA /*!< reload command */ +} wdt_cmd_value_type; + +/** + * @brief type define wdt register all + */ +typedef struct +{ + + /** + * @brief wdt cmd register, offset:0x00 + */ + union + { + __IO uint32_t cmd; + struct + { + __IO uint32_t cmd : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } cmd_bit; + }; + + /** + * @brief wdt div register, offset:0x04 + */ + union + { + __IO uint32_t div; + struct + { + __IO uint32_t div : 3; /* [2:0] */ + __IO uint32_t reserved1 : 29;/* [31:3] */ + } div_bit; + }; + + /** + * @brief wdt rld register, offset:0x08 + */ + union + { + __IO uint32_t rld; + struct + { + __IO uint32_t rld : 12;/* [11:0] */ + __IO uint32_t reserved1 : 20;/* [31:12] */ + } rld_bit; + }; + + /** + * @brief wdt sts register, offset:0x0C + */ + union + { + __IO uint32_t sts; + struct + { + __IO uint32_t divf : 1; /* [0] */ + __IO uint32_t rldf : 1; /* [1] */ + __IO uint32_t reserved1 : 30;/* [31:2] */ + } sts_bit; + }; + +} wdt_type; + +/** + * @} + */ + +#define WDT ((wdt_type *) WDT_BASE) + +/** @defgroup WDT_exported_functions + * @{ + */ + +void wdt_enable(void); +void wdt_counter_reload(void); +void wdt_reload_value_set(uint16_t reload_value); +void wdt_divider_set(wdt_division_type division); +void wdt_register_write_enable( confirm_state new_state); +flag_status wdt_flag_get(uint16_t wdt_flag); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_wwdt.h b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_wwdt.h new file mode 100644 index 0000000..8c26c5a --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_wwdt.h @@ -0,0 +1,158 @@ +/** + ************************************************************************** + * @file at32f403a_407_wwdt.h + * @version v2.0.9 + * @date 2022-04-25 + * @brief at32f403a_407 wwdt header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_WWDT_H +#define __AT32F403A_407_WWDT_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f403a_407.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @addtogroup WWDT + * @{ + */ + +/** @defgroup WWDT_enable_bit_definition + * @brief wwdt enable bit + * @{ + */ + +#define WWDT_EN_BIT ((uint32_t)0x00000080) /*!< wwdt enable bit */ + +/** + * @} + */ + +/** @defgroup WWDT_exported_types + * @{ + */ + +/** + * @brief wwdt division type + */ +typedef enum +{ + WWDT_PCLK1_DIV_4096 = 0x00, /*!< wwdt counter clock = (pclk1/4096)/1) */ + WWDT_PCLK1_DIV_8192 = 0x01, /*!< wwdt counter clock = (pclk1/4096)/2) */ + WWDT_PCLK1_DIV_16384 = 0x02, /*!< wwdt counter clock = (pclk1/4096)/4) */ + WWDT_PCLK1_DIV_32768 = 0x03 /*!< wwdt counter clock = (pclk1/4096)/8) */ +} wwdt_division_type; + +/** + * @brief type define wwdt register all + */ +typedef struct +{ + + /** + * @brief wwdt ctrl register, offset:0x00 + */ + union + { + __IO uint32_t ctrl; + struct + { + __IO uint32_t cnt : 7; /* [6:0] */ + __IO uint32_t wwdten : 1; /* [7] */ + __IO uint32_t reserved1 : 24;/* [31:8] */ + } ctrl_bit; + }; + + /** + * @brief wwdt cfg register, offset:0x04 + */ + union + { + __IO uint32_t cfg; + struct + { + __IO uint32_t win : 7; /* [6:0] */ + __IO uint32_t div : 2; /* [8:7] */ + __IO uint32_t rldien : 1; /* [9] */ + __IO uint32_t reserved1 : 22;/* [31:10] */ + } cfg_bit; + }; + + /** + * @brief wwdt cfg register, offset:0x08 + */ + union + { + __IO uint32_t sts; + struct + { + __IO uint32_t rldf : 1; /* [0] */ + __IO uint32_t reserved1 : 31;/* [31:1] */ + } sts_bit; + }; + +} wwdt_type; + +/** + * @} + */ + +#define WWDT ((wwdt_type *) WWDT_BASE) + +/** @defgroup WWDT_exported_functions + * @{ + */ + +void wwdt_reset(void); +void wwdt_divider_set(wwdt_division_type division); +void wwdt_flag_clear(void); +void wwdt_enable(uint8_t wwdt_cnt); +void wwdt_interrupt_enable(void); +flag_status wwdt_flag_get(void); +void wwdt_counter_set(uint8_t wwdt_cnt); +void wwdt_window_counter_set(uint8_t window_cnt); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_xmc.h b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_xmc.h new file mode 100644 index 0000000..67d2645 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/inc/at32f403a_407_xmc.h @@ -0,0 +1,568 @@ +/** + ************************************************************************** + * @file at32f403a_407_xmc.h + * @version v2.0.9 + * @date 2022-04-25 + * @brief at32f403a_407 xmc header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_XMC_H +#define __AT32F403A_407_XMC_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f403a_407.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @addtogroup XMC + * @{ + */ + +/** @defgroup XMC_exported_types + * @{ + */ + +/** + * @brief xmc data address bus multiplexing type + */ +typedef enum +{ + XMC_DATA_ADDR_MUX_DISABLE = 0x00000000, /*!< xmc address/data multiplexing disable */ + XMC_DATA_ADDR_MUX_ENABLE = 0x00000002 /*!< xmc address/data multiplexing enable */ +} xmc_data_addr_mux_type; + +/** + * @brief xmc burst access mode type + */ +typedef enum +{ + XMC_BURST_MODE_DISABLE = 0x00000000, /*!< xmc burst mode disable */ + XMC_BURST_MODE_ENABLE = 0x00000100 /*!< xmc burst mode enable */ +} xmc_burst_access_mode_type; + +/** + * @brief xmc asynchronous wait type + */ +typedef enum +{ + XMC_ASYN_WAIT_DISABLE = 0x00000000, /*!< xmc wait signal during asynchronous transfers disbale */ + XMC_ASYN_WAIT_ENABLE = 0x00008000 /*!< xmc wait signal during asynchronous transfers enable */ +} xmc_asyn_wait_type; + +/** + * @brief xmc wrapped mode type + */ +typedef enum +{ + XMC_WRAPPED_MODE_DISABLE = 0x00000000, /*!< xmc direct wrapped burst is disbale */ + XMC_WRAPPED_MODE_ENABLE = 0x00000400 /*!< xmc direct wrapped burst is enable */ +} xmc_wrap_mode_type; + +/** + * @brief xmc write operation type + */ +typedef enum +{ + XMC_WRITE_OPERATION_DISABLE = 0x00000000, /*!< xmc write operations is disable */ + XMC_WRITE_OPERATION_ENABLE = 0x00001000 /*!< xmc write operations is enable */ +} xmc_write_operation_type; + +/** + * @brief xmc wait signal type + */ +typedef enum +{ + XMC_WAIT_SIGNAL_DISABLE = 0x00000000, /*!< xmc nwait signal is disable */ + XMC_WAIT_SIGNAL_ENABLE = 0x00002000 /*!< xmc nwait signal is enable */ +} xmc_wait_signal_type; + +/** + * @brief xmc write burst type + */ +typedef enum +{ + XMC_WRITE_BURST_SYN_DISABLE = 0x00000000, /*!< xmc write operations are always performed in asynchronous mode */ + XMC_WRITE_BURST_SYN_ENABLE = 0x00080000 /*!< xmc write operations are performed in synchronous mode */ +} xmc_write_burst_type; + +/** + * @brief xmc extended mode type + */ +typedef enum +{ + XMC_WRITE_TIMING_DISABLE = 0x00000000, /*!< xmc write timing disable */ + XMC_WRITE_TIMING_ENABLE = 0x00004000 /*!< xmc write timing enable */ +} xmc_extended_mode_type; + +/** + * @brief xmc nand wait type + */ +typedef enum +{ + XMC_WAIT_OPERATION_DISABLE = 0x00000000, /*!< xmc wait operation for the nand flash memory bank disable */ + XMC_WAIT_OPERATION_ENABLE = 0x00000002 /*!< xmc wait operation for the nand flash memory bank enable */ +} xmc_nand_wait_type; + +/** + * @brief xmc ecc enable type + */ +typedef enum +{ + XMC_ECC_OPERATION_DISABLE = 0x00000000, /*!< xmc ecc module disable */ + XMC_ECC_OPERATION_ENABLE = 0x00000040 /*!< xmc ecc module enable */ +} xmc_ecc_enable_type; + +/** + * @brief xmc nor/sram bank type + */ +typedef enum +{ + XMC_BANK1_NOR_SRAM1 = 0x00000000, /*!< xmc nor/sram subbank1 */ + XMC_BANK1_NOR_SRAM4 = 0x00000003 /*!< xmc nor/sram subbank4 */ +} xmc_nor_sram_subbank_type; + +/** + * @brief xmc class bank type + */ +typedef enum +{ + XMC_BANK2_NAND = 0x00000010, /*!< xmc nand flash bank2 */ +} xmc_class_bank_type; + +/** + * @brief xmc memory type + */ +typedef enum +{ + XMC_DEVICE_SRAM = 0x00000000, /*!< xmc device choice sram */ + XMC_DEVICE_PSRAM = 0x00000004, /*!< xmc device choice psram */ + XMC_DEVICE_NOR = 0x00000008 /*!< xmc device choice nor flash */ +} xmc_memory_type; + +/** + * @brief xmc data width type + */ +typedef enum +{ + XMC_BUSTYPE_8_BITS = 0x00000000, /*!< xmc databuss width 8bits */ + XMC_BUSTYPE_16_BITS = 0x00000010 /*!< xmc databuss width 16bits */ +} xmc_data_width_type; + +/** + * @brief xmc wait signal polarity type + */ +typedef enum +{ + XMC_WAIT_SIGNAL_LEVEL_LOW = 0x00000000, /*!< xmc nwait active low */ + XMC_WAIT_SIGNAL_LEVEL_HIGH = 0x00000200 /*!< xmc nwait active high */ +} xmc_wait_signal_polarity_type; + +/** + * @brief xmc wait timing type + */ +typedef enum +{ + XMC_WAIT_SIGNAL_SYN_BEFORE = 0x00000000, /*!< xmc nwait signal is active one data cycle before wait state */ + XMC_WAIT_SIGNAL_SYN_DURING = 0x00000800 /*!< xmc nwait signal is active during wait state */ +} xmc_wait_timing_type; + +/** + * @brief xmc access mode type + */ +typedef enum +{ + XMC_ACCESS_MODE_A = 0x00000000, /*!< xmc access mode A */ + XMC_ACCESS_MODE_B = 0x10000000, /*!< xmc access mode B */ + XMC_ACCESS_MODE_C = 0x20000000, /*!< xmc access mode C */ + XMC_ACCESS_MODE_D = 0x30000000 /*!< xmc access mode D */ +} xmc_access_mode_type; + +/** + * @brief xmc ecc page size type + */ +typedef enum +{ + XMC_ECC_PAGESIZE_256_BYTES = 0x00000000, /*!< xmc ecc page size 256 bytes */ + XMC_ECC_PAGESIZE_512_BYTES = 0x00020000, /*!< xmc ecc page size 512 bytes */ + XMC_ECC_PAGESIZE_1024_BYTES = 0x00040000, /*!< xmc ecc page size 1024 bytes */ + XMC_ECC_PAGESIZE_2048_BYTES = 0x00060000, /*!< xmc ecc page size 2048 bytes */ + XMC_ECC_PAGESIZE_4096_BYTES = 0x00080000, /*!< xmc ecc page size 4096 bytes */ + XMC_ECC_PAGESIZE_8192_BYTES = 0x000A0000 /*!< xmc ecc page size 8192 bytes */ +} xmc_ecc_pagesize_type; + +/** + * @brief xmc interrupt sources type + */ +typedef enum +{ + XMC_INT_RISING_EDGE = 0x00000008, /*!< xmc rising edge detection interrupt enable */ + XMC_INT_LEVEL = 0x00000010, /*!< xmc high-level edge detection interrupt enable */ + XMC_INT_FALLING_EDGE = 0x00000020 /*!< xmc falling edge detection interrupt enable */ +} xmc_interrupt_sources_type; + +/** + * @brief xmc interrupt flag type + */ +typedef enum +{ + XMC_RISINGEDGE_FLAG = 0x00000001, /*!< xmc interrupt rising edge detection flag */ + XMC_LEVEL_FLAG = 0x00000002, /*!< xmc interrupt high-level edge detection flag */ + XMC_FALLINGEDGE_FLAG = 0x00000004, /*!< xmc interrupt falling edge detection flag */ + XMC_FEMPT_FLAG = 0x00000040 /*!< xmc fifo empty flag */ +} xmc_interrupt_flag_type; + +/** + * @brief nor/sram banks timing parameters + */ +typedef struct +{ + xmc_nor_sram_subbank_type subbank; /*!< xmc nor/sram subbank */ + xmc_extended_mode_type write_timing_enable; /*!< xmc nor/sram write timing enable */ + uint32_t addr_setup_time; /*!< xmc nor/sram address setup time */ + uint32_t addr_hold_time; /*!< xmc nor/sram address hold time */ + uint32_t data_setup_time; /*!< xmc nor/sram data setup time */ + uint32_t bus_latency_time; /*!< xmc nor/sram bus latency time */ + uint32_t clk_psc; /*!< xmc nor/sram clock prescale */ + uint32_t data_latency_time; /*!< xmc nor/sram data latency time */ + xmc_access_mode_type mode; /*!< xmc nor/sram access mode */ +} xmc_norsram_timing_init_type; + +/** + * @brief xmc nor/sram init structure definition + */ +typedef struct +{ + xmc_nor_sram_subbank_type subbank; /*!< xmc nor/sram subbank */ + xmc_data_addr_mux_type data_addr_multiplex; /*!< xmc nor/sram address/data multiplexing enable */ + xmc_memory_type device; /*!< xmc nor/sram memory device */ + xmc_data_width_type bus_type; /*!< xmc nor/sram data bus width */ + xmc_burst_access_mode_type burst_mode_enable; /*!< xmc nor/sram burst mode enable */ + xmc_asyn_wait_type asynwait_enable; /*!< xmc nor/sram nwait in asynchronous transfer enable */ + xmc_wait_signal_polarity_type wait_signal_lv; /*!< xmc nor/sram nwait polarity */ + xmc_wrap_mode_type wrapped_mode_enable; /*!< xmc nor/sram wrapped enable */ + xmc_wait_timing_type wait_signal_config; /*!< xmc nor/sram nwait timing configuration */ + xmc_write_operation_type write_enable; /*!< xmc nor/sram write enable */ + xmc_wait_signal_type wait_signal_enable; /*!< xmc nor/sram nwait in synchronous transfer enable */ + xmc_extended_mode_type write_timing_enable; /*!< xmc nor/sram read-write timing different */ + xmc_write_burst_type write_burst_syn; /*!< xmc nor/sram memory write mode control */ +} xmc_norsram_init_type; + +/** + * @brief nand timing parameters xmc + */ + +typedef struct +{ + xmc_class_bank_type class_bank; /*!< xmc nand bank */ + uint32_t mem_setup_time; /*!< xmc nand memory setup time */ + uint32_t mem_waite_time; /*!< xmc nand memory wait time */ + uint32_t mem_hold_time; /*!< xmc nand memory hold time */ + uint32_t mem_hiz_time; /*!< xmc nand memory databus high resistance time */ +} xmc_nand_timinginit_type; + +/** + * @brief xmc nand init structure definition + */ + +typedef struct +{ + xmc_class_bank_type nand_bank; /*!< xmc nand bank */ + xmc_nand_wait_type wait_enable; /*!< xmc wait feature enable */ + xmc_data_width_type bus_type; /*!< xmc nand bus width */ + xmc_ecc_enable_type ecc_enable; /*!< xmc nand ecc enable */ + xmc_ecc_pagesize_type ecc_pagesize; /*!< xmc nand ecc page size */ + uint32_t delay_time_cycle; /*!< xmc nand cle to re delay */ + uint32_t delay_time_ar; /*!< xmc nand ale to re delay */ +} xmc_nand_init_type; + +typedef struct +{ + /** + * @brief xmc bank1 bk1ctrl register, offset:0x00+0x08*(x-1) x= 1 or 4 + */ + union + { + __IO uint32_t bk1ctrl; + struct + { + __IO uint32_t en : 1; /* [0] */ + __IO uint32_t admuxen : 1; /* [1] */ + __IO uint32_t dev : 2; /* [3:2] */ + __IO uint32_t extmdbw : 2; /* [5:4] */ + __IO uint32_t noren : 1; /* [6] */ + __IO uint32_t reserved1 : 1; /* [7] */ + __IO uint32_t syncben : 1; /* [8] */ + __IO uint32_t nwpol : 1; /* [9] */ + __IO uint32_t wrapen : 1; /* [10] */ + __IO uint32_t nwtcfg : 1; /* [11] */ + __IO uint32_t wen : 1; /* [12] */ + __IO uint32_t nwsen : 1; /* [13] */ + __IO uint32_t rwtd : 1; /* [14] */ + __IO uint32_t nwasen : 1; /* [15] */ + __IO uint32_t crpgs : 3; /* [18:16] */ + __IO uint32_t mwmc : 1; /* [19] */ + __IO uint32_t reserved2 : 12;/* [31:20] */ + } bk1ctrl_bit; + }; + + /** + * @brief xmc bank1 bk1tmg register, offset:0x04+0x08*(x-1) x= 1 or 4 + */ + union + { + __IO uint32_t bk1tmg; + struct + { + __IO uint32_t addrst : 4; /* [3:0] */ + __IO uint32_t addrht : 4; /* [7:4] */ + __IO uint32_t dtst : 8; /* [15:8] */ + __IO uint32_t buslat : 4; /* [19:16] */ + __IO uint32_t clkpsc : 4; /* [23:20] */ + __IO uint32_t dtlat : 4; /* [27:24] */ + __IO uint32_t asyncm : 2; /* [29:28] */ + __IO uint32_t reserved1 : 2; /* [31:30] */ + } bk1tmg_bit; + }; + +} xmc_bank1_ctrl_tmg_reg_type; + +typedef struct +{ + /** + * @brief xmc bank1 bk1tmgwr register, offset:0x104+0x08*(x-1) x= 1 or 4 + */ + union + { + __IO uint32_t bk1tmgwr; + struct + { + __IO uint32_t addrst : 4; /* [3:0] */ + __IO uint32_t addrht : 4; /* [7:4] */ + __IO uint32_t dtst : 8; /* [15:8] */ + __IO uint32_t buslat : 4; /* [19:16] */ + __IO uint32_t reserved1 : 8; /* [27:20] */ + __IO uint32_t asyncm : 2; /* [29:28] */ + __IO uint32_t reserved2 : 2; /* [31:30] */ + } bk1tmgwr_bit; + }; + + /** + * @brief xmc bank1 reserved register + */ + __IO uint32_t reserved1; + +} xmc_bank1_tmgwr_reg_type; + +/** + * @brief xmc bank1 registers + */ +typedef struct +{ + /** + * @brief xmc bank1 ctrl and tmg register, offset:0x00~0x1C + */ + xmc_bank1_ctrl_tmg_reg_type ctrl_tmg_group[4]; + + /** + * @brief xmc bank1 reserved register, offset:0x20~0x100 + */ + __IO uint32_t reserved1[57]; + + /** + * @brief xmc bank1 tmgwr register, offset:0x104~0x11C + */ + xmc_bank1_tmgwr_reg_type tmgwr_group[4]; + + /** + * @brief xmc bank1 reserved register, offset:0x120~0x21C + */ + __IO uint32_t reserved2[63]; + + /** + * @brief xmc bank1 ext register, offset:0x220~0x22C + */ + union + { + __IO uint32_t ext[4]; + struct + { + __IO uint32_t buslatw2w : 8; /* [7:0] */ + __IO uint32_t buslatr2r : 8; /* [15:8] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } ext_bit[4]; + }; + +} xmc_bank1_type; + +/** + * @brief xmc bank2 registers + */ +typedef struct +{ + /** + * @brief xmc bk2ctrl register, offset:0x60 + */ + union + { + __IO uint32_t bk2ctrl; + struct + { + __IO uint32_t reserved1 : 1; /* [0] */ + __IO uint32_t nwen : 1; /* [1] */ + __IO uint32_t en : 1; /* [2] */ + __IO uint32_t dev : 1; /* [3] */ + __IO uint32_t extmdbw : 2; /* [5:4] */ + __IO uint32_t eccen : 1; /* [6] */ + __IO uint32_t reserved2 : 2; /* [8:7] */ + __IO uint32_t tcr : 4; /* [12:9] */ + __IO uint32_t tar : 4; /* [16:13] */ + __IO uint32_t eccpgs : 3; /* [19:17] */ + __IO uint32_t reserved3 : 12;/* [31:20] */ + } bk2ctrl_bit; + }; + + /** + * @brief xmc bk2is register, offset:0x64 + */ + union + { + __IO uint32_t bk2is; + struct + { + __IO uint32_t res : 1; /* [0] */ + __IO uint32_t hls : 1; /* [1] */ + __IO uint32_t fes : 1; /* [2] */ + __IO uint32_t reien : 1; /* [3] */ + __IO uint32_t hlien : 1; /* [4] */ + __IO uint32_t feien : 1; /* [5] */ + __IO uint32_t fifoe : 1; /* [6] */ + __IO uint32_t reserved1 : 25;/* [31:7] */ + } bk2is_bit; + }; + + /** + * @brief xmc bk2tmgmem register, offset:0x68 + */ + union + { + __IO uint32_t bk2tmgmem; + struct + { + __IO uint32_t cmst : 8; /* [7:0] */ + __IO uint32_t cmwt : 8; /* [15:8] */ + __IO uint32_t cmht : 8; /* [23:16] */ + __IO uint32_t cmdhizt : 8; /* [31:24] */ + } bk2tmgmem_bit; + }; + + /** + * @brief xmc bk2tmgatt register, offset:0x6C + */ + union + { + __IO uint32_t bk2tmgatt; + struct + { + __IO uint32_t amst : 8; /* [7:0] */ + __IO uint32_t amwt : 8; /* [15:8] */ + __IO uint32_t amht : 8; /* [23:16] */ + __IO uint32_t amdhizt : 8; /* [31:24] */ + } bk2tmgatt_bit; + }; + + /** + * @brief xmc reserved register, offset:0x70 + */ + __IO uint32_t reserved1; + + /** + * @brief xmc bk2ecc register, offset:0x74 + */ + union + { + __IO uint32_t bk2ecc; + struct + { + __IO uint32_t ecc : 32; /* [31:0] */ + } bk2ecc_bit; + }; + +} xmc_bank2_type; + +/** + * @} + */ + +#define XMC_BANK1 ((xmc_bank1_type *) XMC_BANK1_REG_BASE) +#define XMC_BANK2 ((xmc_bank2_type *) XMC_BANK2_REG_BASE) + +/** @defgroup XMC_exported_functions + * @{ + */ + +void xmc_nor_sram_reset(xmc_nor_sram_subbank_type xmc_subbank); +void xmc_nor_sram_init(xmc_norsram_init_type* xmc_norsram_init_struct); +void xmc_nor_sram_timing_config(xmc_norsram_timing_init_type* xmc_rw_timing_struct, + xmc_norsram_timing_init_type* xmc_w_timing_struct); +void xmc_norsram_default_para_init(xmc_norsram_init_type* xmc_nor_sram_init_struct); +void xmc_norsram_timing_default_para_init(xmc_norsram_timing_init_type* xmc_rw_timing_struct, + xmc_norsram_timing_init_type* xmc_w_timing_struct); +void xmc_nor_sram_enable(xmc_nor_sram_subbank_type xmc_subbank, confirm_state new_state); +void xmc_ext_timing_config(xmc_nor_sram_subbank_type xmc_sub_bank, uint16_t w2w_timing, uint16_t r2r_timing); +void xmc_nand_reset(xmc_class_bank_type xmc_bank); +void xmc_nand_init(xmc_nand_init_type* xmc_nand_init_struct); +void xmc_nand_timing_config(xmc_nand_timinginit_type* xmc_common_spacetiming_struct, + xmc_nand_timinginit_type* xmc_attribute_spacetiming_struct); +void xmc_nand_default_para_init(xmc_nand_init_type* xmc_nand_init_struct); +void xmc_nand_timing_default_para_init(xmc_nand_timinginit_type* xmc_common_spacetiming_struct, + xmc_nand_timinginit_type* xmc_attribute_spacetiming_struct); +void xmc_nand_enable(xmc_class_bank_type xmc_bank, confirm_state new_state); +void xmc_nand_ecc_enable(xmc_class_bank_type xmc_bank, confirm_state new_state); +uint32_t xmc_ecc_get(xmc_class_bank_type xmc_bank); +void xmc_interrupt_enable(xmc_class_bank_type xmc_bank, xmc_interrupt_sources_type xmc_int, confirm_state new_state); +flag_status xmc_flag_status_get(xmc_class_bank_type xmc_bank, xmc_interrupt_flag_type xmc_flag); +void xmc_flag_clear(xmc_class_bank_type xmc_bank, xmc_interrupt_flag_type xmc_flag); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_acc.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_acc.c new file mode 100644 index 0000000..770db6a --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_acc.c @@ -0,0 +1,218 @@ +/** + ************************************************************************** + * @file at32f403a_407_acc.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the acc firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup ACC + * @brief ACC driver modules + * @{ + */ + +#ifdef ACC_MODULE_ENABLED + +/** @defgroup ACC_private_functions + * @{ + */ + +/** + * @brief enable or disable the acc calibration mode. + * @param acc_trim: specifies the acc calibration type. + * this parameter can be one of the following values: + * - ACC_CAL_HICKCAL + * - ACC_CAL_HICKTRIM + * @param new_state: specifies the acc calibration to be enabled or disabled.(TRUE or FALSE) + * @retval none + */ +void acc_calibration_mode_enable(uint16_t acc_trim, confirm_state new_state) +{ + if(acc_trim == ACC_CAL_HICKCAL) + { + ACC->ctrl1_bit.entrim = FALSE; + } + else + { + ACC->ctrl1_bit.entrim = TRUE; + } + ACC->ctrl1_bit.calon = new_state; +} + +/** + * @brief store calibration step data in acc's ctrl1 register. + * @param step_value: value to be stored in the acc's ctrl1 register + * @retval none + */ +void acc_step_set(uint8_t step_value) +{ + ACC->ctrl1_bit.step = step_value; +} + +/** + * @brief enable or disable the specified acc interrupts. + * @param acc_int: specifies the acc interrupt sources to be enabled or disabled. + * this parameter can be one of the following values: + * - ACC_CALRDYIEN_INT + * - ACC_EIEN_INT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void acc_interrupt_enable(uint16_t acc_int, confirm_state new_state) +{ + if(acc_int == ACC_CALRDYIEN_INT) + { + ACC->ctrl1_bit.calrdyien = new_state; + } + else + { + ACC->ctrl1_bit.eien = new_state; + } +} + +/** + * @brief return the current acc hicktrim value. + * @param none + * @retval 8-bit hicktrim value. + */ +uint8_t acc_hicktrim_get(void) +{ + return ((uint8_t)(ACC->ctrl2_bit.hicktrim)); +} + +/** + * @brief return the current acc hickcal value. + * @param none + * @retval 8-bit hicktrim value. + */ +uint8_t acc_hickcal_get(void) +{ + return ((uint8_t)(ACC->ctrl2_bit.hickcal)); +} + +/** + * @brief wtire the value to acc c1 register. + * @param acc_c1_value + * @retval none. + */ +void acc_write_c1(uint16_t acc_c1_value) +{ + ACC->c1 = acc_c1_value; +} + +/** + * @brief wtire the value to acc c2 register. + * @param acc_c2_value + * @retval none. + */ +void acc_write_c2(uint16_t acc_c2_value) +{ + ACC->c2 = acc_c2_value; +} + +/** + * @brief wtire the value to acc c3 register. + * @param acc_c3_value + * @retval none. + */ +void acc_write_c3(uint16_t acc_c3_value) +{ + ACC->c3 = acc_c3_value; +} + +/** + * @brief return the current acc c1 value. + * @param none + * @retval 16-bit c1 value. + */ +uint16_t acc_read_c1(void) +{ + return ((uint16_t)(ACC->c1)); +} + +/** + * @brief return the current acc c2 value. + * @param none + * @retval 16-bit c2 value. + */ +uint16_t acc_read_c2(void) +{ + return ((uint16_t)(ACC->c2)); +} + +/** + * @brief return the current acc c3 value. + * @param none + * @retval 16-bit c3 value. + */ +uint16_t acc_read_c3(void) +{ + return ((uint16_t)(ACC->c3)); +} + +/** + * @brief check whether the specified acc flag is set or not. + * @param acc_flag: specifies the flag to check. + * this parameter can be one of the following values: + * - ACC_RSLOST_FLAG + * - ACC_CALRDY_FLAG + * @retval flag_status (SET or RESET) + */ +flag_status acc_flag_get(uint16_t acc_flag) +{ + if(acc_flag == ACC_CALRDY_FLAG) + return (flag_status)(ACC->sts_bit.calrdy); + else + return (flag_status)(ACC->sts_bit.rslost); +} + +/** + * @brief clear the specified acc flag is set or not. + * @param acc_flag: specifies the flag to check. + * this parameter can be any combination of the following values: + * - ACC_RSLOST_FLAG + * - ACC_CALRDY_FLAG + * @retval none + */ +void acc_flag_clear(uint16_t acc_flag) +{ + ACC->sts = ~acc_flag; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_adc.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_adc.c new file mode 100644 index 0000000..5161242 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_adc.c @@ -0,0 +1,949 @@ +/** + ************************************************************************** + * @file at32f403a_407_adc.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the adc firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup ADC + * @brief ADC driver modules + * @{ + */ + +#ifdef ADC_MODULE_ENABLED + +/** @defgroup ADC_private_functions + * @{ + */ + +/** + * @brief deinitialize the adc peripheral registers to their default reset values. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @retval none + */ +void adc_reset(adc_type *adc_x) +{ + if(adc_x == ADC1) + { + crm_periph_reset(CRM_ADC1_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_ADC1_PERIPH_RESET, FALSE); + } + else if(adc_x == ADC2) + { + crm_periph_reset(CRM_ADC2_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_ADC2_PERIPH_RESET, FALSE); + } + else if(adc_x == ADC3) + { + crm_periph_reset(CRM_ADC3_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_ADC3_PERIPH_RESET, FALSE); + } +} + +/** + * @brief enable or disable the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param new_state: new state of a/d converter. + * this parameter can be: TRUE or FALSE. + * note:after adc ready,user set adcen bit will cause ordinary conversion + * @retval none + */ +void adc_enable(adc_type *adc_x, confirm_state new_state) +{ + adc_x->ctrl2_bit.adcen = new_state; +} + +/** + * @brief select combine mode of the specified adc peripheral. + * @param combine_mode: select the adc combine mode. + * this parameter can be one of the following values: + * - ADC_INDEPENDENT_MODE + * - ADC_ORDINARY_SMLT_PREEMPT_SMLT_MODE + * - ADC_ORDINARY_SMLT_PREEMPT_INTERLTRIG_MODE + * - ADC_ORDINARY_SHORTSHIFT_PREEMPT_SMLT_MODE + * - ADC_ORDINARY_LONGSHIFT_PREEMPT_SMLT_MODE + * - ADC_PREEMPT_SMLT_ONLY_MODE + * - ADC_ORDINARY_SMLT_ONLY_MODE + * - ADC_ORDINARY_SHORTSHIFT_ONLY_MODE + * - ADC_ORDINARY_LONGSHIFT_ONLY_MODE + * - ADC_PREEMPT_INTERLTRIG_ONLY_MODE + * note:these bits are reserved in adc2 and adc3 + * @retval none + */ +void adc_combine_mode_select(adc_combine_mode_type combine_mode) +{ + ADC1->ctrl1_bit.mssel = combine_mode; +} + +/** + * @brief adc base default para init. + * @param sequence_mode: set the state of adc sequence mode. + * this parameter can be:TRUE or FALSE + * @param repeat_mode: set the state of adc repeat conversion mode. + * this parameter can be:TRUE or FALSE + * @param data_align: set the state of adc data alignment. + * this parameter can be one of the following values: + * - ADC_RIGHT_ALIGNMENT + * - ADC_LEFT_ALIGNMENT + * @param ordinary_channel_length: configure the adc ordinary channel sequence length. + * this parameter can be: + * - (0x1~0xf) + * @retval none + */ +void adc_base_default_para_init(adc_base_config_type *adc_base_struct) +{ + adc_base_struct->sequence_mode = FALSE; + adc_base_struct->repeat_mode = FALSE; + adc_base_struct->data_align = ADC_RIGHT_ALIGNMENT; + adc_base_struct->ordinary_channel_length = 1; +} + +/** + * @brief initialize the adc peripheral according to the specified parameters. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param sequence_mode: set the state of adc sequence mode. + * this parameter can be:TRUE or FALSE + * @param repeat_mode: set the state of adc repeat conversion mode. + * this parameter can be:TRUE or FALSE + * @param data_align: set the state of adc data alignment. + * this parameter can be one of the following values: + * - ADC_RIGHT_ALIGNMENT + * - ADC_LEFT_ALIGNMENT + * @param ordinary_channel_length: configure the adc ordinary channel sequence length. + * this parameter can be: + * - (0x1~0xf) + * @retval none + */ +void adc_base_config(adc_type *adc_x, adc_base_config_type *adc_base_struct) +{ + adc_x->ctrl1_bit.sqen = adc_base_struct->sequence_mode; + adc_x->ctrl2_bit.rpen = adc_base_struct->repeat_mode; + adc_x->ctrl2_bit.dtalign = adc_base_struct->data_align; + adc_x->osq1_bit.oclen = adc_base_struct->ordinary_channel_length - 1; +} + +/** + * @brief enable or disable the adc dma transfer. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC3. + * note:this bit is reserved in adc2 + * @param new_state: new state of the adc dma transfer. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_dma_mode_enable(adc_type *adc_x, confirm_state new_state) +{ + adc_x->ctrl2_bit.ocdmaen = new_state; +} + +/** + * @brief enable or disable the specified adc interrupts. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param adc_int: specifies the adc interrupt sources to be enabled or disabled. + * this parameter can be one of the following values: + * - ADC_VMOR_INT + * - ADC_CCE_INT + * - ADC_PCCE_INT + * @param new_state: new state of the specified adc interrupts. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_interrupt_enable(adc_type *adc_x, uint32_t adc_int, confirm_state new_state) +{ + if(new_state == TRUE) + { + adc_x->ctrl1 |= adc_int; + } + else if(new_state == FALSE) + { + adc_x->ctrl1 &= ~adc_int; + } +} + +/** + * @brief initialize calibration register of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @retval none + */ +void adc_calibration_init(adc_type *adc_x) +{ + adc_x->ctrl2_bit.adcalinit = TRUE; +} + +/** + * @brief get calibration register's initialize status of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @retval the new state of reset calibration register status(SET or RESET). + */ +flag_status adc_calibration_init_status_get(adc_type *adc_x) +{ + if(adc_x->ctrl2_bit.adcalinit) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief start calibration process of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @retval none + */ +void adc_calibration_start(adc_type *adc_x) +{ + adc_x->ctrl2_bit.adcal = TRUE; +} + +/** + * @brief get calibration status of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @retval the new state of calibration status(SET or RESET). + */ +flag_status adc_calibration_status_get(adc_type *adc_x) +{ + if(adc_x->ctrl2_bit.adcal) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief enable or disable the voltage monitoring on single/all ordinary or preempt channels of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param adc_voltage_monitoring: choose the adc_voltage_monitoring config. + * this parameter can be one of the following values: + * - ADC_VMONITOR_SINGLE_ORDINARY + * - ADC_VMONITOR_SINGLE_PREEMPT + * - ADC_VMONITOR_SINGLE_ORDINARY_PREEMPT + * - ADC_VMONITOR_ALL_ORDINARY + * - ADC_VMONITOR_ALL_PREEMPT + * - ADC_VMONITOR_ALL_ORDINARY_PREEMPT + * - ADC_VMONITOR_NONE + * @retval none + */ +void adc_voltage_monitor_enable(adc_type *adc_x, adc_voltage_monitoring_type adc_voltage_monitoring) +{ + adc_x->ctrl1_bit.ocvmen = FALSE; + adc_x->ctrl1_bit.pcvmen = FALSE; + adc_x->ctrl1_bit.vmsgen = FALSE; + adc_x->ctrl1 |= adc_voltage_monitoring; +} + +/** + * @brief set voltage monitoring's high and low thresholds value of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param adc_high_threshold: voltage monitoring's high thresholds value. + * this parameter can be: + * - (0x000~0xFFF) + * @param adc_low_threshold: voltage monitoring's low thresholds value. + * this parameter can be: + * - (0x000~0xFFF) + * @retval none + */ +void adc_voltage_monitor_threshold_value_set(adc_type *adc_x, uint16_t adc_high_threshold, uint16_t adc_low_threshold) +{ + adc_x->vmhb_bit.vmhb = adc_high_threshold; + adc_x->vmlb_bit.vmlb = adc_low_threshold; +} + +/** + * @brief select the voltage monitoring's channel of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param adc_channel: select the channel. + * this parameter can be one of the following values: + * - ADC_CHANNEL_0 - ADC_CHANNEL_1 - ADC_CHANNEL_2 - ADC_CHANNEL_3 + * - ADC_CHANNEL_4 - ADC_CHANNEL_5 - ADC_CHANNEL_6 - ADC_CHANNEL_7 + * - ADC_CHANNEL_8 - ADC_CHANNEL_9 - ADC_CHANNEL_10 - ADC_CHANNEL_11 + * - ADC_CHANNEL_12 - ADC_CHANNEL_13 - ADC_CHANNEL_14 - ADC_CHANNEL_15 + * - ADC_CHANNEL_16 - ADC_CHANNEL_17 + * @retval none + */ +void adc_voltage_monitor_single_channel_select(adc_type *adc_x, adc_channel_select_type adc_channel) +{ + adc_x->ctrl1_bit.vmcsel = adc_channel; +} + +/** + * @brief set ordinary channel's corresponding rank in the sequencer and sample time of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param adc_channel: select the channel. + * this parameter can be one of the following values: + * - ADC_CHANNEL_0 - ADC_CHANNEL_1 - ADC_CHANNEL_2 - ADC_CHANNEL_3 + * - ADC_CHANNEL_4 - ADC_CHANNEL_5 - ADC_CHANNEL_6 - ADC_CHANNEL_7 + * - ADC_CHANNEL_8 - ADC_CHANNEL_9 - ADC_CHANNEL_10 - ADC_CHANNEL_11 + * - ADC_CHANNEL_12 - ADC_CHANNEL_13 - ADC_CHANNEL_14 - ADC_CHANNEL_15 + * - ADC_CHANNEL_16 - ADC_CHANNEL_17 + * @param adc_sequence: set rank in the ordinary group sequencer. + * this parameter must be: + * - between 1 to 16 + * @param adc_sampletime: set the sampletime of adc channel. + * this parameter can be one of the following values: + * - ADC_SAMPLETIME_1_5 + * - ADC_SAMPLETIME_7_5 + * - ADC_SAMPLETIME_13_5 + * - ADC_SAMPLETIME_28_5 + * - ADC_SAMPLETIME_41_5 + * - ADC_SAMPLETIME_55_5 + * - ADC_SAMPLETIME_71_5 + * - ADC_SAMPLETIME_239_5 + * @retval none + */ +void adc_ordinary_channel_set(adc_type *adc_x, adc_channel_select_type adc_channel, uint8_t adc_sequence, adc_sampletime_select_type adc_sampletime) +{ + switch(adc_channel) + { + case ADC_CHANNEL_0: + adc_x->spt2_bit.cspt0 = adc_sampletime; + break; + case ADC_CHANNEL_1: + adc_x->spt2_bit.cspt1 = adc_sampletime; + break; + case ADC_CHANNEL_2: + adc_x->spt2_bit.cspt2 = adc_sampletime; + break; + case ADC_CHANNEL_3: + adc_x->spt2_bit.cspt3 = adc_sampletime; + break; + case ADC_CHANNEL_4: + adc_x->spt2_bit.cspt4 = adc_sampletime; + break; + case ADC_CHANNEL_5: + adc_x->spt2_bit.cspt5 = adc_sampletime; + break; + case ADC_CHANNEL_6: + adc_x->spt2_bit.cspt6 = adc_sampletime; + break; + case ADC_CHANNEL_7: + adc_x->spt2_bit.cspt7 = adc_sampletime; + break; + case ADC_CHANNEL_8: + adc_x->spt2_bit.cspt8 = adc_sampletime; + break; + case ADC_CHANNEL_9: + adc_x->spt2_bit.cspt9 = adc_sampletime; + break; + case ADC_CHANNEL_10: + adc_x->spt1_bit.cspt10 = adc_sampletime; + break; + case ADC_CHANNEL_11: + adc_x->spt1_bit.cspt11 = adc_sampletime; + break; + case ADC_CHANNEL_12: + adc_x->spt1_bit.cspt12 = adc_sampletime; + break; + case ADC_CHANNEL_13: + adc_x->spt1_bit.cspt13 = adc_sampletime; + break; + case ADC_CHANNEL_14: + adc_x->spt1_bit.cspt14 = adc_sampletime; + break; + case ADC_CHANNEL_15: + adc_x->spt1_bit.cspt15 = adc_sampletime; + break; + case ADC_CHANNEL_16: + adc_x->spt1_bit.cspt16 = adc_sampletime; + break; + case ADC_CHANNEL_17: + adc_x->spt1_bit.cspt17 = adc_sampletime; + break; + default: + break; + } + switch(adc_sequence) + { + case 1: + adc_x->osq3_bit.osn1 = adc_channel; + break; + case 2: + adc_x->osq3_bit.osn2 = adc_channel; + break; + case 3: + adc_x->osq3_bit.osn3 = adc_channel; + break; + case 4: + adc_x->osq3_bit.osn4 = adc_channel; + break; + case 5: + adc_x->osq3_bit.osn5 = adc_channel; + break; + case 6: + adc_x->osq3_bit.osn6 = adc_channel; + break; + case 7: + adc_x->osq2_bit.osn7 = adc_channel; + break; + case 8: + adc_x->osq2_bit.osn8 = adc_channel; + break; + case 9: + adc_x->osq2_bit.osn9 = adc_channel; + break; + case 10: + adc_x->osq2_bit.osn10 = adc_channel; + break; + case 11: + adc_x->osq2_bit.osn11 = adc_channel; + break; + case 12: + adc_x->osq2_bit.osn12 = adc_channel; + break; + case 13: + adc_x->osq1_bit.osn13 = adc_channel; + break; + case 14: + adc_x->osq1_bit.osn14 = adc_channel; + break; + case 15: + adc_x->osq1_bit.osn15 = adc_channel; + break; + case 16: + adc_x->osq1_bit.osn16 = adc_channel; + break; + default: + break; + } +} + +/** + * @brief set preempt channel lenghth of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param adc_channel_lenght: set the adc preempt channel lenghth. + * this parameter can be: + * - (0x1~0x4) + * @retval none + */ +void adc_preempt_channel_length_set(adc_type *adc_x, uint8_t adc_channel_lenght) +{ + adc_x->psq_bit.pclen = adc_channel_lenght - 1; +} + +/** + * @brief configure preempt channel's corresponding rank in the sequencer and sample time of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param adc_channel: select the channel. + * this parameter can be one of the following values: + * - ADC_CHANNEL_0 - ADC_CHANNEL_1 - ADC_CHANNEL_2 - ADC_CHANNEL_3 + * - ADC_CHANNEL_4 - ADC_CHANNEL_5 - ADC_CHANNEL_6 - ADC_CHANNEL_7 + * - ADC_CHANNEL_8 - ADC_CHANNEL_9 - ADC_CHANNEL_10 - ADC_CHANNEL_11 + * - ADC_CHANNEL_12 - ADC_CHANNEL_13 - ADC_CHANNEL_14 - ADC_CHANNEL_15 + * - ADC_CHANNEL_16 - ADC_CHANNEL_17 + * @param adc_sequence: set rank in the preempt group sequencer. + * this parameter must be: + * - between 1 to 4 + * @param adc_sampletime: config the sampletime of adc channel. + * this parameter can be one of the following values: + * - ADC_SAMPLETIME_1_5 + * - ADC_SAMPLETIME_7_5 + * - ADC_SAMPLETIME_13_5 + * - ADC_SAMPLETIME_28_5 + * - ADC_SAMPLETIME_41_5 + * - ADC_SAMPLETIME_55_5 + * - ADC_SAMPLETIME_71_5 + * - ADC_SAMPLETIME_239_5 + * @retval none + */ +void adc_preempt_channel_set(adc_type *adc_x, adc_channel_select_type adc_channel, uint8_t adc_sequence, adc_sampletime_select_type adc_sampletime) +{ + uint16_t sequence_index=0; + switch(adc_channel) + { + case ADC_CHANNEL_0: + adc_x->spt2_bit.cspt0 = adc_sampletime; + break; + case ADC_CHANNEL_1: + adc_x->spt2_bit.cspt1 = adc_sampletime; + break; + case ADC_CHANNEL_2: + adc_x->spt2_bit.cspt2 = adc_sampletime; + break; + case ADC_CHANNEL_3: + adc_x->spt2_bit.cspt3 = adc_sampletime; + break; + case ADC_CHANNEL_4: + adc_x->spt2_bit.cspt4 = adc_sampletime; + break; + case ADC_CHANNEL_5: + adc_x->spt2_bit.cspt5 = adc_sampletime; + break; + case ADC_CHANNEL_6: + adc_x->spt2_bit.cspt6 = adc_sampletime; + break; + case ADC_CHANNEL_7: + adc_x->spt2_bit.cspt7 = adc_sampletime; + break; + case ADC_CHANNEL_8: + adc_x->spt2_bit.cspt8 = adc_sampletime; + break; + case ADC_CHANNEL_9: + adc_x->spt2_bit.cspt9 = adc_sampletime; + break; + case ADC_CHANNEL_10: + adc_x->spt1_bit.cspt10 = adc_sampletime; + break; + case ADC_CHANNEL_11: + adc_x->spt1_bit.cspt11 = adc_sampletime; + break; + case ADC_CHANNEL_12: + adc_x->spt1_bit.cspt12 = adc_sampletime; + break; + case ADC_CHANNEL_13: + adc_x->spt1_bit.cspt13 = adc_sampletime; + break; + case ADC_CHANNEL_14: + adc_x->spt1_bit.cspt14 = adc_sampletime; + break; + case ADC_CHANNEL_15: + adc_x->spt1_bit.cspt15 = adc_sampletime; + break; + case ADC_CHANNEL_16: + adc_x->spt1_bit.cspt16 = adc_sampletime; + break; + case ADC_CHANNEL_17: + adc_x->spt1_bit.cspt17 = adc_sampletime; + break; + default: + break; + } + sequence_index = adc_sequence + 3 - adc_x->psq_bit.pclen; + switch(sequence_index) + { + case 1: + adc_x->psq_bit.psn1 = adc_channel; + break; + case 2: + adc_x->psq_bit.psn2 = adc_channel; + break; + case 3: + adc_x->psq_bit.psn3 = adc_channel; + break; + case 4: + adc_x->psq_bit.psn4 = adc_channel; + break; + default: + break; + } +} + +/** + * @brief enable or disable the ordinary channel's external trigger and + * set external trigger event of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param adc_ordinary_trig: select the external trigger event. + * this parameter can be one of the following values: + * adc1 & adc2 + * - ADC12_ORDINARY_TRIG_TMR1CH1 - ADC12_ORDINARY_TRIG_TMR1CH2 - ADC12_ORDINARY_TRIG_TMR1CH3 - ADC12_ORDINARY_TRIG_TMR2CH2 + * - ADC12_ORDINARY_TRIG_TMR3TRGOUT - ADC12_ORDINARY_TRIG_TMR4CH4 - ADC12_ORDINARY_TRIG_EXINT11_TMR8TRGOUT - ADC12_ORDINARY_TRIG_SOFTWARE + * - ADC12_ORDINARY_TRIG_TMR1TRGOUT - ADC12_ORDINARY_TRIG_TMR8CH1 - ADC12_ORDINARY_TRIG_TMR8CH2 + * adc3 + * - ADC3_ORDINARY_TRIG_TMR3CH1 - ADC3_ORDINARY_TRIG_TMR2CH3 - ADC3_ORDINARY_TRIG_TMR1CH3 - ADC3_ORDINARY_TRIG_TMR8CH1 + * - ADC3_ORDINARY_TRIG_TMR8TRGOUT - ADC3_ORDINARY_TRIG_TMR5CH1 - ADC3_ORDINARY_TRIG_TMR5CH3 - ADC3_ORDINARY_TRIG_SOFTWARE + * - ADC3_ORDINARY_TRIG_TMR1TRGOUT - ADC3_ORDINARY_TRIG_TMR1CH1 - ADC3_ORDINARY_TRIG_TMR8CH3 + * @param new_state: new state of ordinary channel's external trigger. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_ordinary_conversion_trigger_set(adc_type *adc_x, adc_ordinary_trig_select_type adc_ordinary_trig, confirm_state new_state) +{ + if(adc_ordinary_trig > 7) + { + adc_x->ctrl2_bit.octesel_h = 1; + adc_x->ctrl2_bit.octesel_l = adc_ordinary_trig & 0x7; + } + else + { + adc_x->ctrl2_bit.octesel_h = 0; + adc_x->ctrl2_bit.octesel_l = adc_ordinary_trig & 0x7; + } + adc_x->ctrl2_bit.octen = new_state; +} + +/** + * @brief enable or disable the preempt channel's external trigger and + * set external trigger event of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param adc_preempt_trig: select the external trigger event. + * this parameter can be one of the following values: + * adc1 & adc2 + * - ADC12_PREEMPT_TRIG_TMR1TRGOUT - ADC12_PREEMPT_TRIG_TMR1CH4 - ADC12_PREEMPT_TRIG_TMR2TRGOUT - ADC12_PREEMPT_TRIG_TMR2CH1 + * - ADC12_PREEMPT_TRIG_TMR3CH4 - ADC12_PREEMPT_TRIG_TMR4TRGOUT - ADC12_PREEMPT_TRIG_EXINT15_TMR8CH4 - ADC12_PREEMPT_TRIG_SOFTWARE + * - ADC12_PREEMPT_TRIG_TMR1CH1 - ADC12_PREEMPT_TRIG_TMR8CH1 - ADC12_PREEMPT_TRIG_TMR8TRGOUT + * adc3 + * - ADC3_PREEMPT_TRIG_TMR1TRGOUT - ADC3_PREEMPT_TRIG_TMR1CH4 - ADC3_PREEMPT_TRIG_TMR4CH3 - ADC3_PREEMPT_TRIG_TMR8CH2 + * - ADC3_PREEMPT_TRIG_TMR8CH4 - ADC3_PREEMPT_TRIG_TMR5TRGOUT - ADC3_PREEMPT_TRIG_TMR5CH4 - ADC3_PREEMPT_TRIG_SOFTWARE + * - ADC3_PREEMPT_TRIG_TMR1CH1 - ADC3_PREEMPT_TRIG_TMR1CH2 - ADC3_PREEMPT_TRIG_TMR8TRGOUT + * @param new_state: new state of preempt channel's external trigger. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_preempt_conversion_trigger_set(adc_type *adc_x, adc_preempt_trig_select_type adc_preempt_trig, confirm_state new_state) +{ + if(adc_preempt_trig > 7) + { + adc_x->ctrl2_bit.pctesel_h = 1; + adc_x->ctrl2_bit.pctesel_l = adc_preempt_trig & 0x7; + } + else + { + adc_x->ctrl2_bit.pctesel_h = 0; + adc_x->ctrl2_bit.pctesel_l = adc_preempt_trig & 0x7; + } + adc_x->ctrl2_bit.pcten = new_state; +} + + +/** + * @brief set preempt channel's conversion value offset of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param adc_preempt_channel: select the preempt channel. + * this parameter can be one of the following values: + * - ADC_PREEMPT_CHANNEL_1 + * - ADC_PREEMPT_CHANNEL_2 + * - ADC_PREEMPT_CHANNEL_3 + * - ADC_PREEMPT_CHANNEL_4 + * @param adc_offset_value: set the adc preempt channel's conversion value offset. + * this parameter can be: + * - (0x000~0xFFF) + * @retval none + */ +void adc_preempt_offset_value_set(adc_type *adc_x, adc_preempt_channel_type adc_preempt_channel, uint16_t adc_offset_value) +{ + switch(adc_preempt_channel) + { + case ADC_PREEMPT_CHANNEL_1: + adc_x->pcdto1_bit.pcdto1 = adc_offset_value; + break; + case ADC_PREEMPT_CHANNEL_2: + adc_x->pcdto2_bit.pcdto2 = adc_offset_value; + break; + case ADC_PREEMPT_CHANNEL_3: + adc_x->pcdto3_bit.pcdto3 = adc_offset_value; + break; + case ADC_PREEMPT_CHANNEL_4: + adc_x->pcdto4_bit.pcdto4 = adc_offset_value; + break; + default: + break; + } +} + +/** + * @brief set partitioned mode channel count of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param adc_channel_count: configure the adc partitioned mode channel count. + * this parameter can be: + * - (0x1~0x8) + * @retval none + */ +void adc_ordinary_part_count_set(adc_type *adc_x, uint8_t adc_channel_count) +{ + + adc_x->ctrl1_bit.ocpcnt = adc_channel_count - 1; +} + +/** + * @brief enable or disable the partitioned mode on ordinary channel of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param new_state: new state of ordinary channel's partitioned mode. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_ordinary_part_mode_enable(adc_type *adc_x, confirm_state new_state) +{ + adc_x->ctrl1_bit.ocpen = new_state; +} + +/** + * @brief enable or disable the partitioned mode on preempt channel of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param new_state: new state of preempt channel's partitioned mode. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_preempt_part_mode_enable(adc_type *adc_x, confirm_state new_state) +{ + adc_x->ctrl1_bit.pcpen = new_state; +} + +/** + * @brief enable or disable automatic preempt group conversion of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param new_state: new state of automatic preempt group conversion. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_preempt_auto_mode_enable(adc_type *adc_x, confirm_state new_state) +{ + adc_x->ctrl1_bit.pcautoen = new_state; +} + +/** + * @brief enable or disable the temperature sensor and vintrv channel. + * @param new_state: new state of Internal temperature sensor and vintrv. + * this parameter can be: TRUE or FALSE. + * note:this bit is present only in adc1 + * @retval none + */ +void adc_tempersensor_vintrv_enable(confirm_state new_state) +{ + ADC1->ctrl2_bit.itsrven = new_state; +} + +/** + * @brief enable or disable ordinary software start conversion of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param new_state: new state of ordinary software start conversion. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_ordinary_software_trigger_enable(adc_type *adc_x, confirm_state new_state) +{ + adc_x->ctrl2_bit.ocswtrg = new_state; +} + +/** + * @brief get ordinary software start conversion status of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @retval the new state of ordinary software start conversion status(SET or RESET). + */ +flag_status adc_ordinary_software_trigger_status_get(adc_type *adc_x) +{ + if(adc_x->ctrl2_bit.ocswtrg) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief enable or disable preempt software start conversion of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param new_state: new state of preempt software start conversion. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_preempt_software_trigger_enable(adc_type *adc_x, confirm_state new_state) +{ + adc_x->ctrl2_bit.pcswtrg = new_state; +} + +/** + * @brief get preempt software start conversion status of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @retval the new state of preempt software start conversion status(SET or RESET). + */ +flag_status adc_preempt_software_trigger_status_get(adc_type *adc_x) +{ + if(adc_x->ctrl2_bit.pcswtrg) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief return the last conversion data for ordinary channel of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @retval the last conversion data for ordinary channel. + */ +uint16_t adc_ordinary_conversion_data_get(adc_type *adc_x) +{ + return (uint16_t)(adc_x->odt_bit.odt); +} + +/** + * @brief return the last conversion data for ordinary channel of combine adc(adc1 and adc2). + * @retval the last conversion data for ordinary channel. + */ +uint32_t adc_combine_ordinary_conversion_data_get(void) +{ + return (uint32_t)(ADC1->odt); +} + +/** + * @brief return the conversion data for selection preempt channel of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param adc_preempt_channel: select the preempt channel. + * this parameter can be one of the following values: + * - ADC_PREEMPTED_CHANNEL_1 + * - ADC_PREEMPTED_CHANNEL_2 + * - ADC_PREEMPTED_CHANNEL_3 + * - ADC_PREEMPTED_CHANNEL_4 + * @retval the conversion data for selection preempt channel. + */ +uint16_t adc_preempt_conversion_data_get(adc_type *adc_x, adc_preempt_channel_type adc_preempt_channel) +{ + uint16_t preempt_conv_data_index = 0; + switch(adc_preempt_channel) + { + case ADC_PREEMPT_CHANNEL_1: + preempt_conv_data_index = (uint16_t)(adc_x->pdt1_bit.pdt1); + break; + case ADC_PREEMPT_CHANNEL_2: + preempt_conv_data_index = (uint16_t)(adc_x->pdt2_bit.pdt2); + break; + case ADC_PREEMPT_CHANNEL_3: + preempt_conv_data_index = (uint16_t)(adc_x->pdt3_bit.pdt3); + break; + case ADC_PREEMPT_CHANNEL_4: + preempt_conv_data_index = (uint16_t)(adc_x->pdt4_bit.pdt4); + break; + default: + break; + } + return preempt_conv_data_index; +} + +/** + * @brief get flag of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param adc_flag: select the adc flag. + * this parameter can be one of the following values: + * - ADC_VMOR_FLAG + * - ADC_CCE_FLAG + * - ADC_PCCE_FLAG + * - ADC_PCCS_FLAG(no interrupt associated) + * - ADC_OCCS_FLAG(no interrupt associated) + * @retval the new state of adc flag status(SET or RESET). + */ +flag_status adc_flag_get(adc_type *adc_x, uint8_t adc_flag) +{ + flag_status status = RESET; + + if((adc_x->sts & adc_flag) == RESET) + { + status = RESET; + } + else + { + status = SET; + } + return status; +} + +/** + * @brief clear flag of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1, ADC2, ADC3. + * @param adc_flag: select the adc flag. + * this parameter can be any combination of the following values: + * - ADC_VMOR_FLAG + * - ADC_CCE_FLAG(also can clear by reading the adc_x->odt) + * - ADC_PCCE_FLAG + * - ADC_PCCS_FLAG + * - ADC_OCCS_FLAG + * @retval none + */ +void adc_flag_clear(adc_type *adc_x, uint32_t adc_flag) +{ + adc_x->sts = ~adc_flag; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_bpr.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_bpr.c new file mode 100644 index 0000000..08e1922 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_bpr.c @@ -0,0 +1,206 @@ +/** + ************************************************************************** + * @file at32f403a_407_bpr.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the bpr firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup BPR + * @brief BPR driver modules + * @{ + */ + +#ifdef BPR_MODULE_ENABLED + +/** @defgroup BPR_private_functions + * @{ + */ + +/** + * @brief bpr reset by crm reset register + * @param none + * @retval none + */ +void bpr_reset(void) +{ + crm_battery_powered_domain_reset(TRUE); + crm_battery_powered_domain_reset(FALSE); +} + +/** + * @brief bpr event flag get, for tamper event flag + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - BPR_TAMPER_INTERRUPT_FLAG: tamper interrupt flag + * - BPR_TAMPER_EVENT_FLAG: tamper event flag + * @retval state of tamper event flag + */ +flag_status bpr_flag_get(uint32_t flag) +{ + if(flag == BPR_TAMPER_INTERRUPT_FLAG) + { + return (flag_status)(BPR->ctrlsts_bit.tpif); + } + else + { + return (flag_status)(BPR->ctrlsts_bit.tpef); + } +} + +/** + * @brief clear bpr tamper flag + * @param flag: specifies the flag to clear. + * this parameter can be one of the following values: + * - BPR_TAMPER_INTERRUPT_FLAG: tamper interrupt flag + * - BPR_TAMPER_EVENT_FLAG: tamper event flag + * @retval none + */ +void bpr_flag_clear(uint32_t flag) +{ + if(flag == BPR_TAMPER_INTERRUPT_FLAG) + { + BPR->ctrlsts_bit.tpifclr = TRUE; + } + else + { + BPR->ctrlsts_bit.tpefclr = TRUE; + } +} + +/** + * @brief enable or disable bpr tamper interrupt + * @param new_state (TRUE or FALSE) + * @retval none + */ +void bpr_interrupt_enable(confirm_state new_state) +{ + BPR->ctrlsts_bit.tpien = new_state; +} + +/** + * @brief read bpr bpr data + * @param bpr_data + * this parameter can be one of the following values: + * - BPR_DATA1 + * - BPR_DATA2 + * ... + * - BPR_DATA41 + * - BPR_DATA42 + * @retval none + */ +uint16_t bpr_data_read(bpr_data_type bpr_data) +{ + return (*(__IO uint16_t *)(BPR_BASE + bpr_data)); +} + +/** + * @brief write bpr data + * @param bpr_data + * this parameter can be one of the following values: + * - BPR_DATA1 + * - BPR_DATA2 + * ... + * - BPR_DATA41 + * - BPR_DATA42 + * @param data_value (0x0000~0xFFFF) + * @retval none + */ +void bpr_data_write(bpr_data_type bpr_data, uint16_t data_value) +{ + (*(__IO uint32_t *)(BPR_BASE + bpr_data)) = data_value; +} + +/** + * @brief select bpr rtc output + * @param output_source + * this parameter can be one of the following values: + * - BPR_RTC_OUTPUT_NONE: output disable. + * - BPR_RTC_OUTPUT_CLOCK_CAL_BEFORE: output clock before calibration. + * - BPR_RTC_OUTPUT_ALARM: output alarm event with pluse mode. + * - BPR_RTC_OUTPUT_SECOND: output second event with pluse mode. + * - BPR_RTC_OUTPUT_CLOCK_CAL_AFTER: output clock after calibration. + * - BPR_RTC_OUTPUT_ALARM_TOGGLE: output alarm event with toggle mode. + * - BPR_RTC_OUTPUT_SECOND_TOGGLE: output second event with toggle mode. + * @retval none + */ +void bpr_rtc_output_select(bpr_rtc_output_type output_source) +{ + /* clear cco,asoe,asos,ccos,togen bits */ + BPR->rtccal &= (uint32_t)~0x0F80; + + /* set output_source value */ + BPR->rtccal |= output_source; +} + +/** + * @brief set rtc clock calibration value + * @param calibration_value (0x00~0x7f) + * @retval none + */ +void bpr_rtc_clock_calibration_value_set(uint8_t calibration_value) +{ + /* set rtc clock calibration value */ + BPR->rtccal_bit.calval= calibration_value; +} + +/** + * @brief enable or disable bpr tamper pin + * @param new_state (TRUE or FALSE) + * @retval none + */ +void bpr_tamper_pin_enable(confirm_state new_state) +{ + BPR->ctrl_bit.tpen = new_state; +} + +/** + * @brief set bpr tamper pin active level + * @param active_level + * this parameter can be one of the following values: + * - BPR_TAMPER_PIN_ACTIVE_HIGH: tamper pin input active level is high. + * - BPR_TAMPER_PIN_ACTIVE_LOW: tamper pin input active level is low. + * @retval none + */ +void bpr_tamper_pin_active_level_set(bpr_tamper_pin_active_level_type active_level) +{ + BPR->ctrl_bit.tpp = active_level; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_can.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_can.c new file mode 100644 index 0000000..12e4586 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_can.c @@ -0,0 +1,1149 @@ +/** + ************************************************************************** + * @file at32f403a_407_can.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the can firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup CAN + * @brief CAN driver modules + * @{ + */ + +#ifdef CAN_MODULE_ENABLED + +/** @defgroup CAN_private_functions + * @{ + */ + +/** + * @brief deinitialize the can peripheral registers to their default reset values. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1,CAN2. + * @retval none. + */ +void can_reset(can_type* can_x) +{ + if(can_x == CAN1) + { + crm_periph_reset(CRM_CAN1_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_CAN1_PERIPH_RESET, FALSE); + } + else if(can_x == CAN2) + { + crm_periph_reset(CRM_CAN2_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_CAN2_PERIPH_RESET, FALSE); + } +} + +/** + * @brief fill each can_baudrate_struct member with its default value. + * @param can_baudrate_struct: pointer to a can_baudrate_type structure which will be initialized. + * @retval none. + */ +void can_baudrate_default_para_init(can_baudrate_type* can_baudrate_struct) +{ + /* reset can baudrate structure parameters values */ + + /* baud rate division */ + can_baudrate_struct->baudrate_div = 1; + + /* resynchronization adjust width */ + can_baudrate_struct->rsaw_size = CAN_RSAW_2TQ; + + /* bit time segment 1 */ + can_baudrate_struct->bts1_size = CAN_BTS1_4TQ; + + /* bit time segment 2 */ + can_baudrate_struct->bts2_size = CAN_BTS2_3TQ; +} + +/** + * @brief set the baudrate of the can peripheral + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1,CAN2. + * @param can_baudrate_struct: pointer to a can_baudrate_type structure which will be set. + * @note baudrate calculate method is: + * baudrate = fpclk/(baudrate_div *(3 + bts1_size + bts2_size)) + * @retval the result of baudrate set + * this parameter can be one of the following values: + * SUCCESS or ERROR + */ +error_status can_baudrate_set(can_type* can_x, can_baudrate_type* can_baudrate_struct) +{ + error_status status_index = ERROR; + uint32_t wait_ack_index = 0x00000000; + /* exit from doze mode */ + can_x->mctrl_bit.dzen = FALSE; + + /* request freeze mode */ + can_x->mctrl_bit.fzen = TRUE; + + /* wait the acknowledge */ + while((!can_x->msts_bit.fzc) && (wait_ack_index != FZC_TIMEOUT)) + { + wait_ack_index++; + } + + /* check acknowledge */ + if(can_x->msts_bit.fzc) + { + can_x->btmg_bit.brdiv = can_baudrate_struct->baudrate_div - 1; + can_x->btmg_bit.rsaw = can_baudrate_struct->rsaw_size; + can_x->btmg_bit.bts1 = can_baudrate_struct->bts1_size; + can_x->btmg_bit.bts2 = can_baudrate_struct->bts2_size; + + /* request leave freeze mode */ + can_x->mctrl_bit.fzen = FALSE; + + /* wait the acknowledge */ + wait_ack_index = 0; + while((can_x->msts_bit.fzc) && (wait_ack_index != FZC_TIMEOUT)) + { + wait_ack_index++; + } + + /* check acknowledged */ + if(can_x->msts_bit.fzc) + { + status_index = ERROR; + } + else + { + status_index = SUCCESS ; + } + } + else + { + status_index = ERROR; + } + + /* return the status of baudrate set */ + return status_index; +} + +/** + * @brief fill each can_init_struct member with its default value. + * @param can_base_struct: pointer to a can_base_type structure which will be initialized. + * @retval none. + */ +void can_default_para_init(can_base_type* can_base_struct) +{ + /* reset can init structure parameters values */ + + /* initialize the time triggered communication mode */ + can_base_struct->ttc_enable = FALSE; + + /* initialize the automatic exit bus-off management */ + can_base_struct->aebo_enable = FALSE; + + /* initialize the automatic exit doze mode */ + can_base_struct->aed_enable = FALSE; + + /* initialize the prohibit retransmission when sending fails */ + can_base_struct->prsf_enable = FALSE; + + /* initialize the message discarding rule select when overflow */ + can_base_struct->mdrsel_selection = CAN_DISCARDING_FIRST_RECEIVED; + + /* initialize the multiple message sending sequence rule */ + can_base_struct->mmssr_selection = CAN_SENDING_BY_ID; + + /* initialize the can_mode */ + can_base_struct->mode_selection = CAN_MODE_COMMUNICATE; +} + +/** + * @brief initialize the can peripheral according to the specified + * parameters in the can_init_struct. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1,CAN2. + * @param can_base_struct: pointer to a can_base_struct structure that contains the configuration information for the can peripheral. + * @retval the status of initialization + * this parameter can be one of the following values: + * SUCCESS or ERROR + */ +error_status can_base_init(can_type* can_x, can_base_type* can_base_struct) +{ + error_status init_status_index = ERROR; + uint32_t wait_ack_index = 0x00000000; + /* exit from doze mode */ + can_x->mctrl_bit.dzen = FALSE; + + /* request freeze mode */ + can_x->mctrl_bit.fzen = TRUE; + + /* wait the acknowledge */ + while((!can_x->msts_bit.fzc) && (wait_ack_index != FZC_TIMEOUT)) + { + wait_ack_index++; + } + + /* check acknowledge */ + if(can_x->msts_bit.fzc) + { + /* set the time triggered communication mode */ + can_x->mctrl_bit.ttcen = can_base_struct->ttc_enable; + + /* set the automatic exit bus-off management */ + can_x->mctrl_bit.aeboen = can_base_struct->aebo_enable; + + /* set the automatic automatic exit doze mode */ + can_x->mctrl_bit.aeden = can_base_struct->aed_enable; + + /* set the prohibit retransmission when sending fails */ + can_x->mctrl_bit.prsfen = can_base_struct->prsf_enable; + + /* set the message discarding rule select when overflow */ + can_x->mctrl_bit.mdrsel = can_base_struct->mdrsel_selection; + + /* set the multiple message sending sequence rule */ + can_x->mctrl_bit.mmssr = can_base_struct->mmssr_selection; + + /* set the test mode */ + can_x->btmg_bit.lben = can_base_struct->mode_selection & 0x01; + can_x->btmg_bit.loen = (can_base_struct->mode_selection >> 1) & 0x01; + + /* request leave freeze mode */ + can_x->mctrl_bit.fzen = FALSE; + + /* wait the acknowledge */ + wait_ack_index = 0; + while((can_x->msts_bit.fzc) && (wait_ack_index != FZC_TIMEOUT)) + { + wait_ack_index++; + } + + /* check acknowledged */ + if(can_x->msts_bit.fzc) + { + init_status_index = ERROR; + } + else + { + init_status_index = SUCCESS ; + } + } + else + { + init_status_index = ERROR; + } + + /* return the status of initialization */ + return init_status_index; +} + +/** + * @brief fill each can_filter_init_struct member with its default value. + * @param can_filter_init_struct: pointer to a can_filter_init_type structure which will be initialized. + * @retval none. + */ +void can_filter_default_para_init(can_filter_init_type* can_filter_init_struct) +{ + /* reset can filter init structure parameters values */ + + /* initialize the filter activate state */ + can_filter_init_struct->filter_activate_enable = FALSE; + + /* filter mode */ + can_filter_init_struct->filter_mode = CAN_FILTER_MODE_ID_MASK; + + /* filter relation fifo select */ + can_filter_init_struct->filter_fifo = CAN_FILTER_FIFO0; + + /* filter number select */ + can_filter_init_struct->filter_number = 0; + + /* initialize the filter bit width */ + can_filter_init_struct->filter_bit = CAN_FILTER_16BIT; + + /* initialize the filters filter data bit */ + can_filter_init_struct->filter_id_high = 0; + can_filter_init_struct->filter_id_low = 0; + can_filter_init_struct->filter_mask_high = 0; + can_filter_init_struct->filter_mask_low = 0; +} + +/** + * @brief initialize the can peripheral according to the specified + * parameters in the can_filter_init_struct. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1,CAN2. + * @param can_filter_init_struct: pointer to a can_filter_init_type structure that contains the configuration information. + * @retval none. + */ +void can_filter_init(can_type* can_x, can_filter_init_type* can_filter_init_struct) +{ + uint32_t filter_number_bit_pos = 0; + filter_number_bit_pos = ((uint32_t)1) << can_filter_init_struct->filter_number; + /* set the filter turn into configuration condition */ + can_x->fctrl_bit.fcs = TRUE; + + /* filter activate disable */ + can_x->facfg &= ~(uint32_t)filter_number_bit_pos; + + /* filter bit width */ + switch(can_filter_init_struct->filter_bit) + { + case CAN_FILTER_16BIT: + can_x->fbwcfg &= ~(uint32_t)filter_number_bit_pos; + /* first 16-bit identifier and first 16-bit mask or first 16-bit identifier and second 16-bit identifier */ + can_x->ffb[can_filter_init_struct->filter_number].ffdb1 = ((0x0000FFFF & (uint32_t)can_filter_init_struct->filter_mask_low) << 16); + can_x->ffb[can_filter_init_struct->filter_number].ffdb1 |= (0x0000FFFF & (uint32_t)can_filter_init_struct->filter_id_low); + + /* second 16-bit identifier and second 16-bit mask or third 16-bit identifier and fourth 16-bit identifier */ + can_x->ffb[can_filter_init_struct->filter_number].ffdb2 = ((0x0000FFFF & (uint32_t)can_filter_init_struct->filter_mask_high) << 16); + can_x->ffb[can_filter_init_struct->filter_number].ffdb2 |= (0x0000FFFF & (uint32_t)can_filter_init_struct->filter_id_high); + + break; + case CAN_FILTER_32BIT: + can_x->fbwcfg |= filter_number_bit_pos; + /* 32-bit identifier or first 32-bit identifier */ + can_x->ffb[can_filter_init_struct->filter_number].ffdb1 = ((0x0000FFFF & (uint32_t)can_filter_init_struct->filter_id_high) << 16); + can_x->ffb[can_filter_init_struct->filter_number].ffdb1 |= (0x0000FFFF & (uint32_t)can_filter_init_struct->filter_id_low); + + /* 32-bit mask or second 32-bit identifier */ + can_x->ffb[can_filter_init_struct->filter_number].ffdb2 = ((0x0000FFFF & (uint32_t)can_filter_init_struct->filter_mask_high) << 16); + can_x->ffb[can_filter_init_struct->filter_number].ffdb2 |= (0x0000FFFF & (uint32_t)can_filter_init_struct->filter_mask_low); + + break; + default: + break; + } + + /* filter mode */ + switch(can_filter_init_struct->filter_mode) + { + case CAN_FILTER_MODE_ID_MASK: + can_x->fmcfg &= ~(uint32_t)filter_number_bit_pos; + break; + case CAN_FILTER_MODE_ID_LIST: + can_x->fmcfg |= (uint32_t)filter_number_bit_pos; + break; + default: + break; + } + + /* filter relation fifo select */ + switch(can_filter_init_struct->filter_fifo) + { + case CAN_FILTER_FIFO0: + can_x->frf &= ~(uint32_t)filter_number_bit_pos; + break; + case CAN_FILTER_FIFO1: + can_x->frf |= (uint32_t)filter_number_bit_pos; + break; + default: + break; + } + + /* filter activate enable */ + switch(can_filter_init_struct->filter_activate_enable) + { + case TRUE: + can_x->facfg |= (uint32_t)filter_number_bit_pos; + break; + case FALSE: + can_x->facfg &= ~(uint32_t)filter_number_bit_pos; + break; + default: + break; + } + + /* set the filter turn into working condition */ + can_x->fctrl_bit.fcs = FALSE; +} + +/** + * @brief enable or disable the debug transmission prohibit of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1,CAN2. + * @param new_state: new state of debug transmission prohibit. + * this parameter can be: TRUE or FALSE. + * @retval none. + */ +void can_debug_transmission_prohibit(can_type* can_x, confirm_state new_state) +{ + can_x->mctrl_bit.ptd = new_state; +} + +/** + * @brief enable or disable time trigger operation communication mode of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1 or CAN2. + * @param new_state : new state of time trigger operation communication mode. + * this parameter can be: TRUE or FALSE. + * @note + * note1: + * when enabled, transmit mailbox time stamp(tmts[15:0]) value is sent in the last two data bytes of + * the 8-byte message: tmts[7:0] in data byte 6 and tmts[15:8] in data byte 7 + * @note + * note2: + * tmdtbl must be programmed as 8 in order time stamp (2 bytes) to be sent over the can bus. + * @retval none + */ +void can_ttc_mode_enable(can_type* can_x, confirm_state new_state) +{ + /* config the ttc mode new_state */ + can_x->mctrl_bit.ttcen = new_state; + + /* config tmtsten bits new_state */ + can_x->tx_mailbox[0].tmc_bit.tmtsten = new_state; + can_x->tx_mailbox[1].tmc_bit.tmtsten = new_state; + can_x->tx_mailbox[2].tmc_bit.tmtsten = new_state; +} + +/** + * @brief fill the transmission message and transmit of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1,CAN2. + * @param tx_message_struct: pointer to a structure which contains the message to be trans. + * @retval the number of the mailbox that is used for transmission: + * this parameter can be one of the following values: + * - CAN_TX_MAILBOX0 + * - CAN_TX_MAILBOX1 + * - CAN_TX_MAILBOX2 + * - CAN_TX_STATUS_NO_EMPTY + */ +uint8_t can_message_transmit(can_type* can_x, can_tx_message_type* tx_message_struct) +{ + uint8_t transmit_mailbox = CAN_TX_STATUS_NO_EMPTY; + + /* select one empty transmit mailbox */ + if(can_x->tsts_bit.tm0ef) + { + transmit_mailbox = CAN_TX_MAILBOX0; + } + else if(can_x->tsts_bit.tm1ef) + { + transmit_mailbox = CAN_TX_MAILBOX1; + } + else if(can_x->tsts_bit.tm2ef) + { + transmit_mailbox = CAN_TX_MAILBOX2; + } + else + { + transmit_mailbox = CAN_TX_STATUS_NO_EMPTY; + } + + if(transmit_mailbox != CAN_TX_STATUS_NO_EMPTY) + { + /* set up the id */ + can_x->tx_mailbox[transmit_mailbox].tmi &= 0x00000001; + can_x->tx_mailbox[transmit_mailbox].tmi_bit.tmidsel = tx_message_struct->id_type; + switch(tx_message_struct->id_type) + { + case CAN_ID_STANDARD: + can_x->tx_mailbox[transmit_mailbox].tmi_bit.tmsid = tx_message_struct->standard_id; + break; + case CAN_ID_EXTENDED: + can_x->tx_mailbox[transmit_mailbox].tmi |= (tx_message_struct->extended_id << 3); + break; + default: + break; + } + can_x->tx_mailbox[transmit_mailbox].tmi_bit.tmfrsel = tx_message_struct->frame_type; + /* set up the dlc */ + can_x->tx_mailbox[transmit_mailbox].tmc_bit.tmdtbl = (tx_message_struct->dlc & ((uint8_t)0x0F)); + + /* set up the data field */ + can_x->tx_mailbox[transmit_mailbox].tmdtl = (((uint32_t)tx_message_struct->data[3] << 24) | + ((uint32_t)tx_message_struct->data[2] << 16) | + ((uint32_t)tx_message_struct->data[1] << 8) | + ((uint32_t)tx_message_struct->data[0])); + can_x->tx_mailbox[transmit_mailbox].tmdth = (((uint32_t)tx_message_struct->data[7] << 24) | + ((uint32_t)tx_message_struct->data[6] << 16) | + ((uint32_t)tx_message_struct->data[5] << 8) | + ((uint32_t)tx_message_struct->data[4])); + + /* request transmission */ + can_x->tx_mailbox[transmit_mailbox].tmi_bit.tmsr = TRUE; + } + return transmit_mailbox; +} + +/** + * @brief check the transmission state of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1 or CAN2. + * @param transmit_mailbox: the number of the mailbox that is used for transmission. + * this parameter can be one of the following values: + * - CAN_TX_MAILBOX0 + * - CAN_TX_MAILBOX1 + * - CAN_TX_MAILBOX2 + * @retval can transmit status + * this parameter can be one of the following values: + * - CAN_TX_STATUS_SUCCESSFUL + * - CAN_TX_STATUS_FAILED + * - CAN_TX_STATUS_PENDING + */ +can_transmit_status_type can_transmit_status_get(can_type* can_x, can_tx_mailbox_num_type transmit_mailbox) +{ + can_transmit_status_type state_index = CAN_TX_STATUS_FAILED; + switch(transmit_mailbox) + { + case CAN_TX_MAILBOX0: + if(can_x->tsts_bit.tm0tcf != RESET) + { + if(can_x->tsts_bit.tm0tsf != RESET) + { + state_index = CAN_TX_STATUS_SUCCESSFUL; + } + else + { + state_index = CAN_TX_STATUS_FAILED; + } + } + else + { + state_index = CAN_TX_STATUS_PENDING; + } + break; + case CAN_TX_MAILBOX1: + if(can_x->tsts_bit.tm1tcf != RESET) + { + if(can_x->tsts_bit.tm1tsf != RESET) + { + state_index = CAN_TX_STATUS_SUCCESSFUL; + } + else + { + state_index = CAN_TX_STATUS_FAILED; + } + } + else + { + state_index = CAN_TX_STATUS_PENDING; + } + break; + case CAN_TX_MAILBOX2: + if(can_x->tsts_bit.tm2tcf != RESET) + { + if(can_x->tsts_bit.tm2tsf != RESET) + { + state_index = CAN_TX_STATUS_SUCCESSFUL; + } + else + { + state_index = CAN_TX_STATUS_FAILED; + } + } + else + { + state_index = CAN_TX_STATUS_PENDING; + } + break; + default: + state_index = CAN_TX_STATUS_FAILED; + break; + } + return state_index; +} + +/** + * @brief cancel a transmit request of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1 or CAN2. + * @param mailbox: mailbox number. + * this parameter can be one of the following values: + * - CAN_TX_MAILBOX0 + * - CAN_TX_MAILBOX1 + * - CAN_TX_MAILBOX2 + * @retval none. + */ +void can_transmit_cancel(can_type* can_x, can_tx_mailbox_num_type transmit_mailbox) +{ + switch (transmit_mailbox) + { + case CAN_TX_MAILBOX0: + can_x->tsts = CAN_TSTS_TM0CT_VAL; + break; + case CAN_TX_MAILBOX1: + can_x->tsts = CAN_TSTS_TM1CT_VAL; + break; + case CAN_TX_MAILBOX2: + can_x->tsts = CAN_TSTS_TM2CT_VAL; + + break; + default: + break; + } +} + +/** + * @brief receive message of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1,CAN2. + * @param fifo_number: receive fifo number. + * this parameter can be one of the following values: + * - CAN_RX_FIFO0 + * - CAN_RX_FIFO1 + * @param rx_message_struct: pointer to a structure which store the receive message. + * @retval none. + */ +void can_message_receive(can_type* can_x, can_rx_fifo_num_type fifo_number, can_rx_message_type* rx_message_struct) +{ + /* get the id type */ + rx_message_struct->id_type = (can_identifier_type)can_x->fifo_mailbox[fifo_number].rfi_bit.rfidi; + switch (rx_message_struct->id_type) + { + case CAN_ID_STANDARD: + rx_message_struct->standard_id = can_x->fifo_mailbox[fifo_number].rfi_bit.rfsid; + break; + case CAN_ID_EXTENDED: + rx_message_struct->extended_id = 0x1FFFFFFF & (can_x->fifo_mailbox[fifo_number].rfi >> 3); + break; + default: + break; + } + rx_message_struct->frame_type = (can_trans_frame_type)can_x->fifo_mailbox[fifo_number].rfi_bit.rffri; + /* get the dlc */ + rx_message_struct->dlc = can_x->fifo_mailbox[fifo_number].rfc_bit.rfdtl; + + /* get the filter match number */ + rx_message_struct->filter_index = can_x->fifo_mailbox[fifo_number].rfc_bit.rffmn; + + /* get the data field */ + rx_message_struct->data[0] = can_x->fifo_mailbox[fifo_number].rfdtl_bit.rfdt0; + rx_message_struct->data[1] = can_x->fifo_mailbox[fifo_number].rfdtl_bit.rfdt1; + rx_message_struct->data[2] = can_x->fifo_mailbox[fifo_number].rfdtl_bit.rfdt2; + rx_message_struct->data[3] = can_x->fifo_mailbox[fifo_number].rfdtl_bit.rfdt3; + rx_message_struct->data[4] = can_x->fifo_mailbox[fifo_number].rfdth_bit.rfdt4; + rx_message_struct->data[5] = can_x->fifo_mailbox[fifo_number].rfdth_bit.rfdt5; + rx_message_struct->data[6] = can_x->fifo_mailbox[fifo_number].rfdth_bit.rfdt6; + rx_message_struct->data[7] = can_x->fifo_mailbox[fifo_number].rfdth_bit.rfdt7; + + /* release the fifo */ + can_receive_fifo_release(can_x, fifo_number); +} + +/** + * @brief release the specified fifo of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1,CAN2. + * @param fifo_number: fifo to be release. + * this parameter can be one of the following values: + * - CAN_RX_FIFO0 + * - CAN_RX_FIFO1 + * @retval none. + */ +void can_receive_fifo_release(can_type* can_x, can_rx_fifo_num_type fifo_number) +{ + switch (fifo_number) + { + case CAN_RX_FIFO0: + can_x->rf0 = CAN_RF0_RF0R_VAL; + break; + case CAN_RX_FIFO1: + can_x->rf1 = CAN_RF1_RF1R_VAL; + break; + default: + break; + } +} + +/** + * @brief return the number of pending messages of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1,CAN2. + * @param fifo_number: receive fifo number. + * this parameter can be one of the following values: + * - CAN_RX_FIFO0 + * - CAN_RX_FIFO1 + * @retval the number of message pending in the receive fifo. + */ +uint8_t can_receive_message_pending_get(can_type* can_x, can_rx_fifo_num_type fifo_number) +{ + uint8_t message_pending = 0; + switch (fifo_number) + { + case CAN_RX_FIFO0: + message_pending = can_x->rf0_bit.rf0mn; + break; + case CAN_RX_FIFO1: + message_pending = can_x->rf1_bit.rf1mn; + break; + default: + break; + } + return message_pending; +} + +/** + * @brief set the operation mode of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1,CAN2. + * @param can_operating_mode: can operating mode. + * this parameter can be one of the following values: + * - CAN_OPERATINGMODE_FREEZE + * - CAN_OPERATINGMODE_DOZE + * - CAN_OPERATINGMODE_COMMUNICATE + * @retval status of operation mode set + * this parameter can be one of the following values: + * SUCCESS or ERROR + */ +error_status can_operating_mode_set(can_type* can_x, can_operating_mode_type can_operating_mode) +{ + error_status status = ERROR; + uint32_t time_out_index = FZC_TIMEOUT; + + if (can_operating_mode == CAN_OPERATINGMODE_FREEZE) + { + /* request enter freeze mode */ + can_x->mctrl_bit.dzen = FALSE; + can_x->mctrl_bit.fzen = TRUE; + + while(((can_x->msts_bit.dzc) || (!can_x->msts_bit.fzc)) && (time_out_index != 0)) + { + time_out_index--; + } + if((can_x->msts_bit.dzc) || (!can_x->msts_bit.fzc)) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + } + else if(can_operating_mode == CAN_OPERATINGMODE_DOZE) + { + /* request enter doze mode */ + can_x->mctrl_bit.dzen = TRUE; + can_x->mctrl_bit.fzen = FALSE; + + while(((!can_x->msts_bit.dzc) || (can_x->msts_bit.fzc)) && (time_out_index != 0)) + { + time_out_index--; + } + if((!can_x->msts_bit.dzc) || (can_x->msts_bit.fzc)) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + } + else if(can_operating_mode == CAN_OPERATINGMODE_COMMUNICATE) + { + /* request enter normal mode */ + can_x->mctrl_bit.dzen = FALSE; + can_x->mctrl_bit.fzen = FALSE; + + while(((can_x->msts_bit.dzc) || (can_x->msts_bit.fzc)) && (time_out_index != 0)) + { + time_out_index--; + } + if((can_x->msts_bit.dzc) || (can_x->msts_bit.fzc)) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + } + else + { + status = ERROR; + } + return status; +} + +/** + * @brief enter the low power mode of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1,CAN2. + * @retval status of doze mode enter, the returned value can be: + * - CAN_ENTER_DOZE_SUCCESSFUL + * - CAN_ENTER_DOZE_FAILED + */ +can_enter_doze_status_type can_doze_mode_enter(can_type* can_x) +{ + can_enter_doze_status_type status = CAN_ENTER_DOZE_FAILED; + uint32_t time_out_index = FZC_TIMEOUT; + can_x->mctrl_bit.fzen = FALSE; + can_x->mctrl_bit.dzen = TRUE; + while(((!can_x->msts_bit.dzc) || (can_x->msts_bit.fzc)) && (time_out_index != 0)) + { + time_out_index--; + } + if((!can_x->msts_bit.dzc) || (can_x->msts_bit.fzc)) + { + status = CAN_ENTER_DOZE_FAILED; + } + else + { + status = CAN_ENTER_DOZE_SUCCESSFUL; + } + return status; +} + +/** + * @brief exit the doze mode of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1,CAN2. + * @retval status of doze mode enter, the returned value can be: + * - CAN_QUIT_DOZE_SUCCESSFUL + * - CAN_QUIT_DOZE_FAILED + */ +can_quit_doze_status_type can_doze_mode_exit(can_type* can_x) +{ + can_quit_doze_status_type status = CAN_QUIT_DOZE_FAILED; + uint32_t time_out_index = DZC_TIMEOUT; + can_x->mctrl_bit.dzen = FALSE; + while((can_x->msts_bit.dzc) && (time_out_index != 0)) + { + time_out_index--; + } + if(!can_x->msts_bit.dzc) + { + status = CAN_QUIT_DOZE_SUCCESSFUL; + } + return status; +} + +/** + * @brief return the error type record (etr) of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1,CAN2. + * @retval the value of the error code + * the return can be one of the follow values: + * - CAN_ERRORRECORD_NOERR + * - CAN_ERRORRECORD_STUFFERR, + * - CAN_ERRORRECORD_FORMERR, + * - CAN_ERRORRECORD_ACKERR, + * - CAN_ERRORRECORD_BITRECESSIVEERR, + * - CAN_ERRORRECORD_BITDOMINANTERR, + * - CAN_ERRORRECORD_CRCERR, + * - CAN_ERRORRECORD_SOFTWARESETERR + */ +can_error_record_type can_error_type_record_get(can_type* can_x) +{ + can_error_record_type error_code = CAN_ERRORRECORD_NOERR; + + error_code = (can_error_record_type)can_x->ests_bit.etr; + return error_code; +} + +/** + * @brief return the receive error counter (rec) of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1,CAN2. + * @retval the value of receive error counter. + */ +uint8_t can_receive_error_counter_get(can_type* can_x) +{ + uint8_t counter = 0; + counter = can_x->ests_bit.rec; + return counter; +} + +/** + * @brief return the transmit error counter of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1,CAN2. + * @retval the value of transmit error counter. + */ +uint8_t can_transmit_error_counter_get(can_type* can_x) +{ + uint8_t counter = 0; + counter = can_x->ests_bit.tec; + return counter; +} + +/** + * @brief enable or disable the interrupt of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1,CAN2. + * @param can_int: specifies the can interrupt sources to be enabled or disabled. + * this parameter can be one of the following values: + * - CAN_TCIEN_INT + * - CAN_RF0MIEN_INT + * - CAN_RF0FIEN_INT + * - CAN_RF0OIEN_INT + * - CAN_RF1MIEN_INT + * - CAN_RF1FIEN_INT + * - CAN_RF1OIEN_INT + * - CAN_EAIEN_INT + * - CAN_EPIEN_INT + * - CAN_BOIEN_INT + * - CAN_ETRIEN_INT + * - CAN_EOIEN_INT + * - CAN_QDZIEN_INT + * - CAN_EDZIEN_INT + * @param new_state: new state of the can interrupts. + * this parameter can be: TRUE or FALSE. + * @retval none. + */ +void can_interrupt_enable(can_type* can_x, uint32_t can_int, confirm_state new_state) +{ + if (new_state != FALSE) + { + can_x->inten |= can_int; + } + else + { + can_x->inten &= ~can_int; + } +} + +/** + * @brief get flag of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1,CAN2. + * @param can_flag: select the flag. + * this parameter can be one of the following flags: + * - CAN_EAF_FLAG + * - CAN_EPF_FLAG + * - CAN_BOF_FLAG + * - CAN_ETR_FLAG + * - CAN_EOIF_FLAG + * - CAN_TM0TCF_FLAG + * - CAN_TM1TCF_FLAG + * - CAN_TM2TCF_FLAG + * - CAN_RF0MN_FLAG + * - CAN_RF0FF_FLAG + * - CAN_RF0OF_FLAG + * - CAN_RF1MN_FLAG + * - CAN_RF1FF_FLAG + * - CAN_RF1OF_FLAG + * - CAN_QDZIF_FLAG + * - CAN_EDZC_FLAG + * - CAN_TMEF_FLAG + * note:the state of CAN_EDZC_FLAG need to check dzc and edzif bit + * note:the state of CAN_TMEF_FLAG need to check rqc0,rqc1 and rqc2 bit + * @retval status of can_flag, the returned value can be:SET or RESET. + */ +flag_status can_flag_get(can_type* can_x, uint32_t can_flag) +{ + flag_status bit_status = RESET; + switch(can_flag) + { + case CAN_EAF_FLAG: + bit_status = (flag_status)can_x->ests_bit.eaf; + break; + case CAN_EPF_FLAG: + bit_status = (flag_status)can_x->ests_bit.epf; + break; + case CAN_BOF_FLAG: + bit_status = (flag_status)can_x->ests_bit.bof; + break; + case CAN_ETR_FLAG: + if(can_x->ests_bit.etr != 0) + { + bit_status = SET; + } + else + { + bit_status = RESET; + } + break; + case CAN_EOIF_FLAG: + bit_status = (flag_status)can_x->msts_bit.eoif; + break; + case CAN_TM0TCF_FLAG: + bit_status = (flag_status)can_x->tsts_bit.tm0tcf; + break; + case CAN_TM1TCF_FLAG: + bit_status = (flag_status)can_x->tsts_bit.tm1tcf; + break; + case CAN_TM2TCF_FLAG: + bit_status = (flag_status)can_x->tsts_bit.tm2tcf; + break; + case CAN_RF0MN_FLAG: + if(can_x->rf0_bit.rf0mn != 0) + { + bit_status = SET; + } + else + { + bit_status = RESET; + } + break; + case CAN_RF0FF_FLAG: + bit_status = (flag_status)can_x->rf0_bit.rf0ff; + break; + case CAN_RF0OF_FLAG: + bit_status = (flag_status)can_x->rf0_bit.rf0of; + break; + case CAN_RF1MN_FLAG: + if(can_x->rf1_bit.rf1mn != 0) + { + bit_status = SET; + } + else + { + bit_status = RESET; + } + break; + case CAN_RF1FF_FLAG: + bit_status = (flag_status)can_x->rf1_bit.rf1ff; + break; + case CAN_RF1OF_FLAG: + bit_status = (flag_status)can_x->rf1_bit.rf1of; + break; + case CAN_QDZIF_FLAG: + bit_status = (flag_status)can_x->msts_bit.qdzif; + break; + case CAN_EDZC_FLAG: + if((can_x->msts_bit.dzc != RESET) ||(can_x->msts_bit.edzif != RESET)) + { + bit_status = SET; + } + else + { + bit_status = RESET; + } + break; + case CAN_TMEF_FLAG: + if((can_x->tsts_bit.tm0ef != RESET) || (can_x->tsts_bit.tm1ef != RESET) || (can_x->tsts_bit.tm2ef != RESET)) + { + bit_status = SET; + } + else + { + bit_status = RESET; + } + break; + default: + bit_status = RESET; + break; + } + return bit_status; +} + +/** + * @brief clear flag of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1,CAN2. + * @param can_flag: select the flag. + * this parameter can be one of the following flags: + * - CAN_EAF_FLAG + * - CAN_EPF_FLAG + * - CAN_BOF_FLAG + * - CAN_ETR_FLAG + * - CAN_EOIF_FLAG + * - CAN_TM0TCF_FLAG + * - CAN_TM1TCF_FLAG + * - CAN_TM2TCF_FLAG + * - CAN_RF0FF_FLAG + * - CAN_RF0OF_FLAG + * - CAN_RF1FF_FLAG + * - CAN_RF1OF_FLAG + * - CAN_QDZIF_FLAG + * - CAN_EDZC_FLAG + * - CAN_TMEF_FLAG + * note:CAN_RF0MN_FLAG and CAN_RF1MN_FLAG can not clear by this function + * @retval none. + */ +void can_flag_clear(can_type* can_x, uint32_t can_flag) +{ + switch(can_flag) + { + case CAN_EAF_FLAG: + case CAN_EPF_FLAG: + case CAN_BOF_FLAG: + case CAN_EOIF_FLAG: + can_x->msts = CAN_MSTS_EOIF_VAL; + break; + case CAN_ETR_FLAG: + can_x->msts = CAN_MSTS_EOIF_VAL; + can_x->ests = 0; + break; + case CAN_TM0TCF_FLAG: + can_x->tsts = CAN_TSTS_TM0TCF_VAL; + break; + case CAN_TM1TCF_FLAG: + can_x->tsts = CAN_TSTS_TM1TCF_VAL; + break; + case CAN_TM2TCF_FLAG: + can_x->tsts = CAN_TSTS_TM2TCF_VAL; + break; + case CAN_RF0FF_FLAG: + can_x->rf0 = CAN_RF0_RF0FF_VAL; + break; + case CAN_RF0OF_FLAG: + can_x->rf0 = CAN_RF0_RF0OF_VAL; + break; + case CAN_RF1FF_FLAG: + can_x->rf1 = CAN_RF1_RF1FF_VAL; + break; + case CAN_RF1OF_FLAG: + can_x->rf1 = CAN_RF1_RF1OF_VAL; + break; + case CAN_QDZIF_FLAG: + can_x->msts = CAN_MSTS_QDZIF_VAL; + break; + case CAN_EDZC_FLAG: + can_x->msts = CAN_MSTS_EDZIF_VAL; + break; + case CAN_TMEF_FLAG: + can_x->tsts = CAN_TSTS_TM0TCF_VAL | CAN_TSTS_TM1TCF_VAL | CAN_TSTS_TM2TCF_VAL; + break; + default: + break; + } +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_crc.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_crc.c new file mode 100644 index 0000000..aa81315 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_crc.c @@ -0,0 +1,164 @@ +/** + ************************************************************************** + * @file at32f403a_407_crc.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the crc firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup CRC + * @brief CRC driver modules + * @{ + */ + +#ifdef CRC_MODULE_ENABLED + +/** @defgroup CRC_private_functions + * @{ + */ + +/** + * @brief reset the crc data register. + * @param none + * @retval none + */ +void crc_data_reset(void) +{ + /* reset crc generator */ + CRC->ctrl_bit.rst = 0x1; +} + +/** + * @brief compute the 32-bit crc of a given data word(32-bit). + * @param data: data word(32-bit) to compute its crc + * @retval 32-bit crc + */ +uint32_t crc_one_word_calculate(uint32_t data) +{ + CRC->dt = data; + return (CRC->dt); +} + +/** + * @brief compute the 32-bit crc of a given buffer of data word(32-bit). + * @param pbuffer: pointer to the buffer containing the data to be computed + * @param length: length of the buffer to be computed + * @retval 32-bit crc + */ +uint32_t crc_block_calculate(uint32_t *pbuffer, uint32_t length) +{ + uint32_t index = 0; + + for(index = 0; index < length; index++) + { + CRC->dt = pbuffer[index]; + } + + return (CRC->dt); +} + +/** + * @brief return the current crc value. + * @param none + * @retval 32-bit crc + */ +uint32_t crc_data_get(void) +{ + return (CRC->dt); +} + +/** + * @brief store a 8-bit data in the common data register. + * @param cdt_value: 8-bit value to be stored in the common data register + * @retval none + */ +void crc_common_data_set(uint8_t cdt_value) +{ + CRC->cdt_bit.cdt = cdt_value; +} + +/** + * @brief return the 8-bit data stored in the common data register + * @param none + * @retval 8-bit value of the common data register + */ +uint8_t crc_common_date_get(void) +{ + return (CRC->cdt_bit.cdt); +} + +/** + * @brief set the 32-bit initial data of crc + * @param value: initial data + * @retval none + */ +void crc_init_data_set(uint32_t value) +{ + CRC->idt = value; +} + +/** + * @brief control the reversal of the bit order in the input data + * @param value + * this parameter can be one of the following values: + * - CRC_REVERSE_INPUT_NO_AFFECTE + * - CRC_REVERSE_INPUT_BY_BYTE + * - CRC_REVERSE_INPUT_BY_HALFWORD + * - CRC_REVERSE_INPUT_BY_WORD + * @retval none. + */ +void crc_reverse_input_data_set(crc_reverse_input_type value) +{ + CRC->ctrl_bit.revid = value; +} + +/** + * @brief control the reversal of the bit order in the output data + * @param value + * this parameter can be one of the following values: + * - CRC_REVERSE_OUTPUT_NO_AFFECTE + * - CRC_REVERSE_OUTPUT_DATA + * @retval none. + */ +void crc_reverse_output_data_set(crc_reverse_output_type value) +{ + CRC->ctrl_bit.revod = value; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_crm.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_crm.c new file mode 100644 index 0000000..c3ea29c --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_crm.c @@ -0,0 +1,860 @@ +/** + ************************************************************************** + * @file at32f403a_407_crm.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the crm firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup CRM + * @brief CRM driver modules + * @{ + */ + +#ifdef CRM_MODULE_ENABLED + +/** @defgroup CRM_private_functions + * @{ + */ + +/** + * @brief reset the crm register + * @param none + * @retval none + */ +void crm_reset(void) +{ + /* reset the crm clock configuration to the default reset state(for debug purpose) */ + /* set hicken bit */ + CRM->ctrl_bit.hicken = TRUE; + + /* wait hick stable */ + while(CRM->ctrl_bit.hickstbl != SET); + + /* hick used as system clock */ + CRM->cfg_bit.sclksel = CRM_SCLK_HICK; + + /* wait sclk switch status */ + while(CRM->cfg_bit.sclksts != CRM_SCLK_HICK); + + /* reset cfg register, include sclk switch, ahbdiv, apb1div, apb2div, adcdiv, + clkout pllrcs, pllhextdiv, pllmult, usbdiv and pllrange bits */ + CRM->cfg = 0; + + /* reset hexten, hextbyps, cfden and pllen bits */ + CRM->ctrl &= ~(0x010D0000U); + + /* reset clkout[3], usbbufs, hickdiv, clkoutdiv */ + CRM->misc1 = 0; + + /* disable all interrupts enable and clear pending bits */ + CRM->clkint = 0x009F0000; +} + +/** + * @brief enable or disable crm low speed external crystal bypass + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_lext_bypass(confirm_state new_state) +{ + CRM->bpdc_bit.lextbyps = new_state; +} + +/** + * @brief enable or disable crm high speed external crystal bypass + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_hext_bypass(confirm_state new_state) +{ + CRM->ctrl_bit.hextbyps = new_state; +} + +/** + * @brief get crm flag status + * @param flag + * this parameter can be one of the following values: + * - CRM_HICK_STABLE_FLAG + * - CRM_HEXT_STABLE_FLAG + * - CRM_PLL_STABLE_FLAG + * - CRM_LEXT_STABLE_FLAG + * - CRM_LICK_STABLE_FLAG + * - CRM_NRST_RESET_FLAG + * - CRM_POR_RESET_FLAG + * - CRM_SW_RESET_FLAG + * - CRM_WDT_RESET_FLAG + * - CRM_WWDT_RESET_FLAG + * - CRM_LOWPOWER_RESET_FLAG + * interrupt flag: + * - CRM_LICK_READY_INT_FLAG + * - CRM_LEXT_READY_INT_FLAG + * - CRM_HICK_READY_INT_FLAG + * - CRM_HEXT_READY_INT_FLAG + * - CRM_PLL_READY_INT_FLAG + * - CRM_CLOCK_FAILURE_INT_FLAG + * @retval flag_status (SET or RESET) + */ +flag_status crm_flag_get(uint32_t flag) +{ + flag_status status = RESET; + if((CRM_REG(flag) & CRM_REG_BIT(flag)) != CRM_REG_BIT(flag)) + { + status = RESET; + } + else + { + status = SET; + } + return status; +} + +/** + * @brief wait for hext stable + * @param none + * @retval error_status (ERROR or SUCCESS) + */ +error_status crm_hext_stable_wait(void) +{ + uint32_t stable_cnt = 0; + error_status status = ERROR; + + while((crm_flag_get(CRM_HEXT_STABLE_FLAG) != SET) && (stable_cnt < HEXT_STARTUP_TIMEOUT)) + { + stable_cnt ++; + } + + if(crm_flag_get(CRM_HEXT_STABLE_FLAG) != SET) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + + return status; +} + +/** + * @brief set the hick trimming value + * @param trim_value (0x00~0x3F) + * @retval none + */ +void crm_hick_clock_trimming_set(uint8_t trim_value) +{ + CRM->ctrl_bit.hicktrim = trim_value; +} + +/** + * @brief set the crm calibration value + * @param cali_value (0x00~0xFF) + * @retval none + */ +void crm_hick_clock_calibration_set(uint8_t cali_value) +{ + /* enable write hick calibration */ + CRM->misc1_bit.hickcal_key = 0x5A; + + /* write hick calibration value */ + CRM->ctrl_bit.hickcal = cali_value; + + /* disable write hick calibration */ + CRM->misc1_bit.hickcal_key = 0x0; +} + +/** + * @brief enable or disable the peripheral clock + * @param value + * this parameter can be one of the following values: + * - CRM_DMA1_PERIPH_CLOCK - CRM_DMA2_PERIPH_CLOCK - CRM_CRC_PERIPH_CLOCK - CRM_XMC_PERIPH_CLOCK + * - CRM_SDIO1_PERIPH_CLOCK - CRM_SDIO2_PERIPH_CLOCK - CRM_EMAC_PERIPH_CLOCK - CRM_EMACTX_PERIPH_CLOCK + * - CRM_EMACRX_PERIPH_CLOCK - CRM_EMACPTP_PERIPH_CLOCK - CRM_IOMUX_PERIPH_CLOCK - CRM_GPIOA_PERIPH_CLOCK + * - CRM_GPIOB_PERIPH_CLOCK - CRM_GPIOC_PERIPH_CLOCK - CRM_GPIOD_PERIPH_CLOCK - CRM_GPIOE_PERIPH_CLOCK + * - CRM_ADC1_PERIPH_CLOCK - CRM_ADC2_PERIPH_CLOCK - CRM_TMR1_PERIPH_CLOCK - CRM_SPI1_PERIPH_CLOCK + * - CRM_TMR8_PERIPH_CLOCK - CRM_USART1_PERIPH_CLOCK - CRM_ADC3_PERIPH_CLOCK - CRM_TMR9_PERIPH_CLOCK + * - CRM_TMR10_PERIPH_CLOCK - CRM_TMR11_PERIPH_CLOCK - CRM_ACC_PERIPH_CLOCK - CRM_I2C3_PERIPH_CLOCK + * - CRM_USART6_PERIPH_CLOCK - CRM_UART7_PERIPH_CLOCK - CRM_UART8_PERIPH_CLOCK - CRM_TMR2_PERIPH_CLOCK + * - CRM_TMR3_PERIPH_CLOCK - CRM_TMR4_PERIPH_CLOCK - CRM_TMR5_PERIPH_CLOCK - CRM_TMR6_PERIPH_CLOCK + * - CRM_TMR7_PERIPH_CLOCK - CRM_TMR12_PERIPH_CLOCK - CRM_TMR13_PERIPH_CLOCK - CRM_TMR14_PERIPH_CLOCK + * - CRM_WWDT_PERIPH_CLOCK - CRM_SPI2_PERIPH_CLOCK - CRM_SPI3_PERIPH_CLOCK - CRM_SPI4_PERIPH_CLOCK + * - CRM_USART2_PERIPH_CLOCK - CRM_USART3_PERIPH_CLOCK - CRM_UART4_PERIPH_CLOCK - CRM_UART5_PERIPH_CLOCK + * - CRM_I2C1_PERIPH_CLOCK - CRM_I2C2_PERIPH_CLOCK - CRM_USB_PERIPH_CLOCK - CRM_CAN1_PERIPH_CLOCK + * - CRM_CAN2_PERIPH_CLOCK - CRM_BPR_PERIPH_CLOCK - CRM_PWC_PERIPH_CLOCK - CRM_DAC_PERIPH_CLOCK + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_periph_clock_enable(crm_periph_clock_type value, confirm_state new_state) +{ + /* enable periph clock */ + if(TRUE == new_state) + { + CRM_REG(value) |= CRM_REG_BIT(value); + } + /* disable periph clock */ + else + { + CRM_REG(value) &= ~(CRM_REG_BIT(value)); + } +} + +/** + * @brief enable or disable the peripheral reset + * @param value + * this parameter can be one of the following values: + * - CRM_EMAC_PERIPH_RESET - CRM_IOMUX_PERIPH_RESET - CRM_EXINT_PERIPH_RESET - CRM_GPIOA_PERIPH_RESET + * - CRM_GPIOB_PERIPH_RESET - CRM_GPIOC_PERIPH_RESET - CRM_GPIOD_PERIPH_RESET - CRM_GPIOE_PERIPH_RESET + * - CRM_ADC1_PERIPH_RESET - CRM_ADC2_PERIPH_RESET - CRM_TMR1_PERIPH_RESET - CRM_SPI1_PERIPH_RESET + * - CRM_TMR8_PERIPH_RESET - CRM_USART1_PERIPH_RESET - CRM_ADC3_PERIPH_RESET - CRM_TMR9_PERIPH_RESET + * - CRM_TMR10_PERIPH_RESET - CRM_TMR11_PERIPH_RESET - CRM_ACC_PERIPH_RESET - CRM_I2C3_PERIPH_RESET + * - CRM_USART6_PERIPH_RESET - CRM_UART7_PERIPH_RESET - CRM_UART8_PERIPH_RESET - CRM_TMR2_PERIPH_RESET + * - CRM_TMR3_PERIPH_RESET - CRM_TMR4_PERIPH_RESET - CRM_TMR5_PERIPH_RESET - CRM_TMR6_PERIPH_RESET + * - CRM_TMR7_PERIPH_RESET - CRM_TMR12_PERIPH_RESET - CRM_TMR13_PERIPH_RESET - CRM_TMR14_PERIPH_RESET + * - CRM_WWDT_PERIPH_RESET - CRM_SPI2_PERIPH_RESET - CRM_SPI3_PERIPH_RESET - CRM_SPI4_PERIPH_RESET + * - CRM_USART2_PERIPH_RESET - CRM_USART3_PERIPH_RESET - CRM_UART4_PERIPH_RESET - CRM_UART5_PERIPH_RESET + * - CRM_I2C1_PERIPH_RESET - CRM_I2C2_PERIPH_RESET - CRM_USB_PERIPH_RESET - CRM_CAN1_PERIPH_RESET + * - CRM_CAN2_PERIPH_RESET - CRM_BPR_PERIPH_RESET - CRM_PWC_PERIPH_RESET - CRM_DAC_PERIPH_RESET + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_periph_reset(crm_periph_reset_type value, confirm_state new_state) +{ + /* enable periph reset */ + if(new_state == TRUE) + { + CRM_REG(value) |= (CRM_REG_BIT(value)); + } + /* disable periph reset */ + else + { + CRM_REG(value) &= ~(CRM_REG_BIT(value)); + } +} + +/** + * @brief enable or disable the peripheral clock in sleep mode + * @param value + * this parameter can be one of the following values: + * - CRM_SRAM_PERIPH_CLOCK_SLEEP_MODE + * - CRM_FLASH_PERIPH_CLOCK_SLEEP_MODE + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_periph_sleep_mode_clock_enable(crm_periph_clock_sleepmd_type value, confirm_state new_state) +{ + /* enable periph clock in sleep mode */ + if(new_state == TRUE) + { + CRM_REG(value) |= (CRM_REG_BIT(value)); + } + /* disable perph clock in sleep mode */ + else + { + CRM_REG(value) &= ~(CRM_REG_BIT(value)); + } + +} + +/** + * @brief enable or disable the crm clock source + * @param source + * this parameter can be one of the following values: + * - CRM_CLOCK_SOURCE_HICK + * - CRM_CLOCK_SOURCE_HEXT + * - CRM_CLOCK_SOURCE_PLL + * - CRM_CLOCK_SOURCE_LEXT + * - CRM_CLOCK_SOURCE_LICK + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_clock_source_enable(crm_clock_source_type source, confirm_state new_state) +{ + switch(source) + { + case CRM_CLOCK_SOURCE_HICK: + CRM->ctrl_bit.hicken = new_state; + break; + case CRM_CLOCK_SOURCE_HEXT: + CRM->ctrl_bit.hexten = new_state; + break; + case CRM_CLOCK_SOURCE_PLL: + CRM->ctrl_bit.pllen = new_state; + break; + case CRM_CLOCK_SOURCE_LEXT: + CRM->bpdc_bit.lexten = new_state; + break; + case CRM_CLOCK_SOURCE_LICK: + CRM->ctrlsts_bit.licken = new_state; + break; + default: + break; + } +} + +/** + * @brief clear the crm reset flags + * @param flag + * this parameter can be one of the following values: + * reset flag: + * - CRM_NRST_RESET_FLAG + * - CRM_POR_RESET_FLAG + * - CRM_SW_RESET_FLAG + * - CRM_WDT_RESET_FLAG + * - CRM_WWDT_RESET_FLAG + * - CRM_LOWPOWER_RESET_FLAG + * - CRM_ALL_RESET_FLAG + * interrupt flag: + * - CRM_LICK_READY_INT_FLAG + * - CRM_LEXT_READY_INT_FLAG + * - CRM_HICK_READY_INT_FLAG + * - CRM_HEXT_READY_INT_FLAG + * - CRM_PLL_READY_INT_FLAG + * - CRM_CLOCK_FAILURE_INT_FLAG + * @retval none + */ +void crm_flag_clear(uint32_t flag) +{ + switch(flag) + { + case CRM_NRST_RESET_FLAG: + case CRM_POR_RESET_FLAG: + case CRM_SW_RESET_FLAG: + case CRM_WDT_RESET_FLAG: + case CRM_WWDT_RESET_FLAG: + case CRM_LOWPOWER_RESET_FLAG: + case CRM_ALL_RESET_FLAG: + CRM->ctrlsts_bit.rstfc = TRUE; + break; + case CRM_LICK_READY_INT_FLAG: + CRM->clkint_bit.lickstblfc = TRUE; + break; + case CRM_LEXT_READY_INT_FLAG: + CRM->clkint_bit.lextstblfc = TRUE; + break; + case CRM_HICK_READY_INT_FLAG: + CRM->clkint_bit.hickstblfc = TRUE; + break; + case CRM_HEXT_READY_INT_FLAG: + CRM->clkint_bit.hextstblfc = TRUE; + break; + case CRM_PLL_READY_INT_FLAG: + CRM->clkint_bit.pllstblfc = TRUE; + break; + case CRM_CLOCK_FAILURE_INT_FLAG: + CRM->clkint_bit.cfdfc = TRUE; + break; + default: + break; + } +} + +/** + * @brief select rtc clock + * @param value + * this parameter can be one of the following values: + * - CRM_RTC_CLOCK_LEXT + * - CRM_RTC_CLOCK_LICK + * - CRM_RTC_CLOCK_HEXT_DIV + * @retval none + */ +void crm_rtc_clock_select(crm_rtc_clock_type value) +{ + CRM->bpdc_bit.rtcsel = value; +} + +/** + * @brief enable or disable rtc + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_rtc_clock_enable(confirm_state new_state) +{ + CRM->bpdc_bit.rtcen = new_state; +} + +/** + * @brief set crm ahb division + * @param value + * this parameter can be one of the following values: + * - CRM_AHB_DIV_1 + * - CRM_AHB_DIV_2 + * - CRM_AHB_DIV_4 + * - CRM_AHB_DIV_8 + * - CRM_AHB_DIV_16 + * - CRM_AHB_DIV_64 + * - CRM_AHB_DIV_128 + * - CRM_AHB_DIV_256 + * - CRM_AHB_DIV_512 + * @retval none + */ +void crm_ahb_div_set(crm_ahb_div_type value) +{ + CRM->cfg_bit.ahbdiv = value; +} + +/** + * @brief set crm apb1 division + * @param value + * this parameter can be one of the following values: + * - CRM_APB1_DIV_1 + * - CRM_APB1_DIV_2 + * - CRM_APB1_DIV_4 + * - CRM_APB1_DIV_8 + * - CRM_APB1_DIV_16 + * @retval none + */ +void crm_apb1_div_set(crm_apb1_div_type value) +{ + CRM->cfg_bit.apb1div = value; +} + +/** + * @brief set crm apb2 division + * @param value + * this parameter can be one of the following values: + * - CRM_APB2_DIV_1 + * - CRM_APB2_DIV_2 + * - CRM_APB2_DIV_4 + * - CRM_APB2_DIV_8 + * - CRM_APB2_DIV_16 + * @retval none + */ +void crm_apb2_div_set(crm_apb2_div_type value) +{ + CRM->cfg_bit.apb2div = value; +} + +/** + * @brief set crm adc division + * @param value + * this parameter can be one of the following values: + * - CRM_ADC_DIV_2 + * - CRM_ADC_DIV_4 + * - CRM_ADC_DIV_6 + * - CRM_ADC_DIV_8 + * - CRM_ADC_DIV_12 + * - CRM_ADC_DIV_16 + * @retval none + */ +void crm_adc_clock_div_set(crm_adc_div_type div_value) +{ + CRM->cfg_bit.adcdiv_l = div_value & 0x03; + CRM->cfg_bit.adcdiv_h = (div_value >> 2) & 0x01; +} + +/** + * @brief set crm usb division + * @param value + * this parameter can be one of the following values: + * - CRM_USB_DIV_1_5 + * - CRM_USB_DIV_1 + * - CRM_USB_DIV_2_5 + * - CRM_USB_DIV_2 + * - CRM_USB_DIV_3_5 + * - CRM_USB_DIV_3 + * - CRM_USB_DIV_4 + * @retval none + */ +void crm_usb_clock_div_set(crm_usb_div_type div_value) +{ + CRM->cfg_bit.usbdiv_l = div_value & 0x03; + CRM->cfg_bit.usbdiv_h = (div_value >> 2) & 0x01; +} + +/** + * @brief enable or disable clock failure detection + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_clock_failure_detection_enable(confirm_state new_state) +{ + CRM->ctrl_bit.cfden = new_state; +} + +/** + * @brief battery powered domain software reset + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_battery_powered_domain_reset(confirm_state new_state) +{ + CRM->bpdc_bit.bpdrst = new_state; +} + +/** + * @brief config crm pll + * @param clock_source + * this parameter can be one of the following values: + * - CRM_PLL_SOURCE_HICK + * - CRM_PLL_SOURCE_HEXT + * - CRM_PLL_SOURCE_HEXT_DIV + * @param mult_value (CRM_PLL_MULT_2~64) + * @param pll_range + * this parameter can be one of the following values: + * - CRM_PLL_OUTPUT_RANGE_LE72MHZ + * - CRM_PLL_OUTPUT_RANGE_GT72MHZ + * @retval none + */ +void crm_pll_config(crm_pll_clock_source_type clock_source, crm_pll_mult_type mult_value, crm_pll_output_range_type pll_range) +{ + /* config pll clock source */ + if(clock_source == CRM_PLL_SOURCE_HICK) + { + CRM->cfg_bit.pllrcs = FALSE; + } + else + { + CRM->cfg_bit.pllrcs = TRUE; + if(CRM_PLL_SOURCE_HEXT == clock_source) + { + CRM->cfg_bit.pllhextdiv = FALSE; + } + else + { + CRM->cfg_bit.pllhextdiv = TRUE; + } + } + + /* config pll multiplication factor */ + CRM->cfg_bit.pllmult_l = (mult_value & 0x0F); + CRM->cfg_bit.pllmult_h = ((mult_value & 0x30) >> 4); + + /* config pll output range */ + CRM->cfg_bit.pllrange = pll_range; +} + +/** + * @brief select system clock source + * @param value + * this parameter can be one of the following values: + * - CRM_SCLK_HICK + * - CRM_SCLK_HEXT + * - CRM_SCLK_PLL + * @retval none + */ +void crm_sysclk_switch(crm_sclk_type value) +{ + CRM->cfg_bit.sclksel = value; +} + +/** + * @brief indicate which clock source is used as system clock + * @param none + * @retval crm_sclk + * this return can be one of the following values: + * - CRM_SCLK_HICK + * - CRM_SCLK_HEXT + * - CRM_SCLK_PLL + */ +crm_sclk_type crm_sysclk_switch_status_get(void) +{ + return (crm_sclk_type)CRM->cfg_bit.sclksts; +} + +/** + * @brief get crm clocks freqency + * @param clocks + * - pointer to the crm_clocks_freq structure + * @retval none + */ +void crm_clocks_freq_get(crm_clocks_freq_type *clocks_struct) +{ + uint32_t hext_prediv = 0, pll_mult = 0, pll_mult_h = 0, pll_clock_source = 0, temp = 0, div_value = 0; + crm_sclk_type sclk_source; + + static const uint8_t sclk_ahb_div_table[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + static const uint8_t ahb_apb1_div_table[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + static const uint8_t ahb_apb2_div_table[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + static const uint8_t adc_div_table[8] = {2, 4, 6, 8, 2, 12, 8, 16}; + + /* get sclk source */ + sclk_source = crm_sysclk_switch_status_get(); + + switch(sclk_source) + { + case CRM_SCLK_HICK: + if(((CRM->misc3_bit.hick_to_sclk) != RESET) && ((CRM->misc1_bit.hickdiv) != RESET)) + clocks_struct->sclk_freq = HICK_VALUE * 6; + else + clocks_struct->sclk_freq = HICK_VALUE; + break; + case CRM_SCLK_HEXT: + clocks_struct->sclk_freq = HEXT_VALUE; + break; + case CRM_SCLK_PLL: + pll_clock_source = CRM->cfg_bit.pllrcs; + /* get multiplication factor */ + pll_mult = CRM->cfg_bit.pllmult_l; + pll_mult_h = CRM->cfg_bit.pllmult_h; + + /* process high bits */ + if((pll_mult_h != 0U) || (pll_mult == 15U)) + { + pll_mult += ((16U * pll_mult_h) + 1U); + } + else + { + pll_mult += 2U; + } + + if (pll_clock_source == 0x00) + { + /* hick divided by 2 selected as pll clock entry */ + clocks_struct->sclk_freq = (HICK_VALUE >> 1) * pll_mult; + } + else + { + /* hext selected as pll clock entry */ + if (CRM->cfg_bit.pllhextdiv != RESET) + { + hext_prediv = CRM->misc3_bit.hextdiv; + /* hext clock divided by 2 */ + clocks_struct->sclk_freq = (HEXT_VALUE / (hext_prediv + 2)) * pll_mult; + } + else + { + clocks_struct->sclk_freq = HEXT_VALUE * pll_mult; + } + } + break; + default: + clocks_struct->sclk_freq = HICK_VALUE; + break; + } + + /* compute sclk, ahbclk, abp1clk apb2clk and adcclk frequencies */ + /* get ahb division */ + temp = CRM->cfg_bit.ahbdiv; + div_value = sclk_ahb_div_table[temp]; + /* ahbclk frequency */ + clocks_struct->ahb_freq = clocks_struct->sclk_freq >> div_value; + + /* get apb1 division */ + temp = CRM->cfg_bit.apb1div; + div_value = ahb_apb1_div_table[temp]; + /* apb1clk frequency */ + clocks_struct->apb1_freq = clocks_struct->ahb_freq >> div_value; + + /* get apb2 division */ + temp = CRM->cfg_bit.apb2div; + div_value = ahb_apb2_div_table[temp]; + /* apb2clk frequency */ + clocks_struct->apb2_freq = clocks_struct->ahb_freq >> div_value; + + /* get adc division */ + temp = CRM->cfg_bit.adcdiv_h; + temp = ((temp << 2) | (CRM->cfg_bit.adcdiv_l)); + div_value = adc_div_table[temp]; + /* adcclk clock frequency */ + clocks_struct->adc_freq = clocks_struct->apb2_freq / div_value; +} + +/** + * @brief set crm clkout + * @param clkout + * this parameter can be one of the following values: + * - CRM_CLKOUT_NOCLK + * - CRM_CLKOUT_LICK + * - CRM_CLKOUT_LEXT + * - CRM_CLKOUT_SCLK + * - CRM_CLKOUT_HICK + * - CRM_CLKOUT_HEXT + * - CRM_CLKOUT_PLL_DIV_2 + * - CRM_CLKOUT_PLL_DIV_4 + * - CRM_CLKOUT_USB + * - CRM_CLKOUT_ADC + * @retval none + */ +void crm_clock_out_set(crm_clkout_select_type clkout) +{ + CRM->cfg_bit.clkout_sel = clkout & 0x7; + CRM->misc1_bit.clkout_sel = (clkout >> 3) & 0x1; +} + +/** + * @brief config crm interrupt + * @param int + * this parameter can be any combination of the following values: + * - CRM_LICK_STABLE_INT + * - CRM_LEXT_STABLE_INT + * - CRM_HICK_STABLE_INT + * - CRM_HEXT_STABLE_INT + * - CRM_PLL_STABLE_INT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_interrupt_enable(uint32_t crm_int, confirm_state new_state) +{ + if(new_state == TRUE) + CRM->clkint |= crm_int; + else + CRM->clkint &= ~crm_int; +} + +/** + * @brief auto step clock switch enable + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_auto_step_mode_enable(confirm_state new_state) +{ + if(new_state == TRUE) + CRM->misc3_bit.auto_step_en = CRM_AUTO_STEP_MODE_ENABLE; + else + CRM->misc3_bit.auto_step_en = CRM_AUTO_STEP_MODE_DISABLE; +} + +/** + * @brief usbdev interrupt remapping control + * @param int_remap + * this parameter can be one of the following values: + * - CRM_USB_INT19_INT20 + * - CRM_USB_INT73_INT74 + * @retval none + */ +void crm_usb_interrupt_remapping_set(crm_usb_int_map_type int_remap) +{ + CRM->intmap_bit.usbintmap = int_remap; +} + +/** + * @brief config hick divider select + * @param value + * this parameter can be one of the following values: + * - CRM_HICK48_DIV6 + * - CRM_HICK48_NODIV + * @retval none + */ +void crm_hick_divider_select(crm_hick_div_6_type value) +{ + CRM->misc1_bit.hickdiv = value; +} + +/** + * @brief hick as system clock frequency select + * @param value + * this parameter can be one of the following values: + * - CRM_HICK_SCLK_8MHZ + * - CRM_HICK_SCLK_48MHZ + * @retval none + */ +void crm_hick_sclk_frequency_select(crm_hick_sclk_frequency_type value) +{ + crm_hick_divider_select(CRM_HICK48_NODIV); + CRM->misc3_bit.hick_to_sclk = value; +} + +/** + * @brief usb 48 mhz clock source select + * @param value + * this parameter can be one of the following values: + * - CRM_USB_CLOCK_SOURCE_PLL + * - CRM_USB_CLOCK_SOURCE_HICK + * @retval none + */ +void crm_usb_clock_source_select(crm_usb_clock_source_type value) +{ + if(value == CRM_USB_CLOCK_SOURCE_HICK) + { + crm_hick_sclk_frequency_select(CRM_HICK_SCLK_48MHZ); + } + CRM->misc3_bit.hick_to_usb = value; +} + +/** + * @brief enable or disable clkout direct to tmr10 channel 1 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_clkout_to_tmr10_enable(confirm_state new_state) +{ + CRM->misc2_bit.clk_to_tmr = new_state; +} + +/** + * @brief set hext clock division + * @param value + * this parameter can be one of the following values: + * - CRM_HEXT_DIV_2 + * - CRM_HEXT_DIV_3 + * - CRM_HEXT_DIV_4 + * - CRM_HEXT_DIV_5 + * @retval none + */ +void crm_hext_clock_div_set(crm_hext_div_type value) +{ + CRM->misc3_bit.hextdiv = value; +} + +/** + * @brief set crm clkout division + * @param clkout_div + * this parameter can be one of the following values: + * - CRM_CLKOUT_DIV_1 + * - CRM_CLKOUT_DIV_2 + * - CRM_CLKOUT_DIV_4 + * - CRM_CLKOUT_DIV_8 + * - CRM_CLKOUT_DIV_16 + * - CRM_CLKOUT_DIV_64 + * - CRM_CLKOUT_DIV_128 + * - CRM_CLKOUT_DIV_256 + * - CRM_CLKOUT_DIV_512 + * @retval none + */ +void crm_clkout_div_set(crm_clkout_div_type clkout_div) +{ + CRM->misc1_bit.clkoutdiv = clkout_div; +} + +#if defined (AT32F407xx) +/** + * @brief set emac output pulse width + * @param width + * this parameter can be one of the following values: + * - CRM_EMAC_PULSE_125MS + * - CRM_EMAC_PULSE_1SCLK + * @retval none + */ +void crm_emac_output_pulse_set(crm_emac_output_pulse_type width) +{ + CRM->misc3_bit.emac_pps_sel = width; +} +#endif + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_dac.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_dac.c new file mode 100644 index 0000000..b956361 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_dac.c @@ -0,0 +1,380 @@ +/** + ************************************************************************** + * @file at32f403a_407_dac.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the dac firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup DAC + * @brief DAC driver modules + * @{ + */ + +#ifdef DAC_MODULE_ENABLED + +/** @defgroup DAC_private_functions + * @{ + */ + +/** + * @brief dac reset + * @param none + * @retval none + */ +void dac_reset(void) +{ + crm_periph_reset(CRM_DAC_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_DAC_PERIPH_RESET, FALSE); +} + +/** + * @brief enable or disable dac + * @param dac_select + * this parameter can be one of the following values: + * - DAC1_SELECT + * - DAC2_SELECT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void dac_enable(dac_select_type dac_select, confirm_state new_state) +{ + switch(dac_select) + { + case DAC1_SELECT: + DAC->ctrl_bit.d1en = new_state; + break; + case DAC2_SELECT: + DAC->ctrl_bit.d2en = new_state; + break; + default: + break; + } +} + +/** + * @brief enable or disable dac output buffer + * @param dac_select + * this parameter can be one of the following values: + * - DAC1_SELECT + * - DAC2_SELECT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void dac_output_buffer_enable(dac_select_type dac_select, confirm_state new_state) +{ + new_state = (confirm_state)!new_state; + switch(dac_select) + { + case DAC1_SELECT: + DAC->ctrl_bit.d1obdis = new_state; + break; + case DAC2_SELECT: + DAC->ctrl_bit.d2obdis = new_state; + break; + default: + break; + } +} + +/** + * @brief enable or disable dac trigger + * @param dac_select + * this parameter can be one of the following values: + * - DAC1_SELECT + * - DAC2_SELECT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void dac_trigger_enable(dac_select_type dac_select, confirm_state new_state) +{ + switch(dac_select) + { + case DAC1_SELECT: + DAC->ctrl_bit.d1trgen = new_state; + break; + case DAC2_SELECT: + DAC->ctrl_bit.d2trgen = new_state; + break; + default: + break; + } +} + +/** + * @brief select dac trigger + * @param dac_select + * this parameter can be one of the following values: + * - DAC1_SELECT + * - DAC2_SELECT + * @param dac_trigger_source + * this parameter can be one of the following values: + * - DAC_TMR6_TRGOUT_EVENT + * - DAC_TMR8_TRGOUT_EVENT + * - DAC_TMR7_TRGOUT_EVENT + * - DAC_TMR5_TRGOUT_EVENT + * - DAC_TMR2_TRGOUT_EVENT + * - DAC_TMR4_TRGOUT_EVENT + * - DAC_EXTERNAL_INTERRUPT_LINE_9 + * - DAC_SOFTWARE_TRIGGER + * @retval none + */ +void dac_trigger_select(dac_select_type dac_select, dac_trigger_type dac_trigger_source) +{ + switch(dac_select) + { + case DAC1_SELECT: + DAC->ctrl_bit.d1trgsel = dac_trigger_source; + break; + case DAC2_SELECT: + DAC->ctrl_bit.d2trgsel = dac_trigger_source; + break; + default: + break; + } +} + +/** + * @brief generate dac software trigger + * @param dac_select + * this parameter can be one of the following values: + * - DAC1_SELECT + * - DAC2_SELECT + * @retval none + */ +void dac_software_trigger_generate(dac_select_type dac_select) +{ + switch(dac_select) + { + case DAC1_SELECT: + DAC->swtrg_bit.d1swtrg = TRUE; + break; + case DAC2_SELECT: + DAC->swtrg_bit.d2swtrg = TRUE; + break; + default: + break; + } +} + +/** + * @brief generate dac dual software trigger synchronously + * @param none + * @retval none + */ +void dac_dual_software_trigger_generate(void) +{ + DAC->swtrg |= 0x03; +} + +/** + * @brief generate dac wave + * @param dac_select + * this parameter can be one of the following values: + * - DAC1_SELECT + * - DAC2_SELECT + * @param dac_wave + * this parameter can be one of the following values: + * - DAC_WAVE_GENERATE_NONE + * - DAC_WAVE_GENERATE_NOISE + * - DAC_WAVE_GENERATE_TRIANGLE + * @retval none + */ +void dac_wave_generate(dac_select_type dac_select, dac_wave_type dac_wave) +{ + switch(dac_select) + { + case DAC1_SELECT: + DAC->ctrl_bit.d1nm = dac_wave; + break; + case DAC2_SELECT: + DAC->ctrl_bit.d2nm = dac_wave; + break; + default: + break; + } +} + +/** + * @brief select dac mask amplitude + * @param dac_select + * this parameter can be one of the following values: + * - DAC1_SELECT + * - DAC2_SELECT + * @param dac_mask_amplitude + * this parameter can be one of the following values: + * - DAC_LSFR_BIT0_AMPLITUDE_1 + * - DAC_LSFR_BIT10_AMPLITUDE_3 + * - DAC_LSFR_BIT20_AMPLITUDE_7 + * - DAC_LSFR_BIT30_AMPLITUDE_15 + * - DAC_LSFR_BIT40_AMPLITUDE_31 + * - DAC_LSFR_BIT50_AMPLITUDE_63 + * - DAC_LSFR_BIT60_AMPLITUDE_127 + * - DAC_LSFR_BIT70_AMPLITUDE_255 + * - DAC_LSFR_BIT80_AMPLITUDE_511 + * - DAC_LSFR_BIT90_AMPLITUDE_1023 + * - DAC_LSFR_BITA0_AMPLITUDE_2047 + * - DAC_LSFR_BITB0_AMPLITUDE_4095 + * @retval none + */ +void dac_mask_amplitude_select(dac_select_type dac_select, dac_mask_amplitude_type dac_mask_amplitude) +{ + switch(dac_select) + { + case DAC1_SELECT: + DAC->ctrl_bit.d1nbsel = dac_mask_amplitude; + break; + case DAC2_SELECT: + DAC->ctrl_bit.d2nbsel = dac_mask_amplitude; + break; + default: + break; + } +} + +/** + * @brief enable or disable dac dma + * @param dac_select + * this parameter can be one of the following values: + * - DAC1_SELECT + * - DAC2_SELECT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void dac_dma_enable(dac_select_type dac_select, confirm_state new_state) +{ + switch(dac_select) + { + case DAC1_SELECT: + DAC->ctrl_bit.d1dmaen = new_state; + break; + case DAC2_SELECT: + DAC->ctrl_bit.d2dmaen = new_state; + break; + default: + break; + } +} + +/** + * @brief get dac data output + * @param dac_select + * this parameter can be one of the following values: + * - DAC1_SELECT + * - DAC2_SELECT + * @retval dac channel data output + */ +uint16_t dac_data_output_get(dac_select_type dac_select) +{ + uint16_t data_output =0 ; + switch(dac_select) + { + case DAC1_SELECT: + data_output = DAC->d1odt_bit.d1odt; + break; + case DAC2_SELECT: + data_output = DAC->d2odt_bit.d2odt; + break; + default: + break; + } + return data_output; +} + +/** + * @brief set dac1 data + * @param dac1_aligned + * this parameter can be one of the following values: + * DAC1_12BIT_RIGHT + * DAC1_12BIT_LEFT + * DAC1_8BIT_RIGHT + * @param dac1_data :indecate from selected data holding register + * @retval none + */ +void dac_1_data_set(dac1_aligned_data_type dac1_aligned, uint16_t dac1_data) +{ + *(__IO uint32_t *) dac1_aligned = dac1_data; +} + +/** + * @brief set dac2 data + * @param dac2_aligned + * this parameter can be one of the following values: + * DAC2_12BIT_RIGHT + * DAC2_12BIT_LEFT + * DAC2_8BIT_RIGHT + * @param dac2_data :indecate from selected data holding register + * @retval none + */ +void dac_2_data_set(dac2_aligned_data_type dac2_aligned, uint16_t dac2_data) +{ + *(__IO uint32_t *) dac2_aligned = dac2_data; +} + +/** + * @brief set dac dual data + * @param dac_dual + * this parameter can be one of the following values: + * DAC_DUAL_12BIT_RIGHT + * DAC_DUAL_12BIT_LEFT + * DAC_DUAL_8BIT_RIGHT + * @param data1 :dac1 channel indecate from selected data holding register + * @param data2 :dac1 channel indecate from selected data holding register + * @retval none + */ +void dac_dual_data_set(dac_dual_data_type dac_dual, uint16_t data1, uint16_t data2) +{ + switch(dac_dual) + { + case DAC_DUAL_12BIT_RIGHT: + *(__IO uint32_t *) dac_dual = (uint32_t)(data1 | (data2 << 16)); + break; + case DAC_DUAL_12BIT_LEFT: + *(__IO uint32_t *) dac_dual = (uint32_t)(data1 | (data2 << 16)); + break; + case DAC_DUAL_8BIT_RIGHT: + *(__IO uint32_t *) dac_dual = (uint32_t)(data1 | (data2 << 8)); + break; + default: + break; + } +} + + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_debug.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_debug.c new file mode 100644 index 0000000..893cd60 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_debug.c @@ -0,0 +1,97 @@ +/** + ************************************************************************** + * @file at32f403a_407_debug.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the debug firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup DEBUG + * @brief DEBUG driver modules + * @{ + */ + +#ifdef DEBUG_MODULE_ENABLED + +/** @defgroup DEBUG_private_functions + * @{ + */ + +/** + * @brief get debug device id + * @param none + * @retval the debug device id + */ +uint32_t debug_device_id_get(void) +{ + return DEBUGMCU->pid; +} + +/** + * @brief set periph debug mode + * @param periph_debug_mode + * this parameter can be any combination of the following values: + * - DEBUG_SLEEP - DEBUG_DEEPSLEEP + * - DEBUG_STANDBY - DEBUG_WDT_PAUSE + * - DEBUG_WWDT_PAUSE - DEBUG_TMR1_PAUSE + * - DEBUG_TMR3_PAUSE - DEBUG_I2C1_SMBUS_TIMEOUT + * - DEBUG_I2C2_SMBUS_TIMEOUT - DEBUG_I2C3_SMBUS_TIMEOUT + * - DEBUG_TMR2_PAUSE - DEBUG_TMR4_PAUSE + * - DEBUG_CAN1_PAUSE - DEBUG_TMR8_PAUSE + * - DEBUG_TMR5_PAUSE - DEBUG_TMR6_PAUSE + * - DEBUG_TMR7_PAUSE - DEBUG_CAN2_PAUSE + * - DEBUG_TMR12_PAUSE - DEBUG_TMR13_PAUSE + * - DEBUG_TMR14_PAUSE - DEBUG_TMR9_PAUSE + * - DEBUG_TMR10_PAUSE - DEBUG_TMR11_PAUSE + * @param new_state (TRUE or FALSE) + * @retval none + */ +void debug_periph_mode_set(uint32_t periph_debug_mode, confirm_state new_state) +{ + if(new_state != FALSE) + { + DEBUGMCU->ctrl |= periph_debug_mode; + } + else + { + DEBUGMCU->ctrl &= ~periph_debug_mode; + } +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_dma.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_dma.c new file mode 100644 index 0000000..39e036d --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_dma.c @@ -0,0 +1,431 @@ +/** + ************************************************************************** + * @file at32f403a_407_dma.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the dma firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup DMA + * @brief DMA driver modules + * @{ + */ + +#ifdef DMA_MODULE_ENABLED + +/** @defgroup DMA_private_functions + * @{ + */ + +/** + * @brief reset the dmax channely registers. + * @param dmax_channely: + * this parameter can be one of the following values: + * - DMA1_CHANNEL1 + * - DMA1_CHANNEL2 + * - DMA1_CHANNEL3 + * - DMA1_CHANNEL4 + * - DMA1_CHANNEL5 + * - DMA1_CHANNEL6 + * - DMA1_CHANNEL7 + * - DMA2_CHANNEL1 + * - DMA2_CHANNEL2 + * - DMA2_CHANNEL3 + * - DMA2_CHANNEL4 + * - DMA2_CHANNEL5 + * - DMA2_CHANNEL6 + * - DMA2_CHANNEL7 + * @retval none + */ +void dma_reset(dma_channel_type* dmax_channely) +{ + uint32_t temp = 0; + dmax_channely->ctrl_bit.chen = FALSE; + dmax_channely->ctrl = 0; + dmax_channely->dtcnt = 0; + dmax_channely->paddr = 0; + dmax_channely->maddr = 0; + + temp = (uint32_t)dmax_channely; + + if((temp & 0x4ff) < 0x408) + { + /* dma1 channel */ + DMA1->clr |= (uint32_t)(0x0f << ((((temp & 0xff) - 0x08) / 0x14) * 4)); + } + else if((temp & 0x4ff) < 0x488) + { + /* dma2 channel */ + DMA2->clr |= (uint32_t)(0x0f << ((((temp & 0xff) - 0x08) / 0x14) * 4)); + } +} + +/** + * @brief set the number of data to be transferred + * @param dmax_channely: + * this parameter can be one of the following values: + * - DMA1_CHANNEL1 + * - DMA1_CHANNEL2 + * - DMA1_CHANNEL3 + * - DMA1_CHANNEL4 + * - DMA1_CHANNEL5 + * - DMA1_CHANNEL6 + * - DMA1_CHANNEL7 + * - DMA2_CHANNEL1 + * - DMA2_CHANNEL2 + * - DMA2_CHANNEL3 + * - DMA2_CHANNEL4 + * - DMA2_CHANNEL5 + * - DMA2_CHANNEL6 + * - DMA2_CHANNEL7 + * @param data_number: the number of data to be transferred(0x0000~0xFFFF) + * transfer. + * @retval none. + */ +void dma_data_number_set(dma_channel_type* dmax_channely, uint16_t data_number) +{ + dmax_channely->dtcnt = data_number; +} + +/** + * @brief get number of data from dtcnt register + * @param dmax_channely: + * this parameter can be one of the following values: + * - DMA1_CHANNEL1 + * - DMA1_CHANNEL2 + * - DMA1_CHANNEL3 + * - DMA1_CHANNEL4 + * - DMA1_CHANNEL5 + * - DMA1_CHANNEL6 + * - DMA1_CHANNEL7 + * - DMA2_CHANNEL1 + * - DMA2_CHANNEL2 + * - DMA2_CHANNEL3 + * - DMA2_CHANNEL4 + * - DMA2_CHANNEL5 + * - DMA2_CHANNEL6 + * - DMA2_CHANNEL7 + * @retval the number of data. + */ +uint16_t dma_data_number_get(dma_channel_type* dmax_channely) +{ + return (uint16_t)dmax_channely->dtcnt; +} + +/** + * @brief enable or disable dma interrupt + * @param dmax_channely: + * this parameter can be one of the following values: + * - DMA1_CHANNEL1 + * - DMA1_CHANNEL2 + * - DMA1_CHANNEL3 + * - DMA1_CHANNEL4 + * - DMA1_CHANNEL5 + * - DMA1_CHANNEL6 + * - DMA1_CHANNEL7 + * - DMA2_CHANNEL1 + * - DMA2_CHANNEL2 + * - DMA2_CHANNEL3 + * - DMA2_CHANNEL4 + * - DMA2_CHANNEL5 + * - DMA2_CHANNEL6 + * - DMA2_CHANNEL7 + * @param dma_int: + * this parameter can be any combination of the following values: + * - DMA_FDT_INT + * - DMA_HDT_INT + * - DMA_DTERR_INT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void dma_interrupt_enable(dma_channel_type* dmax_channely, uint32_t dma_int, confirm_state new_state) +{ + if (new_state != FALSE) + { + dmax_channely->ctrl |= dma_int; + } + else + { + dmax_channely->ctrl &= ~dma_int; + } +} + +/** + * @brief enable or disable dma channely + * @param dmax_channely: + * this parameter can be one of the following values: + * - DMA1_CHANNEL1 + * - DMA1_CHANNEL2 + * - DMA1_CHANNEL3 + * - DMA1_CHANNEL4 + * - DMA1_CHANNEL5 + * - DMA1_CHANNEL6 + * - DMA1_CHANNEL7 + * - DMA2_CHANNEL1 + * - DMA2_CHANNEL2 + * - DMA2_CHANNEL3 + * - DMA2_CHANNEL4 + * - DMA2_CHANNEL5 + * - DMA2_CHANNEL6 + * - DMA2_CHANNEL7 + * @param new_state (TRUE or FALSE) + * @retval None + */ +void dma_channel_enable(dma_channel_type* dmax_channely, confirm_state new_state) +{ + dmax_channely->ctrl_bit.chen = new_state; +} + +/** + * @brief initialize the dma_x flexible function according to the specified parameters. + * @param dma_x: + * this parameter can be one of the following values: + * - DMA1 + * - DMA2 + * @param flex_channelx: + * this parameter can be one of the following values: + * - FLEX_CHANNEL1 + * - FLEX_CHANNEL2 + * - FLEX_CHANNEL3 + * - FLEX_CHANNEL4 + * - FLEX_CHANNEL5 + * - FLEX_CHANNEL6 + * - FLEX_CHANNEL7 + * @param flexible_request: every peripheral have specified hardware_id. + * this parameter can be one of the following values: + * - DMA_FLEXIBLE_ADC1 - DMA_FLEXIBLE_ADC3 - DMA_FLEXIBLE_DAC1 - DMA_FLEXIBLE_DAC2 + * - DMA_FLEXIBLE_SPI1_RX - DMA_FLEXIBLE_SPI1_TX - DMA_FLEXIBLE_SPI2_RX - DMA_FLEXIBLE_SPI2_TX + * - DMA_FLEXIBLE_SPI3_RX - DMA_FLEXIBLE_SPI3_TX - DMA_FLEXIBLE_SPI4_RX - DMA_FLEXIBLE_SPI4_TX + * - DMA_FLEXIBLE_I2S2EXT_RX - DMA_FLEXIBLE_I2S2EXT_TX - DMA_FLEXIBLE_I2S3EXT_RX - DMA_FLEXIBLE_I2S3EXT_TX + * - DMA_FLEXIBLE_UART1_RX - DMA_FLEXIBLE_UART1_TX - DMA_FLEXIBLE_UART2_RX - DMA_FLEXIBLE_UART2_TX + * - DMA_FLEXIBLE_UART3_RX - DMA_FLEXIBLE_UART3_TX - DMA_FLEXIBLE_UART4_RX - DMA_FLEXIBLE_UART4_TX + * - DMA_FLEXIBLE_UART5_RX - DMA_FLEXIBLE_UART5_TX - DMA_FLEXIBLE_UART6_RX - DMA_FLEXIBLE_UART6_TX + * - DMA_FLEXIBLE_UART7_RX - DMA_FLEXIBLE_UART7_TX - DMA_FLEXIBLE_UART8_RX - DMA_FLEXIBLE_UART8_TX + * - DMA_FLEXIBLE_I2C1_RX - DMA_FLEXIBLE_I2C1_TX - DMA_FLEXIBLE_I2C2_RX - DMA_FLEXIBLE_I2C2_TX + * - DMA_FLEXIBLE_I2C3_RX - DMA_FLEXIBLE_I2C3_TX - DMA_FLEXIBLE_SDIO1 - DMA_FLEXIBLE_SDIO2 + * - DMA_FLEXIBLE_TMR1_TRIG - DMA_FLEXIBLE_TMR1_HALL - DMA_FLEXIBLE_TMR1_OVERFLOW- DMA_FLEXIBLE_TMR1_CH1 + * - DMA_FLEXIBLE_TMR1_CH2 - DMA_FLEXIBLE_TMR1_CH3 - DMA_FLEXIBLE_TMR1_CH4 - DMA_FLEXIBLE_TMR2_TRIG + * - DMA_FLEXIBLE_TMR2_OVERFLOW- DMA_FLEXIBLE_TMR2_CH1 - DMA_FLEXIBLE_TMR2_CH2 - DMA_FLEXIBLE_TMR2_CH3 + * - DMA_FLEXIBLE_TMR2_CH4 - DMA_FLEXIBLE_TMR3_TRIG - DMA_FLEXIBLE_TMR3_OVERFLOW- DMA_FLEXIBLE_TMR3_CH1 + * - DMA_FLEXIBLE_TMR3_CH2 - DMA_FLEXIBLE_TMR3_CH3 - DMA_FLEXIBLE_TMR3_CH4 - DMA_FLEXIBLE_TMR4_TRIG + * - DMA_FLEXIBLE_TMR4_OVERFLOW- DMA_FLEXIBLE_TMR4_CH1 - DMA_FLEXIBLE_TMR4_CH2 - DMA_FLEXIBLE_TMR4_CH3 + * - DMA_FLEXIBLE_TMR4_CH4 - DMA_FLEXIBLE_TMR5_TRIG - DMA_FLEXIBLE_TMR5_OVERFLOW- DMA_FLEXIBLE_TMR5_CH1 + * - DMA_FLEXIBLE_TMR5_CH2 - DMA_FLEXIBLE_TMR5_CH3 - DMA_FLEXIBLE_TMR5_CH4 - DMA_FLEXIBLE_TMR6_OVERFLOW + * - DMA_FLEXIBLE_TMR7_OVERFLOW- DMA_FLEXIBLE_TMR8_TRIG - DMA_FLEXIBLE_TMR8_HALL - DMA_FLEXIBLE_TMR8_OVERFLOW + * - DMA_FLEXIBLE_TMR8_CH1 - DMA_FLEXIBLE_TMR8_CH2 - DMA_FLEXIBLE_TMR8_CH3 - DMA_FLEXIBLE_TMR8_CH4 + * @retval none + */ + +void dma_flexible_config(dma_type* dma_x, uint8_t flex_channelx, dma_flexible_request_type flexible_request) +{ + if(dma_x->src_sel1_bit.dma_flex_en == RESET) + { + dma_x->src_sel1_bit.dma_flex_en = TRUE; + } + + if(flex_channelx == FLEX_CHANNEL1) + { + dma_x->src_sel0_bit.ch1_src = flexible_request; + } + else if(flex_channelx == FLEX_CHANNEL2) + { + dma_x->src_sel0_bit.ch2_src = flexible_request; + } + else if(flex_channelx == FLEX_CHANNEL3) + { + dma_x->src_sel0_bit.ch3_src = flexible_request; + } + else if(flex_channelx == FLEX_CHANNEL4) + { + dma_x->src_sel0_bit.ch4_src = flexible_request; + } + else if(flex_channelx == FLEX_CHANNEL5) + { + dma_x->src_sel1_bit.ch5_src = flexible_request; + } + else if(flex_channelx == FLEX_CHANNEL6) + { + dma_x->src_sel1_bit.ch6_src = flexible_request; + } + else + { + if(flex_channelx == FLEX_CHANNEL7) + { + dma_x->src_sel1_bit.ch7_src = flexible_request; + } + } +} + +/** + * @brief get dma flag + * @param dmax_flag + * this parameter can be one of the following values: + * - DMA1_GL1_FLAG - DMA1_FDT1_FLAG - DMA1_HDT1_FLAG - DMA1_DTERR1_FLAG + * - DMA1_GL2_FLAG - DMA1_FDT2_FLAG - DMA1_HDT2_FLAG - DMA1_DTERR2_FLAG + * - DMA1_GL3_FLAG - DMA1_FDT3_FLAG - DMA1_HDT3_FLAG - DMA1_DTERR3_FLAG + * - DMA1_GL4_FLAG - DMA1_FDT4_FLAG - DMA1_HDT4_FLAG - DMA1_DTERR4_FLAG + * - DMA1_GL5_FLAG - DMA1_FDT5_FLAG - DMA1_HDT5_FLAG - DMA1_DTERR5_FLAG + * - DMA1_GL6_FLAG - DMA1_FDT6_FLAG - DMA1_HDT6_FLAG - DMA1_DTERR6_FLAG + * - DMA1_GL7_FLAG - DMA1_FDT7_FLAG - DMA1_HDT7_FLAG - DMA1_DTERR7_FLAG + * - DMA2_GL1_FLAG - DMA2_FDT1_FLAG - DMA2_HDT1_FLAG - DMA2_DTERR1_FLAG + * - DMA2_GL2_FLAG - DMA2_FDT2_FLAG - DMA2_HDT2_FLAG - DMA2_DTERR2_FLAG + * - DMA2_GL3_FLAG - DMA2_FDT3_FLAG - DMA2_HDT3_FLAG - DMA2_DTERR3_FLAG + * - DMA2_GL4_FLAG - DMA2_FDT4_FLAG - DMA2_HDT4_FLAG - DMA2_DTERR4_FLAG + * - DMA2_GL5_FLAG - DMA2_FDT5_FLAG - DMA2_HDT5_FLAG - DMA2_DTERR5_FLAG + * - DMA2_GL6_FLAG - DMA2_FDT6_FLAG - DMA2_HDT6_FLAG - DMA2_DTERR6_FLAG + * - DMA2_GL7_FLAG - DMA2_FDT7_FLAG - DMA2_HDT7_FLAG - DMA2_DTERR7_FLAG + * @retval state of dma flag + */ +flag_status dma_flag_get(uint32_t dmax_flag) +{ + flag_status status = RESET; + uint32_t temp = 0; + + if(dmax_flag > 0x10000000) + { + temp = DMA2->sts; + } + else + { + temp = DMA1->sts; + } + + if ((temp & dmax_flag) != (uint16_t)RESET) + { + status = SET; + } + else + { + status = RESET; + } + + return status; +} + +/** + * @brief clear dma flag + * @param dmax_flag + * this parameter can be one of the following values: + * - DMA1_GL1_FLAG - DMA1_FDT1_FLAG - DMA1_HDT1_FLAG - DMA1_DTERR1_FLAG + * - DMA1_GL2_FLAG - DMA1_FDT2_FLAG - DMA1_HDT2_FLAG - DMA1_DTERR2_FLAG + * - DMA1_GL3_FLAG - DMA1_FDT3_FLAG - DMA1_HDT3_FLAG - DMA1_DTERR3_FLAG + * - DMA1_GL4_FLAG - DMA1_FDT4_FLAG - DMA1_HDT4_FLAG - DMA1_DTERR4_FLAG + * - DMA1_GL5_FLAG - DMA1_FDT5_FLAG - DMA1_HDT5_FLAG - DMA1_DTERR5_FLAG + * - DMA1_GL6_FLAG - DMA1_FDT6_FLAG - DMA1_HDT6_FLAG - DMA1_DTERR6_FLAG + * - DMA1_GL7_FLAG - DMA1_FDT7_FLAG - DMA1_HDT7_FLAG - DMA1_DTERR7_FLAG + * - DMA2_GL1_FLAG - DMA2_FDT1_FLAG - DMA2_HDT1_FLAG - DMA2_DTERR1_FLAG + * - DMA2_GL2_FLAG - DMA2_FDT2_FLAG - DMA2_HDT2_FLAG - DMA2_DTERR2_FLAG + * - DMA2_GL3_FLAG - DMA2_FDT3_FLAG - DMA2_HDT3_FLAG - DMA2_DTERR3_FLAG + * - DMA2_GL4_FLAG - DMA2_FDT4_FLAG - DMA2_HDT4_FLAG - DMA2_DTERR4_FLAG + * - DMA2_GL5_FLAG - DMA2_FDT5_FLAG - DMA2_HDT5_FLAG - DMA2_DTERR5_FLAG + * - DMA2_GL6_FLAG - DMA2_FDT6_FLAG - DMA2_HDT6_FLAG - DMA2_DTERR6_FLAG + * - DMA2_GL7_FLAG - DMA2_FDT7_FLAG - DMA2_HDT7_FLAG - DMA2_DTERR7_FLAG + * @retval none + */ +void dma_flag_clear(uint32_t dmax_flag) +{ + if(dmax_flag > 0x10000000) + { + DMA2->clr = (uint32_t)(dmax_flag & 0x0FFFFFFF); + } + else + { + DMA1->clr = dmax_flag; + } +} + +/** + * @brief dma init config with its default value. + * @param dma_init_struct : pointer to a dma_init_type structure which will + * be initialized. + * @retval none + */ +void dma_default_para_init(dma_init_type* dma_init_struct) +{ + dma_init_struct->peripheral_base_addr = 0x0; + dma_init_struct->memory_base_addr = 0x0; + dma_init_struct->direction = DMA_DIR_PERIPHERAL_TO_MEMORY; + dma_init_struct->buffer_size = 0x0; + dma_init_struct->peripheral_inc_enable = FALSE; + dma_init_struct->memory_inc_enable = FALSE; + dma_init_struct->peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE; + dma_init_struct->memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE; + dma_init_struct->loop_mode_enable = FALSE; + dma_init_struct->priority = DMA_PRIORITY_LOW; +} + +/** + * @brief dma init + * @param dmax_channely: + * this parameter can be one of the following values: + * - DMA1_CHANNEL1 + * - DMA1_CHANNEL2 + * - DMA1_CHANNEL3 + * - DMA1_CHANNEL4 + * - DMA1_CHANNEL5 + * - DMA1_CHANNEL6 + * - DMA1_CHANNEL7 + * - DMA2_CHANNEL1 + * - DMA2_CHANNEL2 + * - DMA2_CHANNEL3 + * - DMA2_CHANNEL4 + * - DMA2_CHANNEL5 + * - DMA2_CHANNEL6 + * - DMA2_CHANNEL7 + * @param dma_initstruct : pointer to a dma_init_type structure. + * @retval none + */ +void dma_init(dma_channel_type* dmax_channely, dma_init_type* dma_init_struct) +{ + /* clear ctrl register dtd bit and m2m bit */ + dmax_channely->ctrl &= 0xbfef; + dmax_channely->ctrl |= dma_init_struct->direction; + + dmax_channely->ctrl_bit.chpl = dma_init_struct->priority; + dmax_channely->ctrl_bit.mwidth = dma_init_struct->memory_data_width; + dmax_channely->ctrl_bit.pwidth = dma_init_struct->peripheral_data_width; + dmax_channely->ctrl_bit.mincm = dma_init_struct->memory_inc_enable; + dmax_channely->ctrl_bit.pincm = dma_init_struct->peripheral_inc_enable; + dmax_channely->ctrl_bit.lm = dma_init_struct->loop_mode_enable; + dmax_channely->dtcnt = dma_init_struct->buffer_size; + dmax_channely->paddr = dma_init_struct->peripheral_base_addr; + dmax_channely->maddr = dma_init_struct->memory_base_addr; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_emac.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_emac.c new file mode 100644 index 0000000..a8b93ce --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_emac.c @@ -0,0 +1,2304 @@ +/** + ************************************************************************** + * @file at32f403a_407_emac.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the emac firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup EMAC + * @brief EMAC driver modules + * @{ + */ + +#ifdef EMAC_MODULE_ENABLED + +/** @defgroup EMAC_private_functions + * @{ + */ + +#if defined (EMAC_BASE) +/** + * @brief global pointers on tx and rx descriptor used to track transmit and receive descriptors + */ +emac_dma_desc_type *dma_tx_desc_to_set; +emac_dma_desc_type *dma_rx_desc_to_get; + +/* emac private function */ +static void emac_delay(uint32_t delay); + +/** + * @brief deinitialize the emac peripheral registers to their default reset values. + * @param none + * @retval none + */ +void emac_reset(void) +{ + crm_periph_reset(CRM_EMAC_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_EMAC_PERIPH_RESET, FALSE); +} + +/** + * @brief initialize emac control structure + * @param emac_control_config_type + * @retval none + */ +void emac_control_para_init(emac_control_config_type *control_para) +{ + control_para->auto_nego = EMAC_AUTO_NEGOTIATION_OFF; + control_para->auto_pad_crc_strip = FALSE; + control_para->back_off_limit = EMAC_BACKOFF_LIMIT_0; + control_para->carrier_sense_disable = FALSE; + control_para->deferral_check = FALSE; + control_para->duplex_mode = EMAC_HALF_DUPLEX; + control_para->fast_ethernet_speed = EMAC_SPEED_10MBPS; + control_para->interframe_gap = EMAC_INTERFRAME_GAP_96BIT; + control_para->ipv4_checksum_offload = FALSE; + control_para->jabber_disable = FALSE; + control_para->loopback_mode = FALSE; + control_para->receive_own_disable = FALSE; + control_para->retry_disable = FALSE; + control_para->watchdog_disable = FALSE; +} + +/** + * @brief according to hclk to set mdc clock frequency. + * @param none + * @retval none + */ +void emac_clock_range_set(void) +{ + uint8_t bits_value = 0; + crm_clocks_freq_type clocks_freq = {0}; + + /* clear clock range bits */ + EMAC->miiaddr_bit.cr = bits_value; + + crm_clocks_freq_get(&clocks_freq); + + if((clocks_freq.ahb_freq >= EMAC_HCLK_BORDER_20MHZ) && (clocks_freq.ahb_freq < EMAC_HCLK_BORDER_35MHZ)) + { + bits_value = EMAC_CLOCK_RANGE_20_TO_35; + } + else if((clocks_freq.ahb_freq >= EMAC_HCLK_BORDER_35MHZ) && (clocks_freq.ahb_freq < EMAC_HCLK_BORDER_60MHZ)) + { + bits_value = EMAC_CLOCK_RANGE_35_TO_60; + } + else if((clocks_freq.ahb_freq >= EMAC_HCLK_BORDER_60MHZ) && (clocks_freq.ahb_freq < EMAC_HCLK_BORDER_100MHZ)) + { + bits_value = EMAC_CLOCK_RANGE_60_TO_100; + } + else if((clocks_freq.ahb_freq >= EMAC_HCLK_BORDER_100MHZ) && (clocks_freq.ahb_freq < EMAC_HCLK_BORDER_150MHZ)) + { + bits_value = EMAC_CLOCK_RANGE_100_TO_150; + } + else if((clocks_freq.ahb_freq >= EMAC_HCLK_BORDER_150MHZ) && (clocks_freq.ahb_freq <= EMAC_HCLK_BORDER_240MHZ)) + { + bits_value = EMAC_CLOCK_RANGE_150_TO_240; + } + + EMAC->miiaddr_bit.cr = bits_value; +} + +/** + * @brief configure emac control setting. + * @param control_struct: control setting of mac control register. + * @retval none + */ +void emac_control_config(emac_control_config_type *control_struct) +{ + emac_deferral_check_set(control_struct->deferral_check); + emac_backoff_limit_set(control_struct->back_off_limit); + emac_auto_pad_crc_stripping_set(control_struct->auto_pad_crc_strip); + emac_retry_disable(control_struct->retry_disable); + emac_ipv4_checksum_offload_set(control_struct->ipv4_checksum_offload); + emac_loopback_mode_enable(control_struct->loopback_mode); + emac_receive_own_disable(control_struct->receive_own_disable); + emac_carrier_sense_disable(control_struct->carrier_sense_disable); + emac_interframe_gap_set(control_struct->interframe_gap); + emac_jabber_disable(control_struct->jabber_disable); + emac_watchdog_disable(control_struct->watchdog_disable); +} + +/** + * @brief reset emac dma + * @param none + * @retval none + */ +void emac_dma_software_reset_set(void) +{ + EMAC_DMA->bm_bit.swr = 1; +} + +/** + * @brief get emac dma reset status + * @param none + * @retval TRUE of FALSE + */ +flag_status emac_dma_software_reset_get(void) +{ + if(EMAC_DMA->bm_bit.swr) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief enable emac and dma reception/transmission + * @param none + * @retval none + */ +void emac_start(void) +{ + /* enable transmit state machine of the mac for transmission on the mii */ + emac_trasmitter_enable(TRUE); + + /* flush transmit fifo */ + emac_dma_operations_set(EMAC_DMA_OPS_FLUSH_TRANSMIT_FIFO, TRUE); + + /* enable receive state machine of the mac for reception from the mii */ + emac_receiver_enable(TRUE); + + /* start dma transmission */ + emac_dma_operations_set(EMAC_DMA_OPS_START_STOP_TRANSMIT, TRUE); + + /* start dma reception */ + emac_dma_operations_set(EMAC_DMA_OPS_START_STOP_RECEIVE, TRUE); +} + +/** + * @brief stop emac and dma reception/transmission + * @param none + * @retval none + */ +void emac_stop(void) +{ + /* stop dma transmission */ + emac_dma_operations_set(EMAC_DMA_OPS_START_STOP_TRANSMIT, FALSE); + + /* stop dma reception */ + emac_dma_operations_set(EMAC_DMA_OPS_START_STOP_RECEIVE, FALSE); + + /* stop receive state machine of the mac for reception from the mii */ + emac_receiver_enable(FALSE); + + /* flush transmit fifo */ + emac_dma_operations_set(EMAC_DMA_OPS_FLUSH_TRANSMIT_FIFO, TRUE); + + /* stop transmit state machine of the mac for transmission on the mii */ + emac_trasmitter_enable(FALSE); +} + +/** + * @brief write phy data. + * @param address: phy address. + * @param reg: register of phy. + * @param data: value that wants to write to phy. + * @retval SUCCESS or ERROR + */ +error_status emac_phy_register_write(uint8_t address, uint8_t reg, uint16_t data) +{ + uint32_t timeout = 0; + + EMAC->miidt_bit.md = data; + + EMAC->miiaddr_bit.pa = address; + EMAC->miiaddr_bit.mii = reg; + EMAC->miiaddr_bit.mw = 1; + EMAC->miiaddr_bit.mb = 1; + + do + { + timeout++; + } while((EMAC->miiaddr_bit.mb) && (timeout < PHY_TIMEOUT)); + + if(timeout == PHY_TIMEOUT) + { + return ERROR; + } + return SUCCESS; +} + +/** + * @brief read phy data + * @param address: phy address. + * @param reg: register of phy. + * @param data: value that is read from phy. + * @retval SUCCESS or ERROR + */ +error_status emac_phy_register_read(uint8_t address, uint8_t reg, uint16_t *data) +{ + uint32_t timeout = 0; + + EMAC->miiaddr_bit.pa = address; + EMAC->miiaddr_bit.mii = reg; + EMAC->miiaddr_bit.mw = 0; + EMAC->miiaddr_bit.mb = 1; + + do + { + timeout++; + *data = EMAC->miidt_bit.md; + } while((EMAC->miiaddr_bit.mb) && (timeout < PHY_TIMEOUT)); + + if(timeout == PHY_TIMEOUT) + { + return ERROR; + } + + *data = EMAC->miidt_bit.md; + return SUCCESS; +} + +/** + * @brief emac receiver enable. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_receiver_enable(confirm_state new_state) +{ + __IO uint32_t temp = 0; + + EMAC->ctrl_bit.re = new_state; + + temp = EMAC->ctrl; + emac_delay(1); + EMAC->ctrl = temp; +} + +/** + * @brief emac transmitter enable. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_trasmitter_enable(confirm_state new_state) +{ + __IO uint32_t temp = 0; + + EMAC->ctrl_bit.te = new_state; + + temp = EMAC->ctrl; + emac_delay(1); + EMAC->ctrl = temp; +} + +/** + * @brief emac defferal check enable, only avalible in half-duplex mode. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_deferral_check_set(confirm_state new_state) +{ + EMAC->ctrl_bit.dc = new_state; +} + +/** + * @brief emac back-off limit, only avalible in half-duplex mode. + * @param slot_time: waiting time of retransmission after collision + * this parameter can be one of the following values: + * - EMAC_BACKOFF_LIMIT_0 + * - EMAC_BACKOFF_LIMIT_1 + * - EMAC_BACKOFF_LIMIT_2 + * - EMAC_BACKOFF_LIMIT_3 + * @retval none + */ +void emac_backoff_limit_set(emac_bol_type slot_time) +{ + EMAC->ctrl_bit.bl = slot_time; +} + +/** + * @brief set mac automatic pad/CRC stripping. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_auto_pad_crc_stripping_set(confirm_state new_state) +{ + EMAC->ctrl_bit.acs = new_state; +} + +/** + * @brief transmittion retry disable. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_retry_disable(confirm_state new_state) +{ + EMAC->ctrl_bit.dr = new_state; +} + +/** + * @brief set ipv4 checksum offload. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ipv4_checksum_offload_set(confirm_state new_state) +{ + EMAC->ctrl_bit.ipc = new_state; +} + +/** + * @brief enable loopback mode. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_loopback_mode_enable(confirm_state new_state) +{ + EMAC->ctrl_bit.lm = new_state; +} + +/** + * @brief receive own disable. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_receive_own_disable(confirm_state new_state) +{ + EMAC->ctrl_bit.dro = new_state; +} + +/** + * @brief carrier sense disbale. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_carrier_sense_disable(confirm_state new_state) +{ + EMAC->ctrl_bit.dcs = new_state; +} + +/** + * @brief set minimum interframe gap between frames during transmission. + * @param number: interframe gap number. + * this parameter can be one of the following values: + * - EMAC_FRAME_GAP_96BIT + * - EMAC_FRAME_GAP_88BIT + * - EMAC_FRAME_GAP_80BIT + * - EMAC_FRAME_GAP_72BIT + * - EMAC_FRAME_GAP_64BIT + * - EMAC_FRAME_GAP_56BIT + * - EMAC_FRAME_GAP_48BIT + * - EMAC_FRAME_GAP_40BIT + * @retval none + */ +void emac_interframe_gap_set(emac_intergrame_gap_type number) +{ + EMAC->ctrl_bit.ifg = number; +} + +/** + * @brief jabber disable. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_jabber_disable(confirm_state new_state) +{ + EMAC->ctrl_bit.jd = new_state; +} + +/** + * @brief watchdog disable. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_watchdog_disable(confirm_state new_state) +{ + EMAC->ctrl_bit.wd = new_state; +} + +/** + * @brief set mac fast emac speed. + * @param speed: mac bandwidth + * this parameter can be one of the following values: + * - EMAC_SPEED_10MBPS + * - EMAC_SPEED_100MBPS + * @retval none + */ +void emac_fast_speed_set(emac_speed_type speed) +{ + EMAC->ctrl_bit.fes = speed; +} + +/** + * @brief set duplex mode. + * @param duplex_mode: communication mode + * this parameter can be one of the following values: + * - EMAC_HALF_DUPLEX + * - EMAC_FULL_DUPLEX + * @retval none + */ +void emac_duplex_mode_set(emac_duplex_type duplex_mode) +{ + EMAC->ctrl_bit.dm = duplex_mode; +} + +/** + * @brief set mac promiscuous mode. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_promiscuous_mode_set(confirm_state new_state) +{ + EMAC->frmf_bit.pr = new_state; +} + +/** + * @brief hash unicast. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_hash_unicast_set(confirm_state new_state) +{ + EMAC->frmf_bit.huc = new_state; +} + +/** + * @brief hash multicast. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_hash_multicast_set(confirm_state new_state) +{ + EMAC->frmf_bit.hmc = new_state; +} + +/** + * @brief destination address inverse filtering. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_dstaddr_inverse_filter_set(confirm_state new_state) +{ + EMAC->frmf_bit.daif = new_state; +} + +/** + * @brief pass all multicasting frames. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_pass_all_multicasting_set(confirm_state new_state) +{ + EMAC->frmf_bit.pmc = new_state; +} + +/** + * @brief broadcast frames disable. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_broadcast_frames_disable(confirm_state new_state) +{ + EMAC->frmf_bit.dbf = new_state; +} + +/** + * @brief set mac how to pass control frames. + * @param condition: set what control frame can pass filter. + * this parameter can be one of the following values: + * - EMAC_CONTROL_FRAME_PASSING_NO + * - EMAC_CONTROL_FRAME_PASSING_ALL + * - EMAC_CONTROL_FRAME_PASSING_MATCH + * @retval none + */ +void emac_pass_control_frames_set(emac_control_frames_filter_type condition) +{ + EMAC->frmf_bit.pcf = condition; +} + +/** + * @brief source address inverse filtering. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_srcaddr_inverse_filter_set(confirm_state new_state) +{ + EMAC->frmf_bit.saif = new_state; +} + +/** + * @brief source address filtering. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_srcaddr_filter_set(confirm_state new_state) +{ + EMAC->frmf_bit.saf = new_state; +} + +/** + * @brief mac uses hash or perfect filter. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_hash_perfect_filter_set(confirm_state new_state) +{ + EMAC->frmf_bit.hpf = new_state; +} + +/** + * @brief mac receives all frames. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_receive_all_set(confirm_state new_state) +{ + EMAC->frmf_bit.ra = new_state; +} + +/** + * @brief hash table high 32-bit. + * @param high32bits: the highest 32-bit of hash table. + * @retval none + */ +void emac_hash_table_high32bits_set(uint32_t high32bits) +{ + EMAC->hth_bit.hth = high32bits; +} + +/** + * @brief hash table low 32-bit. + * @param low32bits: the lowest 32-bit of hash table. + * @retval none + */ +void emac_hash_table_low32bits_set(uint32_t low32bits) +{ + EMAC->htl_bit.htl = low32bits; +} + +/** + * @brief mii busy status. + * @param none + * @retval SET or RESET + */ +flag_status emac_mii_busy_get(void) +{ + if(EMAC->miiaddr_bit.mb) { + return SET; + } + else { + return RESET; + } +} + +/** + * @brief tell phy that will be written. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_mii_write(confirm_state new_state) +{ + EMAC->miiaddr_bit.mw = new_state; +} + +/** + * @brief set flow control busy in full-duplex mode, back pressure activate in half-duplex mode. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_fcb_bpa_set(confirm_state new_state) +{ + EMAC->fctrl_bit.fcbbpa = new_state; +} + +/** + * @brief set transmit flow control. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_transmit_flow_control_enable(confirm_state new_state) +{ + EMAC->fctrl_bit.etf = new_state; +} + +/** + * @brief set receive flow control. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_receive_flow_control_enable(confirm_state new_state) +{ + EMAC->fctrl_bit.erf = new_state; +} + +/** + * @brief set unicast pause frame detect. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_unicast_pause_frame_detect(confirm_state new_state) +{ + EMAC->fctrl_bit.dup = new_state; +} + +/** + * @brief set pause low threshold. + * @param pasue_threshold: pause slot time. + * this parameter can be one of the following values: + * - EMAC_PAUSE_4_SLOT_TIME + * - EMAC_PAUSE_28_SLOT_TIME + * - EMAC_PAUSE_144_SLOT_TIME + * - EMAC_PAUSE_256_SLOT_TIME + * @retval none + */ +void emac_pause_low_threshold_set(emac_pause_slot_threshold_type pasue_threshold) +{ + EMAC->fctrl_bit.plt = pasue_threshold; +} + +/** + * @brief set zero-quanta pause disable. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_zero_quanta_pause_disable(confirm_state new_state) +{ + EMAC->fctrl_bit.dzqp = new_state; +} + +/** + * @brief set pause time. + * @param pause_time: time slots to pause transmit frame. + * @retval none + */ +void emac_pause_time_set(uint16_t pause_time) +{ + EMAC->fctrl_bit.pt = pause_time; +} + +/** + * @brief identify coming vlan frame field with setting value. + * @param identifier: it will be compared with coming frame. + * @retval none + */ +void emac_vlan_tag_identifier_set(uint16_t identifier) +{ + EMAC->vlt_bit.vti = identifier; +} + +/** + * @brief set 12-bit vlan identifier. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_vlan_tag_comparison_set(confirm_state new_state) +{ + EMAC->vlt_bit.etv = new_state; +} + +/** + * @brief set wakeup frame. + * @param value: it will be written to eight non transparent registers. + * @retval none + */ +void emac_wakeup_frame_set(uint32_t value) +{ + EMAC->rwff = value; +} + +/** + * @brief get wakeup frame. + * @param none + * @retval get value from eight non transparent registers. + */ +uint32_t emac_wakeup_frame_get(void) +{ + return (EMAC->rwff); +} + +/** + * @brief all frame will be droppped except wakeup frame or magic packet. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_power_down_set(confirm_state new_state) +{ + EMAC->pmtctrlsts_bit.pd = new_state; +} + +/** + * @brief magic packet enable + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_magic_packet_enable(confirm_state new_state) +{ + EMAC->pmtctrlsts_bit.emp = new_state; +} + +/** + * @brief wakeup frame enable + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_wakeup_frame_enable(confirm_state new_state) +{ + EMAC->pmtctrlsts_bit.erwf = new_state; +} + +/** + * @brief received magic packet + * @param none + * @retval the new state of usart_flag (SET or RESET). + */ +flag_status emac_received_magic_packet_get(void) +{ + if(EMAC->pmtctrlsts_bit.rmp) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief received wakeup frame. + * @param none + * @retval the new state of usart_flag (SET or RESET). + */ +flag_status emac_received_wakeup_frame_get(void) +{ + if(EMAC->pmtctrlsts_bit.rrwf) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief set unicast frame that passes DAF as wakeup frame. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_global_unicast_set(confirm_state new_state) +{ + EMAC->pmtctrlsts_bit.guc = new_state; +} + +/** + * @brief reset wakeup frame filter resgister + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_wakeup_frame_filter_reset(confirm_state new_state) +{ + EMAC->pmtctrlsts_bit.rwffpr = new_state; +} + +/** + * @brief read interrupt status + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - EMAC_PMT_FLAG + * - EMAC_MMC_FLAG + * - EMAC_MMCR_FLAG + * - EMAC_MMCT_FLAG + * - EMAC_TST_FLAG + * @retval the new state of usart_flag (SET or RESET). + */ +flag_status emac_interrupt_status_read(uint32_t flag) +{ + if(EMAC->ists & flag) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief set interrupt mask + * @param mask_type: mask the interrupt signal + * this parameter can be one of the following values: + * - EMAC_INTERRUPT_PMT_MASK + * - EMAC_INTERRUPT_TST_MASK + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_interrupt_mask_set(emac_interrupt_mask_type mask_type, confirm_state new_state) +{ + switch(mask_type) + { + case EMAC_INTERRUPT_PMT_MASK: + { + EMAC->imr_bit.pim = new_state; + break; + } + case EMAC_INTERRUPT_TST_MASK: + { + EMAC->imr_bit.tim = new_state; + break; + } + } +} + +/** + * @brief set local mac address + * @param address: local address for mac0 + * @retval none + */ +void emac_local_address_set(uint8_t *address) +{ + EMAC->a0h_bit.ma0h = (uint32_t)(address[5] << 8 | address[4]); + EMAC->a0l_bit.ma0l = (uint32_t)(address[3] << 24 | address[2] << 16 | address[1] << 8 | address[0]); +} + +/** + * @brief set mac filter address + * @param mac: select which mac you want to set + * this parameter can be one of the following values: + * - EMAC_ADDRESS_FILTER_1 + * - EMAC_ADDRESS_FILTER_2 + * - EMAC_ADDRESS_FILTER_3 + * @retval none + */ +void emac_address_filter_set(emac_address_type mac, emac_address_filter_type filter, emac_address_mask_type mask_bit, confirm_state new_state) +{ + switch(mac) + { + case EMAC_ADDRESS_FILTER_1: + { + EMAC->a1h_bit.sa = filter; + EMAC->a1h_bit.mbc = mask_bit; + EMAC->a1h_bit.ae = new_state; + break; + } + case EMAC_ADDRESS_FILTER_2: + { + EMAC->a2h_bit.sa = filter; + EMAC->a2h_bit.mbc = mask_bit; + EMAC->a2h_bit.ae = new_state; + break; + } + case EMAC_ADDRESS_FILTER_3: + { + EMAC->a3h_bit.sa = filter; + EMAC->a3h_bit.mbc = mask_bit; + EMAC->a3h_bit.ae = new_state; + break; + } + } +} + +/** + * @brief set transmit/receive descriptor list address + * @param transfer_type: it will be transmit or receive + * this parameter can be one of the following values: + * - EMAC_DMA_TRANSMIT + * - EMAC_DMA_RECEIVE + * @param dma_desc_tab: pointer on the first tx desc list + * @param buff: pointer on the first tx/rx buffer list + * @param buffer_count: number of the used Tx desc in the list + * @retval none + */ +void emac_dma_descriptor_list_address_set(emac_dma_tx_rx_type transfer_type, emac_dma_desc_type *dma_desc_tab, uint8_t *buff, uint32_t buffer_count) +{ + uint32_t i = 0; + emac_dma_desc_type *dma_descriptor; + + switch(transfer_type) + { + case EMAC_DMA_TRANSMIT: + { + dma_tx_desc_to_set = dma_desc_tab; + for(i = 0; i < buffer_count; i++) + { + dma_descriptor = dma_desc_tab + i; + + dma_descriptor->status = EMAC_DMATXDESC_TCH; + + dma_descriptor->buf1addr = (uint32_t)(&buff[i * EMAC_MAX_PACKET_LENGTH]); + + if(i < (buffer_count - 1)) + { + dma_descriptor->buf2nextdescaddr = (uint32_t)(dma_desc_tab + i + 1); + } + else + { + dma_descriptor->buf2nextdescaddr = (uint32_t) dma_desc_tab; + } + } + EMAC_DMA->tdladdr_bit.stl = (uint32_t) dma_desc_tab; + break; + } + case EMAC_DMA_RECEIVE: + { + dma_rx_desc_to_get = dma_desc_tab; + for(i = 0; i < buffer_count; i++) + { + dma_descriptor = dma_desc_tab + i; + + dma_descriptor->status = EMAC_DMARXDESC_OWN; + + dma_descriptor->controlsize = EMAC_DMARXDESC_RCH | (uint32_t)EMAC_MAX_PACKET_LENGTH; + + dma_descriptor->buf1addr = (uint32_t)(&buff[i * EMAC_MAX_PACKET_LENGTH]); + + if(i < (buffer_count - 1)) + { + dma_descriptor->buf2nextdescaddr = (uint32_t)(dma_desc_tab + i + 1); + } + else + { + dma_descriptor->buf2nextdescaddr = (uint32_t) dma_desc_tab; + } + } + EMAC_DMA->rdladdr_bit.srl = (uint32_t) dma_desc_tab; + break; + } + } +} + +/** + * @brief enable or disable the specified dma rx descriptor receive interrupt + * @param dma_rx_desc: pointer on a rx desc. + * @param new_state: new state of the specified dma rx descriptor interrupt. + * this parameter can be one of the following values: + * - TRUE + * - FALSE. + * @retval none + */ +void emac_dma_rx_desc_interrupt_config(emac_dma_desc_type *dma_rx_desc, confirm_state new_state) +{ + if (new_state != FALSE) + { + /* enable the dma rx desc receive interrupt */ + dma_rx_desc->controlsize &= (~(uint32_t)EMAC_DMARXDESC_DIC); + } + else + { + /* disable the dma rx desc receive interrupt */ + dma_rx_desc->controlsize |= EMAC_DMARXDESC_DIC; + } +} + +/** + * @brief get transmit/receive descriptor list address + * @param transfer_type: it will be transmit or receive + * this parameter can be one of the following values: + * - EMAC_DMA_TRANSMIT + * - EMAC_DMA_RECEIVE + * @retval transmit/receive descriptor list address + */ +uint32_t emac_dma_descriptor_list_address_get(emac_dma_tx_rx_type transfer_type) +{ + switch(transfer_type) + { + case EMAC_DMA_TRANSMIT: + { + return (EMAC_DMA->tdladdr_bit.stl); + } + case EMAC_DMA_RECEIVE: + { + return (EMAC_DMA->rdladdr_bit.srl); + } + } + return 0; +} + +/** + * @brief get the size of received the received packet. + * @param none + * @retval received packet size + */ +uint32_t emac_received_packet_size_get(void) +{ + uint32_t frame_length = 0; + if(((dma_rx_desc_to_get->status & EMAC_DMARXDESC_OWN) == (uint32_t)RESET) && + ((dma_rx_desc_to_get->status & EMAC_DMATXDESC_ES) == (uint32_t)RESET) && + ((dma_rx_desc_to_get->status & EMAC_DMARXDESC_LS) != (uint32_t)RESET) && + ((dma_rx_desc_to_get->status & EMAC_DMARXDESC_FS) != (uint32_t)RESET)) + { + frame_length = emac_dmarxdesc_frame_length_get(dma_rx_desc_to_get); + } + + return frame_length; +} + +/** + * @brief get the specified dma rx descsriptor frame length. + * @param dma_rx_desc: pointer on a dma rx descriptor + * @retval the rx descriptor received frame length. + */ +uint32_t emac_dmarxdesc_frame_length_get(emac_dma_desc_type *dma_rx_desc) +{ + return ((dma_rx_desc->status & EMAC_DMARXDESC_FL) >> EMAC_DMARXDESC_FRAME_LENGTHSHIFT); +} + +/** + * @brief init emac dma parameters + * @param emac_dma_config_type + * @retval none + */ +void emac_dma_para_init(emac_dma_config_type *control_para) +{ + control_para->aab_enable = FALSE; + control_para->da_enable = FALSE; + control_para->desc_skip_length = 0; + control_para->dt_disable = FALSE; + control_para->fb_enable = FALSE; + control_para->fef_enable = FALSE; + control_para->flush_rx_disable = FALSE; + control_para->fugf_enable = FALSE; + control_para->osf_enable = FALSE; + control_para->priority_ratio = EMAC_DMA_1_RX_1_TX; + control_para->rsf_enable = FALSE; + control_para->rx_dma_pal = EMAC_DMA_PBL_1; + control_para->rx_threshold = EMAC_DMA_RX_THRESHOLD_64_BYTES; + control_para->tsf_enable = FALSE; + control_para->tx_dma_pal = EMAC_DMA_PBL_1; + control_para->tx_threshold = EMAC_DMA_TX_THRESHOLD_64_BYTES; + control_para->usp_enable = FALSE; +} + +/** + * @brief configure emac dma + * @param emac_dma_config_type + * @retval none + */ +void emac_dma_config(emac_dma_config_type *control_para) +{ + EMAC_DMA->bm_bit.aab = control_para->aab_enable; + EMAC_DMA->bm_bit.dsl = control_para->desc_skip_length; + EMAC_DMA->bm_bit.rdp = control_para->rx_dma_pal; + EMAC_DMA->bm_bit.pbl = control_para->tx_dma_pal; + EMAC_DMA->bm_bit.fb = control_para->fb_enable; + EMAC_DMA->bm_bit.usp = control_para->usp_enable; + EMAC_DMA->bm_bit.da = control_para->da_enable; + EMAC_DMA->bm_bit.pr = control_para->priority_ratio; + + EMAC_DMA->opm_bit.dt = control_para->dt_disable; + EMAC_DMA->opm_bit.rsf = control_para->rsf_enable; + EMAC_DMA->opm_bit.dfrf = control_para->flush_rx_disable; + EMAC_DMA->opm_bit.tsf = control_para->tsf_enable; + EMAC_DMA->opm_bit.ttc = control_para->tx_threshold; + EMAC_DMA->opm_bit.fef = control_para->fef_enable; + EMAC_DMA->opm_bit.fugf = control_para->fugf_enable; + EMAC_DMA->opm_bit.rtc = control_para->rx_threshold; + EMAC_DMA->opm_bit.osf = control_para->osf_enable; +} + +/** + * @brief set rx tx priority + * @param ratio: rx tx priority ratio + * this parameter can be one of the following values: + * - EMAC_DMA_1_RX_1_TX + * - EMAC_DMA_2_RX_1_TX + * - EMAC_DMA_3_RX_1_TX + * - EMAC_DMA_4_RX_1_TX + * @param new_state: TRUE or FALSE + * @retval none + */ +void emac_dma_arbitation_set(emac_dma_rx_tx_ratio_type ratio, confirm_state new_state) +{ + EMAC_DMA->bm_bit.da = new_state; + + if(new_state) + { + EMAC_DMA->bm_bit.pr = ratio; + } +} + +/** + * @brief set descriptor skip mength + * @param length: descriptor skip length + * @retval none + */ +void emac_dma_descriptor_skip_length_set(uint8_t length) +{ + EMAC_DMA->bm_bit.dsl = length; +} + +/** + * @brief set programmable burst length + * @param tx_length: tx programmable burst length + * this parameter can be one of the following values: + * - EMAC_DMA_PBL_1 + * - EMAC_DMA_PBL_2 + * - EMAC_DMA_PBL_4 + * - EMAC_DMA_PBL_8 + * - EMAC_DMA_PBL_16 + * - EMAC_DMA_PBL_32 + * @param rx_length: rx programmable burst length + * this parameter can be one of the following values: + * - EMAC_DMA_PBL_1 + * - EMAC_DMA_PBL_2 + * - EMAC_DMA_PBL_4 + * - EMAC_DMA_PBL_8 + * - EMAC_DMA_PBL_16 + * - EMAC_DMA_PBL_32 + * @param new_state: TRUE or FALSE + * @retval none + */ +void emac_dma_separate_pbl_set(emac_dma_pbl_type tx_length, emac_dma_pbl_type rx_length, confirm_state new_state) +{ + EMAC_DMA->bm_bit.usp = new_state; + EMAC_DMA->bm_bit.pbl = tx_length; + + if(new_state) + { + EMAC_DMA->bm_bit.pbl = rx_length; + } +} + +/** + * @brief set 8 times programmable burst length + * @param new_state: TRUE or FALSE + * @retval none + */ +void emac_dma_eight_pbl_mode_set(confirm_state new_state) +{ + EMAC_DMA->bm_bit.pblx8 = new_state; +} + +/** + * @brief set address-aligned beats + * @param new_state: TRUE or FALSE + * @retval none + */ +void emac_dma_address_aligned_beats_set(confirm_state new_state) +{ + EMAC_DMA->bm_bit.aab = new_state; +} + +/** + * @brief set transmit/receive poll demand + * @param transfer_type: it will be transmit or receive + * this parameter can be one of the following values: + * - EMAC_DMA_TRANSMIT + * - EMAC_DMA_RECEIVE + * @param value: it can be any number + * @retval none + */ +void emac_dma_poll_demand_set(emac_dma_tx_rx_type transfer_type, uint32_t value) +{ + switch(transfer_type) + { + case EMAC_DMA_TRANSMIT: + { + EMAC_DMA->tpd_bit.tpd = value; + break; + } + case EMAC_DMA_RECEIVE: + { + EMAC_DMA->rpd_bit.rpd = value; + break; + } + } +} + +/** + * @brief get transmit poll demand + * @param transfer_type: it will be transmit or receive + * this parameter can be one of the following values: + * - EMAC_DMA_TRANSMIT + * - EMAC_DMA_RECEIVE + * @retval current transmit descriptor + */ +uint32_t emac_dma_poll_demand_get(emac_dma_tx_rx_type transfer_type) +{ + switch(transfer_type) + { + case EMAC_DMA_TRANSMIT: + { + return (EMAC_DMA->tpd_bit.tpd); + } + case EMAC_DMA_RECEIVE: + { + return (EMAC_DMA->rpd_bit.rpd); + } + } + return 0; +} + +/** + * @brief get receive dma process status + * @param none + * @retval every situation it describe in RM + * this parameter can be one of the following values: + * - EMAC_DMA_RX_RESET_STOP_COMMAND + * - EMAC_DMA_RX_FETCH_DESCRIPTOR + * - EMAC_DMA_RX_WAITING_PACKET + * - EMAC_DMA_RX_DESCRIPTOR_UNAVAILABLE + * - EMAC_DMA_RX_CLOSE_DESCRIPTOR + * - EMAC_DMA_RX_FIFO_TO_HOST + */ +emac_dma_receive_process_status_type emac_dma_receive_status_get(void) +{ + switch(EMAC_DMA->sts_bit.rs) + { + case EMAC_DMA_RX_RESET_STOP_COMMAND: + { + return EMAC_DMA_RX_RESET_STOP_COMMAND; + } + + case EMAC_DMA_RX_FETCH_DESCRIPTOR: + { + return EMAC_DMA_RX_FETCH_DESCRIPTOR; + } + + case EMAC_DMA_RX_WAITING_PACKET: + { + return EMAC_DMA_RX_WAITING_PACKET; + } + + case EMAC_DMA_RX_DESCRIPTOR_UNAVAILABLE: + { + return EMAC_DMA_RX_DESCRIPTOR_UNAVAILABLE; + } + + case EMAC_DMA_RX_CLOSE_DESCRIPTOR: + { + return EMAC_DMA_RX_CLOSE_DESCRIPTOR; + } + + case EMAC_DMA_RX_FIFO_TO_HOST: + { + return EMAC_DMA_RX_FIFO_TO_HOST; + } + } + + return EMAC_DMA_RX_RESET_STOP_COMMAND; +} + +/** + * @brief get transmit dma process status + * @param none + * @retval every situation it describe in RM + * this parameter can be one of the following values: + * - EMAC_DMA_TX_RESET_STOP_COMMAND + * - EMAC_DMA_TX_FETCH_DESCRIPTOR + * - EMAC_DMA_TX_WAITING_FOR_STATUS + * - EMAC_DMA_TX_HOST_TO_FIFO + * - EMAC_DMA_TX_DESCRIPTOR_UNAVAILABLE + * - EMAC_DMA_TX_CLOSE_DESCRIPTOR + */ +emac_dma_transmit_process_status_type emac_dma_transmit_status_get(void) +{ + switch(EMAC_DMA->sts_bit.ts) + { + case EMAC_DMA_TX_RESET_STOP_COMMAND: + { + return EMAC_DMA_TX_RESET_STOP_COMMAND; + } + + case EMAC_DMA_TX_FETCH_DESCRIPTOR: + { + return EMAC_DMA_TX_FETCH_DESCRIPTOR; + } + + case EMAC_DMA_TX_WAITING_FOR_STATUS: + { + return EMAC_DMA_TX_WAITING_FOR_STATUS; + } + + case EMAC_DMA_TX_HOST_TO_FIFO: + { + return EMAC_DMA_TX_HOST_TO_FIFO; + } + + case EMAC_DMA_TX_DESCRIPTOR_UNAVAILABLE: + { + return EMAC_DMA_TX_DESCRIPTOR_UNAVAILABLE; + } + + case EMAC_DMA_TX_CLOSE_DESCRIPTOR: + { + return EMAC_DMA_TX_CLOSE_DESCRIPTOR; + } + } + + return EMAC_DMA_TX_RESET_STOP_COMMAND; +} + +/** + * @brief set dma operations + * @param ops: operations of dma + * this parameter can be one of the following values: + * - EMAC_DMA_OPS_START_STOP_RECEIVE + * - EMAC_DMA_OPS_SECOND_FRAME + * - EMAC_DMA_OPS_FORWARD_UNDERSIZED + * - EMAC_DMA_OPS_FORWARD_ERROR + * - EMAC_DMA_OPS_START_STOP_TRANSMIT + * - EMAC_DMA_OPS_FLUSH_TRANSMIT_FIFO + * - EMAC_DMA_OPS_TRANSMIT_STORE_FORWARD + * - EMAC_DMA_OPS_RECEIVE_FLUSH_DISABLE + * - EMAC_DMA_OPS_RECEIVE_STORE_FORWARD + * - EMAC_DMA_OPS_DROP_ERROR_DISABLE + * @param new_state: TRUE or FALSE + * @retval none + */ +void emac_dma_operations_set(emac_dma_operations_type ops, confirm_state new_state) +{ + __IO uint32_t temp = 0; + switch(ops) + { + case EMAC_DMA_OPS_START_STOP_RECEIVE: + { + EMAC_DMA->opm_bit.ssr = new_state; + break; + } + + case EMAC_DMA_OPS_SECOND_FRAME: + { + EMAC_DMA->opm_bit.osf = new_state; + break; + } + + case EMAC_DMA_OPS_FORWARD_UNDERSIZED: + { + EMAC_DMA->opm_bit.fugf = new_state; + break; + } + + case EMAC_DMA_OPS_FORWARD_ERROR: + { + EMAC_DMA->opm_bit.fef = new_state; + break; + } + + case EMAC_DMA_OPS_START_STOP_TRANSMIT: + { + EMAC_DMA->opm_bit.sstc = new_state; + break; + } + + case EMAC_DMA_OPS_FLUSH_TRANSMIT_FIFO: + { + EMAC_DMA->opm_bit.ftf = new_state; + temp = EMAC_DMA->opm; + emac_delay(1); + EMAC_DMA->opm = temp; + break; + } + + case EMAC_DMA_OPS_TRANSMIT_STORE_FORWARD: + { + EMAC_DMA->opm_bit.tsf = new_state; + break; + } + + case EMAC_DMA_OPS_RECEIVE_FLUSH_DISABLE: + { + EMAC_DMA->opm_bit.dfrf = new_state; + break; + } + + case EMAC_DMA_OPS_RECEIVE_STORE_FORWARD: + { + EMAC_DMA->opm_bit.rsf = new_state; + break; + } + + case EMAC_DMA_OPS_DROP_ERROR_DISABLE: + { + EMAC_DMA->opm_bit.dt = new_state; + break; + } + } +} + +/** + * @brief set receive dma threshold + * @param value: receive threshold + * this parameter can be one of the following values: + * - EMAC_DMA_RX_THRESHOLD_64_BYTES + * - EMAC_DMA_RX_THRESHOLD_32_BYTES + * - EMAC_DMA_RX_THRESHOLD_96_BYTES + * - EMAC_DMA_RX_THRESHOLD_128_BYTES + * @retval none + */ +void emac_dma_receive_threshold_set(emac_dma_receive_threshold_type value) +{ + EMAC_DMA->opm_bit.rtc = value; +} + +/** + * @brief set transmit dma threshold + * @param value: transmit threshold + * this parameter can be one of the following values: + * - EMAC_DMA_TX_THRESHOLD_64_BYTES + * - EMAC_DMA_TX_THRESHOLD_128_BYTES + * - EMAC_DMA_TX_THRESHOLD_192_BYTES + * - EMAC_DMA_TX_THRESHOLD_256_BYTES + * - EMAC_DMA_TX_THRESHOLD_40_BYTES + * - EMAC_DMA_TX_THRESHOLD_32_BYTES + * - EMAC_DMA_TX_THRESHOLD_24_BYTES + * - EMAC_DMA_TX_THRESHOLD_16_BYTES + * @retval none + */ +void emac_dma_transmit_threshold_set(emac_dma_transmit_threshold_type value) +{ + EMAC_DMA->opm_bit.ttc = value; +} + +/** + * @brief enable dma interrupt + * @param it: interrupt type + * this parameter can be one of the following values: + * - EMAC_DMA_INTERRUPT_TX + * - EMAC_DMA_INTERRUPT_TX_STOP + * - EMAC_DMA_INTERRUPT_TX_UNAVAILABLE + * - EMAC_DMA_INTERRUPT_TX_JABBER + * - EMAC_DMA_INTERRUPT_RX_OVERFLOW + * - EMAC_DMA_INTERRUPT_TX_UNDERFLOW + * - EMAC_DMA_INTERRUPT_RX + * - EMAC_DMA_INTERRUPT_RX_UNAVAILABLE + * - EMAC_DMA_INTERRUPT_RX_STOP + * - EMAC_DMA_INTERRUPT_RX_TIMEOUT + * - EMAC_DMA_INTERRUPT_TX_EARLY + * - EMAC_DMA_INTERRUPT_FATAL_BUS_ERROR + * - EMAC_DMA_INTERRUPT_RX_EARLY + * - EMAC_DMA_INTERRUPT_ABNORMAL_SUMMARY + * - EMAC_DMA_INTERRUPT_NORMAL_SUMMARY + * @param new_state: TRUE or FALSE + * @retval none + */ +void emac_dma_interrupt_enable(emac_dma_interrupt_type it, confirm_state new_state) +{ + switch(it) + { + case EMAC_DMA_INTERRUPT_TX: + { + EMAC_DMA->ie_bit.tie = new_state; + break; + } + case EMAC_DMA_INTERRUPT_TX_STOP: + { + EMAC_DMA->ie_bit.tse = new_state; + break; + } + case EMAC_DMA_INTERRUPT_TX_UNAVAILABLE: + { + EMAC_DMA->ie_bit.tue = new_state; + break; + } + case EMAC_DMA_INTERRUPT_TX_JABBER: + { + EMAC_DMA->ie_bit.tje = new_state; + break; + } + case EMAC_DMA_INTERRUPT_RX_OVERFLOW: + { + EMAC_DMA->ie_bit.ove = new_state; + break; + } + case EMAC_DMA_INTERRUPT_TX_UNDERFLOW: + { + EMAC_DMA->ie_bit.une = new_state; + break; + } + case EMAC_DMA_INTERRUPT_RX: + { + EMAC_DMA->ie_bit.rie = new_state; + break; + } + case EMAC_DMA_INTERRUPT_RX_UNAVAILABLE: + { + EMAC_DMA->ie_bit.rbue = new_state; + break; + } + case EMAC_DMA_INTERRUPT_RX_STOP: + { + EMAC_DMA->ie_bit.rse = new_state; + break; + } + case EMAC_DMA_INTERRUPT_RX_TIMEOUT: + { + EMAC_DMA->ie_bit.rwte = new_state; + break; + } + case EMAC_DMA_INTERRUPT_TX_EARLY: + { + EMAC_DMA->ie_bit.eie = new_state; + break; + } + case EMAC_DMA_INTERRUPT_FATAL_BUS_ERROR: + { + EMAC_DMA->ie_bit.fbee = new_state; + break; + } + case EMAC_DMA_INTERRUPT_RX_EARLY: + { + EMAC_DMA->ie_bit.ere = new_state; + break; + } + case EMAC_DMA_INTERRUPT_ABNORMAL_SUMMARY: + { + EMAC_DMA->ie_bit.aie = new_state; + break; + } + case EMAC_DMA_INTERRUPT_NORMAL_SUMMARY: + { + EMAC_DMA->ie_bit.nie = new_state; + break; + } + } +} + +/** + * @brief get missed frames by the controller + * @param none + * @retval missed frames by the controller + */ +uint16_t emac_dma_controller_missing_frame_get(void) +{ + uint16_t number = EMAC_DMA->mfbocnt_bit.mfc; + return number; +} + +/** + * @brief get overflow bit for missed frame counter + * @param none + * @retval overflow bit for missed frame counter + */ +uint8_t emac_dma_missing_overflow_bit_get(void) +{ + uint8_t number = EMAC_DMA->mfbocnt_bit.obmfc; + return number; +} + +/** + * @brief get missed frames by the application + * @param none + * @retval missed frames by the application + */ +uint16_t emac_dma_application_missing_frame_get(void) +{ + uint16_t number = EMAC_DMA->mfbocnt_bit.ofc; + return number; +} + +/** + * @brief get overflow bit for FIFO overflow counter + * @param none + * @retval overflow bit for FIFO overflow counter + */ +uint8_t emac_dma_fifo_overflow_bit_get(void) +{ + uint8_t number = EMAC_DMA->mfbocnt_bit.obfoc; + return number; +} + +/** + * @brief get overflow bit for FIFO overflow counter + * @param transfer type: receive/transmit type + * this parameter can be one of the following values: + * - EMAC_DMA_TX_DESCRIPTOR + * - EMAC_DMA_RX_DESCRIPTOR + * - EMAC_DMA_TX_BUFFER + * - EMAC_DMA_RX_BUFFER + * @retval memory address + */ +uint32_t emac_dma_tansfer_address_get(emac_dma_transfer_address_type transfer_type) +{ + uint32_t address = 0; + + switch(transfer_type) + { + case EMAC_DMA_TX_DESCRIPTOR: + { + address = EMAC_DMA->ctd_bit.htdap; + break; + } + case EMAC_DMA_RX_DESCRIPTOR: + { + address = EMAC_DMA->crd_bit.hrdap; + break; + } + case EMAC_DMA_TX_BUFFER: + { + address = EMAC_DMA->ctbaddr_bit.htbap; + break; + } + case EMAC_DMA_RX_BUFFER: + { + address = EMAC_DMA->crbaddr_bit.hrbap; + break; + } + } + return address; +} + +/** + * @brief reset all counter + * @param none + * @retval none + */ +void emac_mmc_counter_reset(void) +{ + EMAC_MMC->ctrl_bit.rc = TRUE; +} + +/** + * @brief counter stop counting from zero when it reaches maximum + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_mmc_rollover_stop(confirm_state new_state) +{ + EMAC_MMC->ctrl_bit.scr = new_state; +} + +/** + * @brief enable reset on read + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_mmc_reset_on_read_enable(confirm_state new_state) +{ + EMAC_MMC->ctrl_bit.rr = new_state; +} + +/** + * @brief freeze mmc counter + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_mmc_counter_freeze(confirm_state new_state) +{ + EMAC_MMC->ctrl_bit.fmc = new_state; +} + +/** + * @brief interupt status of received frames + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - MMC_RX_CRC_ERROR + * - MMC_RX_ALIGN_ERROR + * - MMC_RX_GOOD_UNICAST + * @retval the new state of usart_flag (SET or RESET). + */ +flag_status emac_mmc_received_status_get(uint32_t flag) +{ + if(EMAC_MMC->ri & flag) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief interupt status of transmit frames + * @param transmit_type: transmit type. + * this parameter can be one of the following values: + * - MMC_TX_SINGLE_COL + * - MMC_TX_MULTIPLE_COL + * - MMC_TX_GOOD_FRAMES + * @retval the new state of usart_flag (SET or RESET). + */ +flag_status emac_mmc_transmit_status_get(uint32_t flag) +{ + if(EMAC_MMC->ti & flag) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief mask received mmc interrupt + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - MMC_RX_CRC_ERROR + * - MMC_RX_ALIGN_ERROR + * - MMC_RX_GOOD_UNICAST + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_mmc_received_interrupt_mask_set(uint32_t flag, confirm_state new_state) +{ + switch(flag) + { + case MMC_RX_CRC_ERROR: + { + EMAC_MMC->rim_bit.rcefcim = new_state; + break; + } + case MMC_RX_ALIGN_ERROR: + { + EMAC_MMC->rim_bit.raefacim = new_state; + break; + } + case MMC_RX_GOOD_UNICAST: + { + EMAC_MMC->rim_bit.rugfcim = new_state; + break; + } + } +} + +/** + * @brief mask transmit mmc interrupt + * @param transmit_type: transmit type. + * this parameter can be one of the following values: + * - MMC_TX_SINGLE_COL + * - MMC_TX_MULTIPLE_COL + * - MMC_TX_GOOD_FRAMES + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_mmc_transmit_interrupt_mask_set(uint32_t flag, confirm_state new_state) +{ + switch(flag) + { + case MMC_TX_SINGLE_COL: + { + EMAC_MMC->tim_bit.tscgfcim = new_state; + break; + } + case MMC_TX_MULTIPLE_COL: + { + EMAC_MMC->tim_bit.tmcgfcim = new_state; + break; + } + case MMC_TX_GOOD_FRAMES: + { + EMAC_MMC->tim_bit.tgfcim = new_state; + break; + } + } +} + +/** + * @brief get good frame numbers as single collision occurs. + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - MMC_TX_SINGLE_COL + * - MMC_TX_MULTIPLE_COL + * - MMC_TX_GOOD_FRAMES + * @retval good frames + */ +uint32_t emac_mmc_transmit_good_frames_get(uint32_t flag) +{ + uint32_t good_frames = MMC_TX_GOOD_FRAMES; + + switch(flag) + { + case MMC_TX_SINGLE_COL: + { + good_frames = EMAC_MMC->tfscc_bit.tgfscc; + break; + } + case MMC_TX_MULTIPLE_COL: + { + good_frames = EMAC_MMC->tfmscc_bit.tgfmscc; + break; + } + case MMC_TX_GOOD_FRAMES: + { + good_frames = EMAC_MMC->tfcnt_bit.tgfc; + break; + } + } + return good_frames; +} + +/** + * @brief get good frame numbers as single collision occurs. + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - MMC_RX_CRC_ERROR + * - MMC_RX_ALIGN_ERROR + * - MMC_RX_GOOD_UNICAST + * @retval good frames + */ +uint32_t emac_mmc_received_error_frames_get(uint32_t flag) +{ + uint32_t error_frames = MMC_RX_GOOD_UNICAST; + + switch(flag) + { + case MMC_RX_CRC_ERROR: + { + error_frames = EMAC_MMC->rfcecnt_bit.rfcec; + break; + } + case MMC_RX_ALIGN_ERROR: + { + error_frames = EMAC_MMC->rfaecnt_bit.rfaec; + break; + } + case MMC_RX_GOOD_UNICAST: + { + error_frames = EMAC_MMC->rgufcnt_bit.rgufc; + break; + } + } + return error_frames; +} + +/** + * @brief enable timestamp. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_timestamp_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.te = new_state; +} + +/** + * @brief enable timestamp fine update. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_timestamp_fine_update_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.tfcu = new_state; +} + +/** + * @brief initialize timestamp time system. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_timestamp_system_time_init(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.ti = new_state; +} + +/** + * @brief update timestamp time system. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_timestamp_system_time_update(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.tu = new_state; +} + +/** + * @brief enable timestamp interrupt trigger. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_interrupt_trigger_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.tite = new_state; +} + +/** + * @brief update timestamp addend register. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_addend_register_update(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.aru = new_state; +} + +/** + * @brief enable timestamp snapshot for all received frames. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_snapshot_received_frames_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.etaf = new_state; +} + +/** + * @brief enable digital rollover. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_subsecond_rollover_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.tdbrc = new_state; +} + +/** + * @brief enable packet snooping for version 2. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_psv2_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.eppv2f = new_state; +} + +/** + * @brief enable snapshot over emac. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_snapshot_emac_frames_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.eppef = new_state; +} + +/** + * @brief enable snapshot for ipv6 frames. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_snapshot_ipv6_frames_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.eppfsip6u = new_state; +} + +/** + * @brief enable snapshot for ipv4 frames. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_snapshot_ipv4_frames_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.eppfsip4u = new_state; +} + +/** + * @brief enable snapshot for event message. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_snapshot_event_message_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.etsfem = new_state; +} + +/** + * @brief enable snapshot for message relevant to master + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_snapshot_master_event_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.esfmrtm = new_state; +} + +/** + * @brief set clock node type + * @param node: select ptp packets for taking snapshot + * this parameter can be one of the following values: + * - EMAC_PTP_NORMAL_CLOCK + * - EMAC_PTP_BOUNDARY_CLOCK + * - EMAC_PTP_END_TO_END_CLOCK + * - EMAC_PTP_PEER_TO_PEER_CLOCK + * @retval none + */ +void emac_ptp_clock_node_set(emac_ptp_clock_node_type node) +{ + EMAC_PTP->tsctrl_bit.sppfts = node; +} + +/** + * @brief enable ptp frame filtering mac address + * @param new_state: TRUE or FALSE. + * @retval none + */ +void emac_ptp_mac_address_filter_enable(confirm_state new_state) +{ + EMAC_PTP->tsctrl_bit.emafpff = new_state; +} + +/** + * @brief set subsecond increment value + * @param value: add to subsecond value for every update + * @retval none + */ +void emac_ptp_subsecond_increment_set(uint8_t value) +{ + EMAC_PTP->ssinc_bit.ssiv = value; +} + +/** + * @brief get system time second + * @param none + * @retval system time second + */ +uint32_t emac_ptp_system_second_get(void) +{ + uint32_t second = EMAC_PTP->tsh_bit.ts; + return second; +} + +/** + * @brief get system time subsecond + * @param none + * @retval system time subsecond + */ +uint32_t emac_ptp_system_subsecond_get(void) +{ + uint32_t subsecond = EMAC_PTP->tsl_bit.tss; + return subsecond; +} + +/** + * @brief get system time sign + * @param none + * @retval TRUE or FALSE + */ +confirm_state emac_ptp_system_time_sign_get(void) +{ + if(EMAC_PTP->tsl_bit.ast) + { + return TRUE; + } + else + { + return FALSE; + } +} + +/** + * @brief set system time second + * @param second: system time second + * @retval none + */ +void emac_ptp_system_second_set(uint32_t second) +{ + EMAC_PTP->tshud_bit.ts = second; +} + +/** + * @brief set system time subsecond + * @param subsecond: system time subsecond + * @retval none + */ +void emac_ptp_system_subsecond_set(uint32_t subsecond) +{ + EMAC_PTP->tslud_bit.tss = subsecond; +} + +/** + * @brief set system time sign + * @param sign: TRUE or FALSE. + * @retval none + */ +void emac_ptp_system_time_sign_set(confirm_state sign) +{ + if(sign) + { + EMAC_PTP->tslud_bit.ast = 1; + } + else + { + EMAC_PTP->tslud_bit.ast = 0; + } +} + +/** + * @brief set time stamp addend + * @param value: to achieve time synchronization + * @retval none + */ +void emac_ptp_timestamp_addend_set(uint32_t value) +{ + EMAC_PTP->tsad_bit.tar = value; +} + +/** + * @brief set target time stamp high + * @param value: to set target time second + * @retval none + */ +void emac_ptp_target_second_set(uint32_t value) +{ + EMAC_PTP->tth_bit.ttsr = value; +} + +/** + * @brief set target time stamp low + * @param value: to set target time nanosecond + * @retval none + */ +void emac_ptp_target_nanosecond_set(uint32_t value) +{ + EMAC_PTP->ttl_bit.ttlr = value; +} + +/** + * @brief set target time stamp low + * @param status: type of status + * this parameter can be one of the following values: + * - EMAC_PTP_SECOND_OVERFLOW + * - EMAC_PTP_TARGET_TIME_REACH + * @retval TRUE or FALSE + */ +confirm_state emac_ptp_timestamp_status_get(emac_ptp_timestamp_status_type status) +{ + switch(status) + { + case EMAC_PTP_SECOND_OVERFLOW: + { + if(EMAC_PTP->tssr_bit.tso) + { + return TRUE; + } + else + { + return FALSE; + } + } + case EMAC_PTP_TARGET_TIME_REACH: + { + if(EMAC_PTP->tssr_bit.tttr) + { + return TRUE; + } + else + { + return FALSE; + } + } + } + return FALSE; +} + +/** + * @brief set pps frequency + * @param freq: pps frequency + * this parameter can be one of the following values: + * - EMAC_PTP_PPS_1HZ + * - EMAC_PTP_PPS_2HZ + * - EMAC_PTP_PPS_4HZ + * - EMAC_PTP_PPS_8HZ + * - EMAC_PTP_PPS_16HZ + * - EMAC_PTP_PPS_32HZ + * - EMAC_PTP_PPS_64HZ + * - EMAC_PTP_PPS_128HZ + * - EMAC_PTP_PPS_256HZ + * - EMAC_PTP_PPS_512HZ + * - EMAC_PTP_PPS_1024HZ + * - EMAC_PTP_PPS_2048HZ + * - EMAC_PTP_PPS_4096HZ + * - EMAC_PTP_PPS_8192HZ + * - EMAC_PTP_PPS_16384HZ + * - EMAC_PTP_PPS_32768HZ + * @retval none + */ +void emac_ptp_pps_frequency_set(emac_ptp_pps_control_type freq) +{ + EMAC_PTP->ppscr_bit.pofc = freq; +} + +/** + * @brief this is delay function base on system clock. + * @param delay: delay time + * @retval none + */ +static void emac_delay(uint32_t delay) +{ + __IO uint32_t delay_time = delay * (system_core_clock / 8 / 1000); + do + { + __NOP(); + } + while(delay_time --); +} + +/** + * @brief check whether the specified emac dma flag is set or not. + * @param dma_flag: specifies the emac dma flag to check. + * this parameter can be one of emac dma flag status: + * - EMAC_DMA_TI_FLAG + * - EMAC_DMA_TPS_FLAG + * - EMAC_DMA_TBU_FLAG + * - EMAC_DMA_TJT_FLAG + * - EMAC_DMA_OVF_FLAG + * - EMAC_DMA_UNF_FLAG + * - EMAC_DMA_RI_FLAG + * - EMAC_DMA_RBU_FLAG + * - EMAC_DMA_RPS_FLAG + * - EMAC_DMA_RWT_FLAG + * - EMAC_DMA_ETI_FLAG + * - EMAC_DMA_FBEI_FLAG + * - EMAC_DMA_ERI_FLAG + * - EMAC_DMA_AIS_FLAG + * - EMAC_DMA_NIS_FLAG + * @retval the new state of dma_flag (SET or RESET). + */ +flag_status emac_dma_flag_get(uint32_t dma_flag) +{ + flag_status status = RESET; + + if(EMAC_DMA->sts & dma_flag) + status = SET; + /* return the new state (SET or RESET) */ + return status; +} + +/** + * @brief clear the emac dma flag. + * @param dma_flag: specifies the emac dma flags to clear. + * this parameter can be any combination of the following values: + * - EMAC_DMA_TI_FLAG + * - EMAC_DMA_TPS_FLAG + * - EMAC_DMA_TBU_FLAG + * - EMAC_DMA_TJT_FLAG + * - EMAC_DMA_OVF_FLAG + * - EMAC_DMA_UNF_FLAG + * - EMAC_DMA_RI_FLAG + * - EMAC_DMA_RBU_FLAG + * - EMAC_DMA_RPS_FLAG + * - EMAC_DMA_RWT_FLAG + * - EMAC_DMA_ETI_FLAG + * - EMAC_DMA_FBEI_FLAG + * - EMAC_DMA_ERI_FLAG + * - EMAC_DMA_AIS_FLAG + * - EMAC_DMA_NIS_FLAG + * @retval none + */ +void emac_dma_flag_clear(uint32_t dma_flag) +{ + EMAC_DMA->sts = dma_flag; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +#endif + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_exint.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_exint.c new file mode 100644 index 0000000..c6ef1c3 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_exint.c @@ -0,0 +1,236 @@ +/** + ************************************************************************** + * @file at32f403a_407_exint.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the exint firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup EXINT + * @brief EXINT driver modules + * @{ + */ + +#ifdef EXINT_MODULE_ENABLED + +/** @defgroup EXINT_private_functions + * @{ + */ + +/** + * @brief exint reset + * @param none + * @retval none + */ +void exint_reset(void) +{ + EXINT->inten = 0x00000000; + EXINT->polcfg1 = 0x00000000; + EXINT->polcfg2 = 0x00000000; + EXINT->evten = 0x00000000; + EXINT->intsts = 0x000FFFFF; +} + +/** + * @brief exint default para init + * @param exint_struct + * - to the structure of exint_init_type + * @retval none + */ +void exint_default_para_init(exint_init_type *exint_struct) +{ + exint_struct->line_enable = FALSE; + exint_struct->line_select = EXINT_LINE_NONE; + exint_struct->line_polarity = EXINT_TRIGGER_FALLING_EDGE; + exint_struct->line_mode = EXINT_LINE_EVENT; +} + +/** + * @brief exint init + * @param exint_struct + * - to the structure of exint_init_type + * @retval none + */ +void exint_init(exint_init_type *exint_struct) +{ + uint32_t line_index = 0; + line_index = exint_struct->line_select; + + EXINT->inten &= ~line_index; + EXINT->evten &= ~line_index; + + if(exint_struct->line_enable != FALSE) + { + if(exint_struct->line_mode == EXINT_LINE_INTERRUPUT) + { + EXINT->inten |= line_index; + } + else + { + EXINT->evten |= line_index; + } + + EXINT->polcfg1 &= ~line_index; + EXINT->polcfg2 &= ~line_index; + if(exint_struct->line_polarity == EXINT_TRIGGER_RISING_EDGE) + { + EXINT->polcfg1 |= line_index; + } + else if(exint_struct->line_polarity == EXINT_TRIGGER_FALLING_EDGE) + { + EXINT->polcfg2 |= line_index; + } + else + { + EXINT->polcfg1 |= line_index; + EXINT->polcfg2 |= line_index; + } + } +} + +/** + * @brief clear exint flag + * @param exint_line + * this parameter can be any combination of the following values: + * - EXINT_LINE_0 + * - EXINT_LINE_1 + * ... + * - EXINT_LINE_18 + * - EXINT_LINE_19 + * @retval none + */ +void exint_flag_clear(uint32_t exint_line) +{ + EXINT->intsts = exint_line; +} + +/** + * @brief get exint flag + * @param exint_line + * this parameter can be one of the following values: + * - EXINT_LINE_0 + * - EXINT_LINE_1 + * ... + * - EXINT_LINE_18 + * - EXINT_LINE_19 + * @retval the new state of exint flag(SET or RESET). + */ +flag_status exint_flag_get(uint32_t exint_line) +{ + flag_status status = RESET; + uint32_t exint_flag =0; + exint_flag = EXINT->intsts & exint_line; + if((exint_flag != (uint16_t)RESET)) + { + status = SET; + } + else + { + status = RESET; + } + return status; +} + +/** + * @brief generate exint software interrupt event + * @param exint_line + * this parameter can be one of the following values: + * - EXINT_LINE_0 + * - EXINT_LINE_1 + * ... + * - EXINT_LINE_18 + * - EXINT_LINE_19 + * @retval none + */ +void exint_software_interrupt_event_generate(uint32_t exint_line) +{ + EXINT->swtrg |= exint_line; +} + +/** + * @brief enable or disable exint interrupt + * @param exint_line + * this parameter can be any combination of the following values: + * - EXINT_LINE_0 + * - EXINT_LINE_1 + * ... + * - EXINT_LINE_18 + * - EXINT_LINE_19 + * @param new_state: new state of exint interrupt. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void exint_interrupt_enable(uint32_t exint_line, confirm_state new_state) +{ + if(new_state == TRUE) + { + EXINT->inten |= exint_line; + } + else + { + EXINT->inten &= ~exint_line; + } +} + +/** + * @brief enable or disable exint event + * @param exint_line + * this parameter can be any combination of the following values: + * - EXINT_LINE_0 + * - EXINT_LINE_1 + * ... + * - EXINT_LINE_18 + * - EXINT_LINE_19 + * @param new_state: new state of exint event. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void exint_event_enable(uint32_t exint_line, confirm_state new_state) +{ + if(new_state == TRUE) + { + EXINT->evten |= exint_line; + } + else + { + EXINT->evten &= ~exint_line; + } +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_flash.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_flash.c new file mode 100644 index 0000000..98e7cb9 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_flash.c @@ -0,0 +1,1284 @@ +/** + ************************************************************************** + * @file at32f403a_407_flash.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the flash firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup FLASH + * @brief FLASH driver modules + * @{ + */ + +#ifdef FLASH_MODULE_ENABLED + +/** @defgroup FLASH_private_functions + * @{ + */ + +/** + * @brief check whether the specified flash flag is set or not. + * @param flash_flag: specifies the flash flag to check. + * this parameter can be one of flash flag status: + * - FLASH_OBF_FLAG + * - FLASH_ODF_FLAG + * - FLASH_PRGMERR_FLAG + * - FLASH_EPPERR_FLAG + * - FLASH_BANK1_OBF_FLAG + * - FLASH_BANK1_ODF_FLAG + * - FLASH_BANK1_PRGMERR_FLAG + * - FLASH_BANK1_EPPERR_FLAG + * - FLASH_BANK2_OBF_FLAG + * - FLASH_BANK2_ODF_FLAG + * - FLASH_BANK2_PRGMERR_FLAG + * - FLASH_BANK2_EPPERR_FLAG + * - FLASH_SPIM_OBF_FLAG + * - FLASH_SPIM_ODF_FLAG + * - FLASH_SPIM_PRGMERR_FLAG + * - FLASH_SPIM_EPPERR_FLAG + * - FLASH_USDERR_FLAG + * @retval the new state of flash_flag (SET or RESET). + */ +flag_status flash_flag_get(uint32_t flash_flag) +{ + flag_status status = RESET; + uint32_t flag_position; + flag_position = flash_flag & 0x70000000; + flash_flag &= 0x8FFFFFFF; + switch(flag_position) + { + case 0x00000000: + if(FLASH->sts & flash_flag) + status = SET; + break; + case 0x10000000: + if(FLASH->sts2 & flash_flag) + status = SET; + break; + case 0x20000000: + if(FLASH->sts3 & flash_flag) + status = SET; + break; + case 0x40000000: + if(FLASH->usd & flash_flag) + status = SET; + break; + default: + break; + } + /* return the new state of flash_flag (SET or RESET) */ + return status; +} + +/** + * @brief clear the flash flag. + * @param flash_flag: specifies the flash flags to clear. + * this parameter can be any combination of the following values: + * - FLASH_ODF_FLAG + * - FLASH_PRGMERR_FLAG + * - FLASH_EPPERR_FLAG + * - FLASH_BANK1_ODF_FLAG + * - FLASH_BANK1_PRGMERR_FLAG + * - FLASH_BANK1_EPPERR_FLAG + * - FLASH_BANK2_ODF_FLAG + * - FLASH_BANK2_PRGMERR_FLAG + * - FLASH_BANK2_EPPERR_FLAG + * - FLASH_SPIM_ODF_FLAG + * - FLASH_SPIM_PRGMERR_FLAG + * - FLASH_SPIM_EPPERR_FLAG + * @retval none + */ +void flash_flag_clear(uint32_t flash_flag) +{ + uint32_t flag_position; + flag_position = flash_flag & 0x70000000; + flash_flag &= 0x8FFFFFFF; + switch(flag_position) + { + case 0x00000000: + FLASH->sts = flash_flag; + break; + case 0x10000000: + FLASH->sts2 = flash_flag; + break; + case 0x20000000: + FLASH->sts3 = flash_flag; + break; + default: + break; + } +} + +/** + * @brief return the flash operation status. + * @param none + * @retval status: the returned value can be: FLASH_OPERATE_BUSY, + * FLASH_PROGRAM_ERROR, FLASH_EPP_ERROR or FLASH_OPERATE_DONE. + */ +flash_status_type flash_operation_status_get(void) +{ + flash_status_type flash_status = FLASH_OPERATE_DONE; + if(FLASH->sts_bit.obf != RESET) + { + flash_status = FLASH_OPERATE_BUSY; + } + else if(FLASH->sts_bit.prgmerr != RESET) + { + flash_status = FLASH_PROGRAM_ERROR; + } + else if(FLASH->sts_bit.epperr != RESET) + { + flash_status = FLASH_EPP_ERROR; + } + else + { + flash_status = FLASH_OPERATE_DONE; + } + /* return the flash status */ + return flash_status; +} + +/** + * @brief return the flash bank1 operation status. + * @param none + * @retval status: the returned value can be: FLASH_OPERATE_BUSY, + * FLASH_PROGRAM_ERROR, FLASH_EPP_ERROR or FLASH_OPERATE_DONE. + */ +flash_status_type flash_bank1_operation_status_get(void) +{ + flash_status_type flash_status = FLASH_OPERATE_DONE; + if(FLASH->sts_bit.obf != RESET) + { + flash_status = FLASH_OPERATE_BUSY; + } + else if(FLASH->sts_bit.prgmerr != RESET) + { + flash_status = FLASH_PROGRAM_ERROR; + } + else if(FLASH->sts_bit.epperr != RESET) + { + flash_status = FLASH_EPP_ERROR; + } + else + { + flash_status = FLASH_OPERATE_DONE; + } + /* return the flash status */ + return flash_status; +} + +/** + * @brief return the flash bank2 operation status. + * @param none + * @retval status: the returned value can be: FLASH_OPERATE_BUSY, + * FLASH_PROGRAM_ERROR, FLASH_EPP_ERROR or FLASH_OPERATE_DONE. + */ +flash_status_type flash_bank2_operation_status_get(void) +{ + flash_status_type flash_status = FLASH_OPERATE_DONE; + if(FLASH->sts2_bit.obf != RESET) + { + flash_status = FLASH_OPERATE_BUSY; + } + else if(FLASH->sts2_bit.prgmerr != RESET) + { + flash_status = FLASH_PROGRAM_ERROR; + } + else if(FLASH->sts2_bit.epperr != RESET) + { + flash_status = FLASH_EPP_ERROR; + } + else + { + flash_status = FLASH_OPERATE_DONE; + } + /* return the flash status */ + return flash_status; +} + +/** + * @brief return the flash spim operation status. + * @param none + * @retval status: the returned value can be: FLASH_OPERATE_BUSY, + * FLASH_PROGRAM_ERROR, FLASH_EPP_ERROR or FLASH_OPERATE_DONE. + */ +flash_status_type flash_spim_operation_status_get(void) +{ + flash_status_type flash_status = FLASH_OPERATE_DONE; + if(FLASH->sts3_bit.obf != RESET) + { + flash_status = FLASH_OPERATE_BUSY; + } + else if(FLASH->sts3_bit.prgmerr != RESET) + { + flash_status = FLASH_PROGRAM_ERROR; + } + else if(FLASH->sts3_bit.epperr != RESET) + { + flash_status = FLASH_EPP_ERROR; + } + else + { + flash_status = FLASH_OPERATE_DONE; + } + /* return the flash status */ + return flash_status; +} + +/** + * @brief wait for flash operation complete or timeout. + * @param time_out: flash operation timeout + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_operation_wait_for(uint32_t time_out) +{ + flash_status_type status = FLASH_OPERATE_DONE; + /* check for the flash status */ + status = flash_operation_status_get(); + + while((status == FLASH_OPERATE_BUSY) && (time_out != 0x00)) + { + status = flash_operation_status_get(); + time_out--; + } + if(time_out == 0x00) + { + status = FLASH_OPERATE_TIMEOUT; + } + /* return the status */ + return status; +} + +/** + * @brief wait for flash bank1 operation complete or timeout. + * @param time_out: flash operation timeout + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_bank1_operation_wait_for(uint32_t time_out) +{ + flash_status_type status = FLASH_OPERATE_DONE; + /* check for the flash status */ + status = flash_bank1_operation_status_get(); + + while((status == FLASH_OPERATE_BUSY) && (time_out != 0x00)) + { + status = flash_bank1_operation_status_get(); + time_out--; + } + if(time_out == 0x00) + { + status = FLASH_OPERATE_TIMEOUT; + } + /* return the operation status */ + return status; +} + +/** + * @brief wait for flash bank2 operation complete or timeout. + * @param time_out: flash operation timeout + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_bank2_operation_wait_for(uint32_t time_out) +{ + flash_status_type status = FLASH_OPERATE_DONE; + /* check for the flash status */ + status = flash_bank2_operation_status_get(); + + while((status == FLASH_OPERATE_BUSY) && (time_out != 0x00)) + { + status = flash_bank2_operation_status_get(); + time_out--; + } + if(time_out == 0x00) + { + status = FLASH_OPERATE_TIMEOUT; + } + /* return the operation status */ + return status; +} + +/** + * @brief wait for flash spim operation complete or timeout. + * @param time_out: flash operation timeout + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_spim_operation_wait_for(uint32_t time_out) +{ + flash_status_type status = FLASH_OPERATE_DONE; + /* check for the flash status */ + status = flash_spim_operation_status_get(); + + while((status == FLASH_OPERATE_BUSY) && (time_out != 0x00)) + { + status = flash_spim_operation_status_get(); + time_out--; + } + if(time_out == 0x00) + { + status = FLASH_OPERATE_TIMEOUT; + } + /* return the operation status */ + return status; +} + +/** + * @brief unlock the flash controller. + * @param none + * @retval none + */ +void flash_unlock(void) +{ + FLASH->unlock = FLASH_UNLOCK_KEY1; + FLASH->unlock = FLASH_UNLOCK_KEY2; + FLASH->unlock2 = FLASH_UNLOCK_KEY1; + FLASH->unlock2 = FLASH_UNLOCK_KEY2; +} + +/** + * @brief unlock the flash bank1 controller. + * @param none + * @retval none + */ +void flash_bank1_unlock(void) +{ + FLASH->unlock = FLASH_UNLOCK_KEY1; + FLASH->unlock = FLASH_UNLOCK_KEY2; +} + +/** + * @brief unlock the flash bank2 controller. + * @param none + * @retval none + */ +void flash_bank2_unlock(void) +{ + FLASH->unlock2 = FLASH_UNLOCK_KEY1; + FLASH->unlock2 = FLASH_UNLOCK_KEY2; +} + +/** + * @brief unlock the flash spim controller. + * @param none + * @retval none + */ +void flash_spim_unlock(void) +{ + FLASH->unlock3 = FLASH_UNLOCK_KEY1; + FLASH->unlock3 = FLASH_UNLOCK_KEY2; +} + +/** + * @brief lock the flash controller. + * @param none + * @retval none + */ +void flash_lock(void) +{ + FLASH->ctrl_bit.oplk = TRUE; + FLASH->ctrl2_bit.oplk = TRUE; +} + +/** + * @brief lock the flash bank1 controller. + * @param none + * @retval none + */ +void flash_bank1_lock(void) +{ + FLASH->ctrl_bit.oplk = TRUE; +} + +/** + * @brief lock the flash bank2 controller. + * @param none + * @retval none + */ +void flash_bank2_lock(void) +{ + FLASH->ctrl2_bit.oplk = TRUE; +} + +/** + * @brief lock the flash spim controller. + * @param none + * @retval none + */ +void flash_spim_lock(void) +{ + FLASH->ctrl3_bit.oplk = TRUE; +} + +/** + * @brief erase a specified flash sector. + * @param sector_address: the sector address to be erased. + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_sector_erase(uint32_t sector_address) +{ + flash_status_type status = FLASH_OPERATE_DONE; + if((sector_address >= FLASH_BANK1_START_ADDR) && (sector_address <= FLASH_BANK1_END_ADDR)) + { + /* wait for last operation to be completed */ + status = flash_bank1_operation_wait_for(ERASE_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + /* if the previous operation is completed, continue to erase the sector */ + FLASH->ctrl_bit.secers = TRUE; + FLASH->addr = sector_address; + FLASH->ctrl_bit.erstr = TRUE; + + /* wait for operation to be completed */ + status = flash_bank1_operation_wait_for(ERASE_TIMEOUT); + + /* disable the secers bit */ + FLASH->ctrl_bit.secers = FALSE; + } + } + else if((sector_address >= FLASH_BANK2_START_ADDR) && (sector_address <= FLASH_BANK2_END_ADDR)) + { + /* wait for last operation to be completed */ + status = flash_bank2_operation_wait_for(ERASE_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + /* if the previous operation is completed, continue to erase the sector */ + FLASH->ctrl2_bit.secers = TRUE; + FLASH->addr2 = sector_address; + FLASH->ctrl2_bit.erstr = TRUE; + + /* wait for operation to be completed */ + status = flash_bank2_operation_wait_for(ERASE_TIMEOUT); + + /* disable the secers bit */ + FLASH->ctrl2_bit.secers = FALSE; + } + } + /* spim : external flash */ + else if(sector_address >= FLASH_SPIM_START_ADDR) + { + /* wait for last operation to be completed */ + status = flash_spim_operation_wait_for(SPIM_ERASE_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + /* if the previous operation is completed, continue to erase the sector */ + FLASH->ctrl3_bit.secers = TRUE; + FLASH->addr3 = sector_address; + FLASH->ctrl3_bit.erstr = TRUE; + + /* wait for operation to be completed */ + status = flash_spim_operation_wait_for(SPIM_ERASE_TIMEOUT); + + /* disable the secers bit */ + FLASH->ctrl3_bit.secers = FALSE; + } + return status; + } + + /* return the erase status */ + return status; +} + +/** + * @brief erase flash all internal sectors. + * @param none + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_internal_all_erase(void) +{ + flash_status_type status = FLASH_OPERATE_DONE; + /* wait for last operation to be completed */ + status = flash_bank1_operation_wait_for(ERASE_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + /* if the previous operation is completed, continue to erase bank1 */ + FLASH->ctrl_bit.bankers = TRUE; + FLASH->ctrl_bit.erstr = TRUE; + + /* wait for operation to be completed */ + status = flash_bank1_operation_wait_for(ERASE_TIMEOUT); + + /* disable the bankers bit */ + FLASH->ctrl_bit.bankers = FALSE; + } + if(status == FLASH_OPERATE_DONE) + { + /* if the previous operation is completed, continue to erase bank2 */ + FLASH->ctrl2_bit.bankers = TRUE; + FLASH->ctrl2_bit.erstr = TRUE; + + /* wait for operation to be completed */ + status = flash_bank2_operation_wait_for(ERASE_TIMEOUT); + + /* disable the bankers bit */ + FLASH->ctrl2_bit.bankers = FALSE; + } + /* return the erase status */ + return status; +} + +/** + * @brief erase flash bank1 sectors. + * @param none + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_bank1_erase(void) +{ + flash_status_type status = FLASH_OPERATE_DONE; + /* wait for last operation to be completed */ + status = flash_bank1_operation_wait_for(ERASE_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + /* if the previous operation is completed, continue to erase bank1 */ + FLASH->ctrl_bit.bankers = TRUE; + FLASH->ctrl_bit.erstr = TRUE; + + /* wait for operation to be completed */ + status = flash_bank1_operation_wait_for(ERASE_TIMEOUT); + + /* disable the bankers bit */ + FLASH->ctrl_bit.bankers = FALSE; + } + /* return the erase status */ + return status; +} + +/** + * @brief erase flash bank2 sectors. + * @param none + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_bank2_erase(void) +{ + flash_status_type status = FLASH_OPERATE_DONE; + /* wait for last operation to be completed */ + status = flash_bank2_operation_wait_for(ERASE_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + /* if the previous operation is completed, continue to erase bank2 */ + FLASH->ctrl2_bit.bankers = TRUE; + FLASH->ctrl2_bit.erstr = TRUE; + + /* wait for operation to be completed */ + status = flash_bank2_operation_wait_for(ERASE_TIMEOUT); + + /* disable the bankers bit */ + FLASH->ctrl2_bit.bankers = FALSE; + } + /* return the erase status */ + return status; +} + +/** + * @brief erase flash spim sectors. + * @param none + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_spim_all_erase(void) +{ + flash_status_type status = FLASH_OPERATE_DONE; + /* wait for last operation to be completed */ + status = flash_spim_operation_wait_for(SPIM_ERASE_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + /* if the previous operation is completed, continue to erase spim */ + FLASH->ctrl3_bit.chpers = TRUE; + FLASH->ctrl3_bit.erstr = TRUE; + + /* wait for operation to be completed */ + status = flash_spim_operation_wait_for(SPIM_ERASE_TIMEOUT); + + /* disable the chpers bit */ + FLASH->ctrl3_bit.chpers = FALSE; + } + /* return the erase status */ + return status; +} + +/** + * @brief erase the flash user system data. + * @note this functions erases all user system data except the fap byte. + * @param none + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_user_system_data_erase(void) +{ + flash_status_type status = FLASH_OPERATE_DONE; + uint16_t fap_val = FAP_RELIEVE_KEY; + /* get the flash access protection status */ + if(flash_fap_status_get() != RESET) + { + fap_val = 0x0000; + } + + /* wait for last operation to be completed */ + status = flash_operation_wait_for(ERASE_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + /* unlock the user system data */ + FLASH->usd_unlock = FLASH_UNLOCK_KEY1; + FLASH->usd_unlock = FLASH_UNLOCK_KEY2; + while(FLASH->ctrl_bit.usdulks==RESET); + + /* erase the user system data */ + FLASH->ctrl_bit.usders = TRUE; + FLASH->ctrl_bit.erstr = TRUE; + + /* wait for operation to be completed */ + status = flash_operation_wait_for(ERASE_TIMEOUT); + + /* disable the usders bit */ + FLASH->ctrl_bit.usders = FALSE; + + if((status == FLASH_OPERATE_DONE) && (fap_val == FAP_RELIEVE_KEY)) + { + /* enable the user system data programming operation */ + FLASH->ctrl_bit.usdprgm = TRUE; + + /* restore the last flash access protection value */ + USD->fap = (uint16_t)fap_val; + + /* wait for operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + + /*disable the usdprgm bit */ + FLASH->ctrl_bit.usdprgm = FALSE; + } + } + /* return the erase status */ + return status; +} + +/** + * @brief program a word at a specified address. + * @param address: specifies the address to be programmed, word alignment is recommended. + * @param data: specifies the data to be programmed. + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_word_program(uint32_t address, uint32_t data) +{ + flash_status_type status = FLASH_OPERATE_DONE; + if((address >= FLASH_BANK1_START_ADDR) && (address <= FLASH_BANK1_END_ADDR)) + { + /* wait for last operation to be completed */ + status = flash_bank1_operation_wait_for(PROGRAMMING_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + FLASH->ctrl_bit.fprgm = TRUE; + *(__IO uint32_t*)address = data; + /* wait for operation to be completed */ + status = flash_bank1_operation_wait_for(PROGRAMMING_TIMEOUT); + + /* disable the fprgm bit */ + FLASH->ctrl_bit.fprgm = FALSE; + } + } + else if((address >= FLASH_BANK2_START_ADDR) && (address <= FLASH_BANK2_END_ADDR)) + { + /* wait for last operation to be completed */ + status = flash_bank2_operation_wait_for(PROGRAMMING_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + FLASH->ctrl2_bit.fprgm = TRUE; + *(__IO uint32_t*)address = data; + /* wait for operation to be completed */ + status = flash_bank2_operation_wait_for(PROGRAMMING_TIMEOUT); + + /* disable the fprgm bit */ + FLASH->ctrl2_bit.fprgm = FALSE; + } + } + /* spim : external flash */ + else if(address >= FLASH_SPIM_START_ADDR) + { + /* wait for last operation to be completed */ + status = flash_spim_operation_wait_for(SPIM_PROGRAMMING_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + FLASH->ctrl3_bit.fprgm = TRUE; + *(__IO uint32_t*)address = data; + /* wait for operation to be completed */ + status = flash_spim_operation_wait_for(SPIM_PROGRAMMING_TIMEOUT); + + /* disable the fprgm bit */ + FLASH->ctrl3_bit.fprgm = FALSE; + } + } + + /* return the program status */ + return status; +} + +/** + * @brief program a halfword at a specified address. + * @param address: specifies the address to be programmed, halfword alignment is recommended. + * @param data: specifies the data to be programmed. + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_halfword_program(uint32_t address, uint16_t data) +{ + flash_status_type status = FLASH_OPERATE_DONE; + if((address >= FLASH_BANK1_START_ADDR) && (address <= FLASH_BANK1_END_ADDR)) + { + /* wait for last operation to be completed */ + status = flash_bank1_operation_wait_for(PROGRAMMING_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + FLASH->ctrl_bit.fprgm = TRUE; + *(__IO uint16_t*)address = data; + /* wait for operation to be completed */ + status = flash_bank1_operation_wait_for(PROGRAMMING_TIMEOUT); + + /* disable the fprgm bit */ + FLASH->ctrl_bit.fprgm = FALSE; + } + } + else if((address >= FLASH_BANK2_START_ADDR) && (address <= FLASH_BANK2_END_ADDR)) + { + /* wait for last operation to be completed */ + status = flash_bank2_operation_wait_for(PROGRAMMING_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + FLASH->ctrl2_bit.fprgm = TRUE; + *(__IO uint16_t*)address = data; + /* wait for operation to be completed */ + status = flash_bank2_operation_wait_for(PROGRAMMING_TIMEOUT); + + /* disable the fprgm bit */ + FLASH->ctrl2_bit.fprgm = FALSE; + } + } + /* spim : external flash */ + else if(address >= FLASH_SPIM_START_ADDR) + { + /* wait for last operation to be completed */ + status = flash_spim_operation_wait_for(SPIM_PROGRAMMING_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + FLASH->ctrl3_bit.fprgm = TRUE; + *(__IO uint16_t*)address = data; + /* wait for operation to be completed */ + status = flash_spim_operation_wait_for(SPIM_PROGRAMMING_TIMEOUT); + + /* disable the fprgm bit */ + FLASH->ctrl3_bit.fprgm = FALSE; + } + } + + /* return the program status */ + return status; +} + +/** + * @brief program a byte at a specified address. + * @note this function cannot be used to program spim. + * @param address: specifies the address to be programmed. + * @param data: specifies the data to be programmed. + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_byte_program(uint32_t address, uint8_t data) +{ + flash_status_type status = FLASH_OPERATE_DONE; + if((address >= FLASH_BANK1_START_ADDR) && (address <= FLASH_BANK1_END_ADDR)) + { + /* wait for last operation to be completed */ + status = flash_bank1_operation_wait_for(PROGRAMMING_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + FLASH->ctrl_bit.fprgm = TRUE; + *(__IO uint8_t*)address = data; + /* wait for operation to be completed */ + status = flash_bank1_operation_wait_for(PROGRAMMING_TIMEOUT); + + /* disable the fprgm bit */ + FLASH->ctrl_bit.fprgm = FALSE; + } + } + else if((address >= FLASH_BANK2_START_ADDR) && (address <= FLASH_BANK2_END_ADDR)) + { + /* wait for last operation to be completed */ + status = flash_bank2_operation_wait_for(PROGRAMMING_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + FLASH->ctrl2_bit.fprgm = TRUE; + *(__IO uint8_t*)address = data; + /* wait for operation to be completed */ + status = flash_bank2_operation_wait_for(PROGRAMMING_TIMEOUT); + + /* disable the fprgm bit */ + FLASH->ctrl2_bit.fprgm = FALSE; + } + } + /* return the program status */ + return status; +} + +/** + * @brief program a halfword at a specified user system data address. + * @param address: specifies the address to be programmed. + * @param data: specifies the data to be programmed. + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_user_system_data_program(uint32_t address, uint8_t data) +{ + flash_status_type status = FLASH_OPERATE_DONE; + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + if(status == FLASH_OPERATE_DONE) + { + /* unlock the user system data */ + FLASH->usd_unlock = FLASH_UNLOCK_KEY1; + FLASH->usd_unlock = FLASH_UNLOCK_KEY2; + while(FLASH->ctrl_bit.usdulks==RESET); + + /* enable the user system data programming operation */ + FLASH->ctrl_bit.usdprgm = TRUE; + *(__IO uint16_t*)address = data; + + /* wait for operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + + /* disable the usdprgm bit */ + FLASH->ctrl_bit.usdprgm = FALSE; + } + /* return the user system data program status */ + return status; +} + +/** + * @brief config erase/program protection for the desired sectors. + * @param sector_bits: + * the pointer of the address of the sectors to be erase/program protected. + * general every bit is used to protect the 4KB bytes, and the last one bit + * is used to protect the rest. + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_epp_set(uint32_t *sector_bits) +{ + uint16_t epp_data[4] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF}; + flash_status_type status = FLASH_OPERATE_DONE; + sector_bits[0] = (uint32_t)(~sector_bits[0]); + epp_data[0] = (uint16_t)((sector_bits[0] >> 0) & 0xFF); + epp_data[1] = (uint16_t)((sector_bits[0] >> 8) & 0xFF); + epp_data[2] = (uint16_t)((sector_bits[0] >> 16) & 0xFF); + epp_data[3] = (uint16_t)((sector_bits[0] >> 24) & 0xFF); + /* wait for last operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + /* unlock the user system data */ + FLASH->usd_unlock = FLASH_UNLOCK_KEY1; + FLASH->usd_unlock = FLASH_UNLOCK_KEY2; + while(FLASH->ctrl_bit.usdulks==RESET); + + FLASH->ctrl_bit.usdprgm = TRUE; + USD->epp0 = epp_data[0]; + /* wait for operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + USD->epp1 = epp_data[1]; + /* wait for operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + } + if(status == FLASH_OPERATE_DONE) + { + USD->epp2 = epp_data[2]; + /* wait for operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + } + if(status == FLASH_OPERATE_DONE) + { + USD->epp3 = epp_data[3]; + /* wait for operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + } + /* disable the usdprgm bit */ + FLASH->ctrl_bit.usdprgm = FALSE; + } + /* return the erase/program protection operation status */ + return status; +} + +/** + * @brief return the flash erase/program protection status. + * @param sector_bits: pointer to get the epps register. + * @retval none + */ +void flash_epp_status_get(uint32_t *sector_bits) +{ + /* return the flash erase/program protection register value */ + sector_bits[0] = (uint32_t)(FLASH->epps); +} + +/** + * @brief enable or disable the flash access protection. + * @note if the user has already programmed the other user system data before calling + * this function, must re-program them since this function erase all user system data. + * @param new_state: new state of the flash access protection. + * this parameter can be: TRUE or FALSE. + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_fap_enable(confirm_state new_state) +{ + flash_status_type status = FLASH_OPERATE_DONE; + status = flash_operation_wait_for(ERASE_TIMEOUT); + if(status == FLASH_OPERATE_DONE) + { + /* unlock the user system data */ + FLASH->usd_unlock = FLASH_UNLOCK_KEY1; + FLASH->usd_unlock = FLASH_UNLOCK_KEY2; + while(FLASH->ctrl_bit.usdulks==RESET); + + FLASH->ctrl_bit.usders = TRUE; + FLASH->ctrl_bit.erstr = TRUE; + /* wait for operation to be completed */ + status = flash_operation_wait_for(ERASE_TIMEOUT); + + /* disable the usders bit */ + FLASH->ctrl_bit.usders = FALSE; + + if(status == FLASH_OPERATE_DONE) + { + if(new_state == FALSE) + { + /* enable the user system data programming operation */ + FLASH->ctrl_bit.usdprgm = TRUE; + USD->fap = FAP_RELIEVE_KEY; + + /* Wait for operation to be completed */ + status = flash_operation_wait_for(ERASE_TIMEOUT); + + /* disable the usdprgm bit */ + FLASH->ctrl_bit.usdprgm = FALSE; + } + } + } + /* return the flash access protection operation status */ + return status; +} + +/** + * @brief check the flash access protection status. + * @param none + * @retval flash access protection status(SET or RESET) + */ +flag_status flash_fap_status_get(void) +{ + return (flag_status)FLASH->usd_bit.fap; +} + +/** + * @brief program the flash system setting byte in usd: wdt_ato_en / depslp_rst / stdby_rst / btopt. + * @param usd_ssb: the system setting byte + * @note this parameter usd_ssb must contain a combination of all the following 4 types of data + * type 1: wdt_ato_en, select the wdt auto start + * this data can be one of the following values: + * - USD_WDT_ATO_DISABLE: disable wdt auto start + * - USD_WDT_ATO_ENABLE: enable wdt auto start + * type 2: depslp_rst, reset event when entering deepsleep mode. + * this data can be one of the following values: + * - USD_DEPSLP_NO_RST: no reset generated when entering in deepsleep + * - USD_DEPSLP_RST: reset generated when entering in deepsleep + * type 3: stdby_rst, reset event when entering standby mode. + * this data can be one of the following values: + * - USD_STDBY_NO_RST: no reset generated when entering in standby + * - USD_STDBY_RST: reset generated when entering in standby + * type 4: btopt, at startup,if boot pins are set in boot from user flash position,selected the device boot from bank1/bank2. + * this data can be one of the following values: + * - FLASH_BOOT_FROM_BANK1:boot from bank1 + * - FLASH_BOOT_FROM_BANK2:boot from bank 2 or bank 1 + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_ssb_set(uint8_t usd_ssb) +{ + flash_status_type status = FLASH_OPERATE_DONE; + /* wait for last operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + /* unlock the user system data */ + FLASH->usd_unlock = FLASH_UNLOCK_KEY1; + FLASH->usd_unlock = FLASH_UNLOCK_KEY2; + while(FLASH->ctrl_bit.usdulks==RESET); + + /* enable the user system data programming operation */ + FLASH->ctrl_bit.usdprgm = TRUE; + + USD->ssb = usd_ssb; + /* wait for operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + + /* disable the usdprgm bit */ + FLASH->ctrl_bit.usdprgm = FALSE; + } + /* return the user system data program status */ + return status; +} + +/** + * @brief return the flash system setting byte status. + * @param none + * @retval values from flash_usd register: wdt_ato_en(bit0), depslp_rst(bit1), + * stdby_rst(bit2) and btopt(bit3). + */ +uint8_t flash_ssb_status_get(void) +{ + /* return the system setting byte status */ + return (uint8_t)(FLASH->usd >> 2); +} + +/** + * @brief enable or disable the specified flash interrupts. + * @param flash_int: specifies the flash interrupt sources to be enabled or disabled. + * this parameter can be any combination of the following values: + * - FLASH_ERR_INT + * - FLASH_ODF_INT + * - FLASH_BANK1_ERR_INT + * - FLASH_BANK1_ODF_INT + * - FLASH_BANK2_ERR_INT + * - FLASH_BANK2_ODF_INT + * - FLASH_SPIM_ERR_INT + * - FLASH_SPIM_ODF_INT + * @param new_state: new state of the specified flash interrupts. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void flash_interrupt_enable(uint32_t flash_int, confirm_state new_state) +{ + if(flash_int & FLASH_BANK1_ERR_INT) + FLASH->ctrl_bit.errie = new_state; + if(flash_int & FLASH_BANK1_ODF_INT) + FLASH->ctrl_bit.odfie = new_state; + if(flash_int & FLASH_BANK2_ERR_INT) + FLASH->ctrl2_bit.errie = new_state; + if(flash_int & FLASH_BANK2_ODF_INT) + FLASH->ctrl2_bit.odfie = new_state; + if(flash_int & FLASH_SPIM_ERR_INT) + FLASH->ctrl3_bit.errie = new_state; + if(flash_int & FLASH_SPIM_ODF_INT) + FLASH->ctrl3_bit.odfie = new_state; +} + +/** + * @brief select spim supports extended spi flash chip model. + * @param mode: the extended spi flash model + * @retval none + */ +void flash_spim_model_select(flash_spim_model_type mode) +{ + FLASH->select = mode; +} + +/** + * @brief set the range of encryption in spim flash. + * when the address is larger than this value, the writing data will be + * directly written to spim without encryption. + * @param decode_address: the end address of encrypted data in spim + * @retval none + */ +void flash_spim_encryption_range_set(uint32_t decode_address) +{ + FLASH->da = decode_address; +} + +/** + * @brief enable security library function. + * @param pwd: slib password + * start_sector: security library start sector + * data_start_sector: security library d-bus area start sector + * end_sector: security library end sector + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_slib_enable(uint32_t pwd, uint16_t start_sector, uint16_t data_start_sector, uint16_t end_sector) +{ + uint32_t slib_range; + flash_status_type status = FLASH_OPERATE_DONE; + /* wait for last operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + + /*check range param limits*/ + if((start_sector>=data_start_sector) || ((data_start_sector > end_sector) && \ + (data_start_sector != 0x7FF)) || (start_sector > end_sector)) + return FLASH_PROGRAM_ERROR; + + if(status == FLASH_OPERATE_DONE) + { + /* unlock slib cfg register */ + FLASH->slib_unlock = SLIB_UNLOCK_KEY; + while(FLASH->slib_misc_sts_bit.slib_ulkf==RESET); + + slib_range = ((uint32_t)(data_start_sector << 11) & FLASH_SLIB_DATA_START_SECTOR) | \ + ((uint32_t)(end_sector << 22) & FLASH_SLIB_END_SECTOR) | \ + (start_sector & FLASH_SLIB_START_SECTOR); + /* configure slib, set pwd and range */ + FLASH->slib_set_pwd = pwd; + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + FLASH->slib_set_range = slib_range; + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + } + return status; +} + +/** + * @brief disable slib when slib enabled. + * @param pwd: slib password + * @retval success or error + */ +error_status flash_slib_disable(uint32_t pwd) +{ + flash_status_type status = FLASH_OPERATE_DONE; + /* write password to disable slib */ + FLASH->slib_pwd_clr = pwd; + + status = flash_operation_wait_for(ERASE_TIMEOUT); + if(status == FLASH_OPERATE_DONE) + { + if(FLASH->slib_misc_sts_bit.slib_pwd_ok) + return SUCCESS; + else + return ERROR; + } + return ERROR; +} + +/** + * @brief get remaining count of slib(range: 256~0). + * @param none + * @retval uint32_t + */ +uint32_t flash_slib_remaining_count_get(void) +{ + return (uint32_t)FLASH->slib_misc_sts_bit.slib_rcnt; +} + +/** + * @brief get the slib state. + * @param none + * @retval SET or RESET + */ +flag_status flash_slib_state_get(void) +{ + if(FLASH->slib_sts0_bit.slib_enf) + return SET; + else + return RESET; +} + +/** + * @brief get the start sector of slib. + * @param none + * @retval uint16_t + */ +uint16_t flash_slib_start_sector_get(void) +{ + return (uint16_t)FLASH->slib_sts1_bit.slib_ss; +} + +/** + * @brief get the data start sector of slib. + * @param none + * @retval uint16_t + */ +uint16_t flash_slib_datstart_sector_get(void) +{ + return (uint16_t)FLASH->slib_sts1_bit.slib_dat_ss; +} + +/** + * @brief get the end sector of slib. + * @param none + * @retval uint16_t + */ +uint16_t flash_slib_end_sector_get(void) +{ + return (uint16_t)FLASH->slib_sts1_bit.slib_es; +} + +/** + * @brief flash crc calibration in main block. + * @param start_sector: crc calibration start sector number + * sector_cnt: crc calibration sector count + * @retval uint32: crc calibration result + */ +uint32_t flash_crc_calibrate(uint32_t start_sector, uint32_t sector_cnt) +{ + FLASH->crc_ctrl_bit.crc_ss = start_sector; + FLASH->crc_ctrl_bit.crc_sn = sector_cnt; + FLASH->crc_ctrl_bit.crc_strt = TRUE; + flash_operation_wait_for(OPERATION_TIMEOUT); + return FLASH->crc_chkr; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_gpio.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_gpio.c new file mode 100644 index 0000000..fbff02d --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_gpio.c @@ -0,0 +1,665 @@ +/** + ************************************************************************** + * @file at32f403a_407_gpio.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the gpio firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup GPIO + * @brief GPIO driver modules + * @{ + */ + +#ifdef GPIO_MODULE_ENABLED + +/** @defgroup GPIO_private_functions + * @{ + */ + +/** + * @brief reset the gpio register + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOE. + * @retval none + */ +void gpio_reset(gpio_type *gpio_x) +{ + if(gpio_x == GPIOA) + { + crm_periph_reset(CRM_GPIOA_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_GPIOA_PERIPH_RESET, FALSE); + } + else if(gpio_x == GPIOB) + { + crm_periph_reset(CRM_GPIOB_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_GPIOB_PERIPH_RESET, FALSE); + } + else if(gpio_x == GPIOC) + { + crm_periph_reset(CRM_GPIOC_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_GPIOC_PERIPH_RESET, FALSE); + } + else if(gpio_x == GPIOD) + { + crm_periph_reset(CRM_GPIOD_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_GPIOD_PERIPH_RESET, FALSE); + } + else if(gpio_x == GPIOE) + { + crm_periph_reset(CRM_GPIOE_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_GPIOE_PERIPH_RESET, FALSE); + } +} + +/** + * @brief reset the mux functions (remap, event control + and exint configuration) registers to their default values. + * @param none + * @retval none + */ +void gpio_iomux_reset(void) +{ + crm_periph_reset(CRM_IOMUX_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_IOMUX_PERIPH_RESET, FALSE); +} + +/** + * @brief initialize the gpio peripheral. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOE. + * @param gpio_init_struct: pointer to gpio init structure. + * @retval none + */ +void gpio_init(gpio_type *gpio_x, gpio_init_type *gpio_init_struct) +{ + uint32_t temp; + uint16_t pinx_value, pin_index; + + pin_index = (uint16_t)gpio_init_struct->gpio_pins; + + /* pinx_value indecate pin grounp bit[3:0] from modey[1:0] confy[1:0] */ + + /* pin input analog config */ + if(gpio_init_struct->gpio_mode == GPIO_MODE_ANALOG) + { + pinx_value = 0x00; + } + /* pin input config */ + else if(gpio_init_struct->gpio_mode == GPIO_MODE_INPUT) + { + pinx_value = gpio_init_struct->gpio_pull & 0x0F; + + if(gpio_init_struct->gpio_pull == GPIO_PULL_UP) + { + gpio_x->scr = pin_index; + } + else if(gpio_init_struct->gpio_pull == GPIO_PULL_DOWN) + { + gpio_x->clr = pin_index; + } + } + else + { + pinx_value = (gpio_init_struct->gpio_mode & 0x08) | (gpio_init_struct->gpio_out_type & 0x04) | \ + (gpio_init_struct->gpio_drive_strength & 0x03); + } + + /* pin 0~7 config */ + if(((uint32_t)pin_index & ((uint32_t)0x00FF)) != 0x00) + { + for(temp = 0; temp < 0x08; temp++) + { + if((1 << temp) & pin_index) + { + gpio_x->cfglr &= (uint32_t)~(0x0F << (temp * 4)); + gpio_x->cfglr |= (uint32_t)(pinx_value << (temp * 4)); + } + } + } + + /* pin 8~15 config */ + if(pin_index > 0x00ff) + { + pin_index = pin_index >> 8; + + for(temp = 0; temp < 0x8; temp++) + { + if((1 << temp) & pin_index) + { + gpio_x->cfghr &= (uint32_t)~(0xf << (temp * 4)); + gpio_x->cfghr |= (uint32_t)(pinx_value << (temp * 4)); + } + } + } +} + +/** + * @brief fill each gpio_init_type member with its default value. + * @param gpio_init_struct : pointer to a gpio_init_type structure which will be initialized. + * @retval none + */ +void gpio_default_para_init(gpio_init_type *gpio_init_struct) +{ + /* reset gpio init structure parameters values */ + gpio_init_struct->gpio_pins = GPIO_PINS_ALL; + gpio_init_struct->gpio_mode = GPIO_MODE_INPUT; + gpio_init_struct->gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct->gpio_pull = GPIO_PULL_NONE; + gpio_init_struct->gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; +} + +/** + * @brief read the specified input port pin. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOE. + * @param pins: gpio pin number + * this parameter can be one of the following values: + * - GPIO_PINS_0 + * - GPIO_PINS_1 + * - GPIO_PINS_2 + * - GPIO_PINS_3 + * - GPIO_PINS_4 + * - GPIO_PINS_5 + * - GPIO_PINS_6 + * - GPIO_PINS_7 + * - GPIO_PINS_8 + * - GPIO_PINS_9 + * - GPIO_PINS_10 + * - GPIO_PINS_11 + * - GPIO_PINS_12 + * - GPIO_PINS_13 + * - GPIO_PINS_14 + * - GPIO_PINS_15 + * @retval flag_status (SET or RESET) + */ +flag_status gpio_input_data_bit_read(gpio_type *gpio_x, uint16_t pins) +{ + flag_status status = RESET; + + if(pins != (pins & gpio_x->idt)) + { + status = RESET; + } + else + { + status = SET; + } + + return status; +} + +/** + * @brief read the specified gpio input data port. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOE. + * @retval gpio input data port value. + */ +uint16_t gpio_input_data_read(gpio_type *gpio_x) +{ + return ((uint16_t)(gpio_x->idt)); +} + +/** + * @brief read the specified output port pin. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOE. + * @param pins: gpio pin number + * this parameter can be one of the following values: + * - GPIO_PINS_0 + * - GPIO_PINS_1 + * - GPIO_PINS_2 + * - GPIO_PINS_3 + * - GPIO_PINS_4 + * - GPIO_PINS_5 + * - GPIO_PINS_6 + * - GPIO_PINS_7 + * - GPIO_PINS_8 + * - GPIO_PINS_9 + * - GPIO_PINS_10 + * - GPIO_PINS_11 + * - GPIO_PINS_12 + * - GPIO_PINS_13 + * - GPIO_PINS_14 + * - GPIO_PINS_15 + * @retval flag_status (SET or RESET) + */ +flag_status gpio_output_data_bit_read(gpio_type *gpio_x, uint16_t pins) +{ + flag_status status = RESET; + + if((gpio_x->odt & pins) != RESET) + { + status = SET; + } + else + { + status = RESET; + } + + return status; +} + +/** + * @brief read the specified gpio ouput data port. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOE. + * @retval gpio input data port value. + */ +uint16_t gpio_output_data_read(gpio_type *gpio_x) +{ + return ((uint16_t)(gpio_x->odt)); +} + +/** + * @brief set the selected data port bits. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOE. + * @param pins: gpio pin number + * parameter can be any combination of gpio_pin_x, gpio_pin_x as following values: + * - GPIO_PINS_0 + * - GPIO_PINS_1 + * - GPIO_PINS_2 + * - GPIO_PINS_3 + * - GPIO_PINS_4 + * - GPIO_PINS_5 + * - GPIO_PINS_6 + * - GPIO_PINS_7 + * - GPIO_PINS_8 + * - GPIO_PINS_9 + * - GPIO_PINS_10 + * - GPIO_PINS_11 + * - GPIO_PINS_12 + * - GPIO_PINS_13 + * - GPIO_PINS_14 + * - GPIO_PINS_15 + * - GPIO_PINS_ALL + * @retval none + */ +void gpio_bits_set(gpio_type *gpio_x, uint16_t pins) +{ + gpio_x->scr = pins; +} + +/** + * @brief clear the selected data port bits. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOE. + * @param pins: gpio pin number + * parameter can be any combination of gpio_pin_x, gpio_pin_x as following values: + * - GPIO_PINS_0 + * - GPIO_PINS_1 + * - GPIO_PINS_2 + * - GPIO_PINS_3 + * - GPIO_PINS_4 + * - GPIO_PINS_5 + * - GPIO_PINS_6 + * - GPIO_PINS_7 + * - GPIO_PINS_8 + * - GPIO_PINS_9 + * - GPIO_PINS_10 + * - GPIO_PINS_11 + * - GPIO_PINS_12 + * - GPIO_PINS_13 + * - GPIO_PINS_14 + * - GPIO_PINS_15 + * - GPIO_PINS_ALL + * @retval none + */ +void gpio_bits_reset(gpio_type *gpio_x, uint16_t pins) +{ + gpio_x->clr = pins; +} + +/** + * @brief set or clear the selected data port bit. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOE. + * @param pins: gpio pin number + * parameter can be any combination of gpio_pin_x, gpio_pin_x as following values: + * - GPIO_PINS_0 + * - GPIO_PINS_1 + * - GPIO_PINS_2 + * - GPIO_PINS_3 + * - GPIO_PINS_4 + * - GPIO_PINS_5 + * - GPIO_PINS_6 + * - GPIO_PINS_7 + * - GPIO_PINS_8 + * - GPIO_PINS_9 + * - GPIO_PINS_10 + * - GPIO_PINS_11 + * - GPIO_PINS_12 + * - GPIO_PINS_13 + * - GPIO_PINS_14 + * - GPIO_PINS_15 + * - GPIO_PINS_ALL + * @param bit_state: specifies the value to be written to the selected bit (TRUE or FALSE). + * @retval none + */ +void gpio_bits_write(gpio_type *gpio_x, uint16_t pins, confirm_state bit_state) +{ + if(bit_state != FALSE) + { + gpio_x->scr = pins; + } + else + { + gpio_x->clr = pins; + } +} + +/** + * @brief write data to the specified gpio data port. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOE. + * @param port_value: specifies the value to be written to the port output data register. + * @retval none + */ +void gpio_port_wirte(gpio_type *gpio_x, uint16_t port_value) +{ + gpio_x->odt = port_value; +} + +/** + * @brief write protect gpio pins configuration registers. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOE. + * @param pins: gpio pin number + * this parameter can be any combination of the following: + * - GPIO_PINS_0 + * - GPIO_PINS_1 + * - GPIO_PINS_2 + * - GPIO_PINS_3 + * - GPIO_PINS_4 + * - GPIO_PINS_5 + * - GPIO_PINS_6 + * - GPIO_PINS_7 + * - GPIO_PINS_8 + * - GPIO_PINS_9 + * - GPIO_PINS_10 + * - GPIO_PINS_11 + * - GPIO_PINS_12 + * - GPIO_PINS_13 + * - GPIO_PINS_14 + * - GPIO_PINS_15 + * - GPIO_PINS_ALL + * @retval none + */ +void gpio_pin_wp_config(gpio_type *gpio_x, uint16_t pins) +{ + uint32_t temp = 0x00010000; + + temp |= pins; + /* set wpen bit */ + gpio_x->wpr = temp; + /* reset wpen bit */ + gpio_x->wpr = pins; + /* set wpen bit */ + gpio_x->wpr = temp; + /* read wpen bit*/ + temp = gpio_x->wpr; + /* read wpen bit*/ + temp = gpio_x->wpr; +} + +/** + * @brief enable or disable gpio pins huge driven. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOE. + * @param pins: gpio pin number + * parameter can be any combination of gpio_pin_x, gpio_pin_x as following values: + * - GPIO_PINS_0 + * - GPIO_PINS_1 + * - GPIO_PINS_2 + * - GPIO_PINS_3 + * - GPIO_PINS_4 + * - GPIO_PINS_5 + * - GPIO_PINS_6 + * - GPIO_PINS_7 + * - GPIO_PINS_8 + * - GPIO_PINS_9 + * - GPIO_PINS_10 + * - GPIO_PINS_11 + * - GPIO_PINS_12 + * - GPIO_PINS_13 + * - GPIO_PINS_14 + * - GPIO_PINS_15 + * - GPIO_PINS_ALL + * @param new_state: new state of the slew rate. + * this parameter can be: true or false. + * @retval none + */ +void gpio_pins_huge_driven_config(gpio_type *gpio_x, uint16_t pins, confirm_state new_state) +{ + if(new_state != FALSE) + { + gpio_x->hdrv |= pins; + } + else + { + gpio_x->hdrv &= ~pins; + } +} + +/** + * @brief select the gpio pin used as event output. + * @param gpio_port_source: select the gpio port to be used as source + * for event output. + * this parameter can be one of the following values: + * - GPIO_PORT_SOURCE_GPIOA + * - GPIO_PORT_SOURCE_GPIOB + * - GPIO_PORT_SOURCE_GPIOC + * - GPIO_PORT_SOURCE_GPIOD + * - GPIO_PORT_SOURCE_GPIOE + * @param gpio_pin_source: specifies the pin for the event output. + * this parameter can be one of the following values: + * - GPIO_PINS_SOURCE0 + * - GPIO_PINS_SOURCE1 + * - GPIO_PINS_SOURCE2 + * - GPIO_PINS_SOURCE3 + * - GPIO_PINS_SOURCE4 + * - GPIO_PINS_SOURCE5 + * - GPIO_PINS_SOURCE6 + * - GPIO_PINS_SOURCE7 + * - GPIO_PINS_SOURCE8 + * - GPIO_PINS_SOURCE9 + * - GPIO_PINS_SOURCE10 + * - GPIO_PINS_SOURCE11 + * - GPIO_PINS_SOURCE12 + * - GPIO_PINS_SOURCE13 + * - GPIO_PINS_SOURCE14 + * - GPIO_PINS_SOURCE15 + * @retval none + */ +void gpio_event_output_config(gpio_port_source_type gpio_port_source, gpio_pins_source_type gpio_pin_source) +{ + uint32_t tmpreg = 0x00; + + tmpreg = IOMUX->evtout; + + /* clear the port[6:4] and pin[3:0] bits */ + tmpreg &= 0x80; + tmpreg |= (uint32_t)gpio_port_source << 0x04; + tmpreg |= gpio_pin_source; + IOMUX->evtout = tmpreg; +} + +/** + * @brief enable or disable the event output. + * @param confirm_state: new state of the event output. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void gpio_event_output_enable(confirm_state new_state) +{ + IOMUX->evtout_bit.evoen = new_state; +} + +/** + * @brief iomux remap and debug i/o configuration. + * @param gpio_remap: select the pin to remap. + * this parameter can be one of the following values: + * - SPI1_MUX_01 - SPI1_MUX_10 - SPI1_MUX_11 - I2C1_MUX + * - USART1_MUX - USART2_MUX - USART3_MUX_01 - USART3_MUX_11 + * - TMR1_MUX_01 - TMR1_MUX_11 - TMR2_MUX_01 - TMR2_MUX_10 + * - TMR2_MUX_11 - TMR3_MUX_10 - TMR3_MUX_11 - TMR4_MUX + * - CAN_MUX_10 - CAN_MUX_11 - PD01_MUX - TMR5CH4_MUX + * - ADC1_EXTRGPRE_MUX - ADC1_EXTRGORD_MUX - ADC2_EXTRGPRE_MUX - ADC2_EXTRGORD_MUX + * - EMAC_MUX - CAN2_MUX - MII_RMII_SEL_MUX - SWJTAG_MUX_001 + * - SWJTAG_MUX_010 - SWJTAG_MUX_100 - SPI3_MUX - TMR2ITR1_MUX + * - PTP_PPS_MUX - TMR9_MUX - XMC_NADV_MUX - SPI4_MUX + * - I2C3_MUX - SDIO2_MUX01 - SDIO2_MUX10 - SDIO2_MUX11 + * - EXT_SPIM_EN_MUX - TMR9_GMUX - TMR1_GMUX_0001 - TMR1_GMUX_0011 + * - TMR2_GMUX_01 - TMR2_GMUX_10 - TMR2_GMUX_11 - TMR2ITR1_GMUX_10 + * - TMR2ITR1_GMUX_11 - TMR3_GMUX_0010 - TMR3_GMUX_0011 - TMR4_GMUX_0001 + * - TMR5CH4_GMUX - UART5_GMUX_0001 - I2C1_GMUX_0001 - I2C3_GMUX_0001 + * - SPI1_GMUX_0001 - SPI1_GMUX_0010 - SPI1_GMUX_0011 - SPI2_GMUX_0001 + * - SPI2_GMUX_0010 - SPI3_GMUX_0001 - SPI3_GMUX_0010 - SPI3_GMUX_0011 + * - SPI4_GMUX_0001 - SPI4_GMUX_0010 - SPI4_GMUX_0011 - CAN1_GMUX_0010 + * - CAN1_GMUX_0011 - CAN2_GMUX_0001 - SDIO2_GMUX_0001 - SDIO2_GMUX_0010 + * - SDIO2_GMUX_0011 - USART1_GMUX_0001 - USART2_GMUX_0001 - USART3_GMUX_0001 + * - USART3_GMUX_0011 - UART4_GMUX_0010 - EXT_SPIM_GMUX_1000 - EXT_SPIM_GMUX_1001 + * - ADC1_ETP_GMUX - ADC1_ETO_GMUX - ADC2_ETP_GMUX - ADC2_ETO_GMUX + * - SWJTAG_GMUX_001 - SWJTAG_GMUX_010 - SWJTAG_GMUX_100 - PD01_GMUX + * - XMC_GMUX_001 - XMC_GMUX_010 - XMC_NADV_GMUX - EMAC_GMUX_01 + * - MII_RMII_SEL_GMUX - PTP_PPS_GMUX - USART6_GMUX - UART7_GMUX + * - UART8_GMUX + * @param new_state: (TRUE or FALSE) + * @retval none + */ +void gpio_pin_remap_config(uint32_t gpio_remap, confirm_state new_state) +{ + uint32_t reg_addr, remap_mask; + uint8_t bit_offset, bit_num, bit_val; + + /* get register address, bit offset, bit number and remap value */ + reg_addr = IOMUX_BASE + (gpio_remap >> 24); + bit_offset = (gpio_remap >> 16) & 0xFF; + bit_num = (gpio_remap >> 8) & 0xFF; + bit_val = gpio_remap & 0xFF; + + /* get remap mask value */ + remap_mask = 0xFFFFFFFF << (32 - bit_num - bit_offset); + remap_mask = remap_mask >> (32 - bit_num - bit_offset); + remap_mask = remap_mask >> bit_offset; + remap_mask = remap_mask << bit_offset; + + /* clear remap value */ + *(uint32_t*)reg_addr &= ~remap_mask; + + if(new_state != FALSE) + { + /* set remap value */ + *(uint32_t*)reg_addr |= (uint32_t)(bit_val << bit_offset); + } +} + +/** + * @brief select the gpio pin used as exint line. + * @param gpio_port_source: select the gpio port to be used as source for exint. + * this parameter can be one of the following values: + * - GPIO_PORT_SOURCE_GPIOA + * - GPIO_PORT_SOURCE_GPIOB + * - GPIO_PORT_SOURCE_GPIOC + * - GPIO_PORT_SOURCE_GPIOD + * - GPIO_PORT_SOURCE_GPIOE + * - GPIO_PORT_SOURCE_GPIOF + * - GPIO_PORT_SOURCE_GPIOG + * @param gpio_pin_source: specifies the pin for the event output. + * this parameter can be one of the following values: + * - GPIO_PINS_SOURCE0 + * - GPIO_PINS_SOURCE1 + * - GPIO_PINS_SOURCE2 + * - GPIO_PINS_SOURCE3 + * - GPIO_PINS_SOURCE4 + * - GPIO_PINS_SOURCE5 + * - GPIO_PINS_SOURCE6 + * - GPIO_PINS_SOURCE7 + * - GPIO_PINS_SOURCE8 + * - GPIO_PINS_SOURCE9 + * - GPIO_PINS_SOURCE10 + * - GPIO_PINS_SOURCE11 + * - GPIO_PINS_SOURCE12 + * - GPIO_PINS_SOURCE13 + * - GPIO_PINS_SOURCE14 + * - GPIO_PINS_SOURCE15 + * @retval none + */ +void gpio_exint_line_config(gpio_port_source_type gpio_port_source, gpio_pins_source_type gpio_pin_source) +{ + uint32_t tmp = 0x00; + tmp = ((uint32_t)0x0F) << (0x04 * (gpio_pin_source & (uint8_t)0x03)); + + switch (gpio_pin_source >> 0x02) + { + case 0: + IOMUX->exintc1 &= ~tmp; + IOMUX->exintc1 |= (((uint32_t)gpio_port_source) << (0x04 * (gpio_pin_source & (uint8_t)0x03))); + break; + case 1: + IOMUX->exintc2 &= ~tmp; + IOMUX->exintc2 |= (((uint32_t)gpio_port_source) << (0x04 * (gpio_pin_source & (uint8_t)0x03))); + break; + case 2: + IOMUX->exintc3 &= ~tmp; + IOMUX->exintc3 |= (((uint32_t)gpio_port_source) << (0x04 * (gpio_pin_source & (uint8_t)0x03))); + break; + case 3: + IOMUX->exintc4 &= ~tmp; + IOMUX->exintc4 |= (((uint32_t)gpio_port_source) << (0x04 * (gpio_pin_source & (uint8_t)0x03))); + break; + default: + break; + } +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_i2c.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_i2c.c new file mode 100644 index 0000000..8a55b48 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_i2c.c @@ -0,0 +1,641 @@ +/** + ************************************************************************** + * @file at32f403a_407_i2c.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the i2c firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup I2C + * @brief I2C driver modules + * @{ + */ + +#ifdef I2C_MODULE_ENABLED + +/** @defgroup I2C_private_functions + * @{ + */ + +/** + * @brief reset the i2c register + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @retval none + */ +void i2c_reset(i2c_type *i2c_x) +{ + if(i2c_x == I2C1) + { + crm_periph_reset(CRM_I2C1_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_I2C1_PERIPH_RESET, FALSE); + } + else if(i2c_x == I2C2) + { + crm_periph_reset(CRM_I2C2_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_I2C2_PERIPH_RESET, FALSE); + } + else if(i2c_x == I2C3) + { + crm_periph_reset(CRM_I2C3_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_I2C3_PERIPH_RESET, FALSE); + } +} + +/** + * @brief software reset. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void i2c_software_reset(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl1_bit.reset = new_state; +} + +/** + * @brief init i2c speed and duty cycle. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param duty + * this parameter can be one of the following values: + * - I2C_FSMODE_DUTY_2_1: duty cycle 2:1 + * - I2C_FSMODE_DUTY_16_9: duty cycle 16:9 + * @param speed: i2c scl clock speed, such as 100000 + * @retval none + */ +void i2c_init(i2c_type *i2c_x, i2c_fsmode_duty_cycle_type duty, uint32_t speed) +{ + uint32_t apb_freq = 0; + uint16_t freq_mhz = 0, temp = 0; + + crm_clocks_freq_type clocks; + + /* disable i2c peripherals */ + i2c_x->ctrl1_bit.i2cen = FALSE; + + /* get system clock */ + crm_clocks_freq_get(&clocks); + + if((i2c_x == I2C1) || (i2c_x == I2C2)) + { + apb_freq = clocks.apb1_freq; + } + else if(i2c_x == I2C3) + { + apb_freq = clocks.apb2_freq; + } + + freq_mhz = (apb_freq / 1000000); + + /* set i2c input clock frequency */ + i2c_x->ctrl2_bit.clkfreq = freq_mhz; + + /* standard mode */ + if(speed <= 100000) + { + temp = (uint16_t)(apb_freq / (speed << 1)); + + if (temp < 0x04) + { + temp = 0x04; + } + + /* set scl clock */ + i2c_x->clkctrl_bit.speed = temp; + + /* disable fast mode */ + i2c_x->clkctrl_bit.speedmode = FALSE; + + /* set the maximum rise time */ + if((freq_mhz + 1) > 0x3F) + { + i2c_x->tmrise_bit.risetime = 0x3F; + } + else + { + i2c_x->tmrise_bit.risetime = (freq_mhz + 1); + } + } + /* fast mode */ + else + { + if (duty == I2C_FSMODE_DUTY_2_1) + { + temp = (uint16_t)(apb_freq / (speed * 3)); + + /* the ratio of high level to low level is 1:2 */ + i2c_x->clkctrl_bit.dutymode = I2C_FSMODE_DUTY_2_1; + } + else + { + temp = (uint16_t)(apb_freq / (speed * 25)); + + /* the ratio of high level to low level is 9:16 */ + i2c_x->clkctrl_bit.dutymode = I2C_FSMODE_DUTY_16_9; + } + + if (temp == 0) + { + temp = 0x0001; + } + + /* set scl clock*/ + i2c_x->clkctrl_bit.speed = temp; + + /* set the mode to fast mode */ + i2c_x->clkctrl_bit.speedmode = TRUE; + + /* set the maximum rise time */ + i2c_x->tmrise_bit.risetime = (uint16_t)(((freq_mhz * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1); + } +} + +/** + * @brief config own address1. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param mode + * this parameter can be one of the following values: + * - I2C_ADDRESS_MODE_7BIT: 7bit address. + * - I2C_ADDRESS_MODE_10BIT: 10bit address. + * @param address: own address1, such as 0xb0. + * @retval none + */ +void i2c_own_address1_set(i2c_type *i2c_x, i2c_address_mode_type mode, uint16_t address) +{ + /* set address mode */ + i2c_x->oaddr1_bit.addr1mode = mode; + + /* set own address1 */ + i2c_x->oaddr1_bit.addr1 = address; +} + +/** + * @brief config own address2. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param address: specifies the 7bit i2c own address2, such as 0xa0. + * @retval none. + */ +void i2c_own_address2_set(i2c_type *i2c_x, uint8_t address) +{ + i2c_x->oaddr2_bit.addr2 = (address >> 1); +} + +/** + * @brief enable or disable own address2. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void i2c_own_address2_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->oaddr2_bit.addr2en = new_state; +} + +/** + * @brief enable or disable the smbus mode + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void i2c_smbus_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl1_bit.permode = new_state; +} + +/** + * @brief enable or disable i2c periph + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void i2c_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl1_bit.i2cen = new_state; +} + +/** + * @brief config fast mode duty cycle + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param duty + * this parameter can be one of the following values: + * - I2C_FSMODE_DUTY_2_1: duty cycle 2:1 + * - I2C_FSMODE_DUTY_16_9: duty cycle 16:9 + * @retval none + */ +void i2c_fast_mode_duty_set(i2c_type *i2c_x, i2c_fsmode_duty_cycle_type duty) +{ + i2c_x->clkctrl_bit.dutymode = duty; +} + +/** + * @brief enable or disable clock stretch. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void i2c_clock_stretch_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl1_bit.stretch = !new_state; +} + +/** + * @brief enable or disable acknowledge. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param new_state (TRUE or FALSE) + * @retval none. + */ +void i2c_ack_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl1_bit.acken = new_state; +} + +/** + * @brief master receiving mode acknowledge control. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param pos + * this parameter can be one of the following values: + * - I2C_MASTER_ACK_CURRENT: acken bit acts on the current byte + * - I2C_MASTER_ACK_NEXT: acken bit acts on the next byte + * @retval none + */ +void i2c_master_receive_ack_set(i2c_type *i2c_x, i2c_master_ack_type pos) +{ + i2c_x->ctrl1_bit.mackctrl = pos; +} + +/** + * @brief pec position set. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param pos + * this parameter can be one of the following values: + * - I2C_PEC_POSITION_CURRENT: the current byte is pec + * - I2C_PEC_POSITION_NEXT: the next byte is pec + * @retval none + */ +void i2c_pec_position_set(i2c_type *i2c_x, i2c_pec_position_type pos) +{ + i2c_x->ctrl1_bit.mackctrl = pos; +} + +/** + * @brief enable or disable general call. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void i2c_general_call_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl1_bit.gcaen = new_state; +} + +/** + * @brief enable or disable arp mode. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void i2c_arp_mode_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl1_bit.arpen = new_state; +} + +/** + * @brief config smbus host or device. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param level + * this parameter can be one of the following values: + * - I2C_SMBUS_MODE_DEVICE: smbus device. + * - I2C_SMBUS_MODE_HOST: smbus host. + * @retval none + */ +void i2c_smbus_mode_set(i2c_type *i2c_x, i2c_smbus_mode_set_type mode) +{ + i2c_x->ctrl1_bit.smbmode = mode; +} + +/** + * @brief drive the smbus alert pin high or low. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param level + * this parameter can be one of the following values: + * - I2C_SMBUS_ALERT_LOW: smbus alert pin set low. + * - I2C_SMBUS_ALERT_HIGH: smbus alert pin set high. + * @retval none + */ +void i2c_smbus_alert_set(i2c_type *i2c_x, i2c_smbus_alert_set_type level) +{ + i2c_x->ctrl1_bit.smbalert = level; +} + +/** + * @brief enable or disable pec transfer. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void i2c_pec_transmit_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl1_bit.pecten = new_state; +} + +/** + * @brief enable or disable pec calcultetion. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void i2c_pec_calculate_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl1_bit.pecen = new_state; +} + +/** + * @brief get pec value. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @retval uint8_t: pec value. + */ +uint8_t i2c_pec_value_get(i2c_type *i2c_x) +{ + return i2c_x->sts2_bit.pecval; +} + +/** + * @brief enable or disable if the next dma transfer will be the last one. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void i2c_dma_end_transfer_set(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl2_bit.dmaend = new_state; +} + +/** + * @brief enable or disable dma requests. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void i2c_dma_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl2_bit.dmaen = new_state; +} + +/** + * @brief enable or disable interrupt + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param source + * this parameter can be one of the following values: + * - I2C_DATA_INT: data interrupt. + * - I2C_EV_INT: event interrupt. + * - I2C_ERR_INT: error interrupt. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void i2c_interrupt_enable(i2c_type *i2c_x, uint16_t source, confirm_state new_state) +{ + if (new_state != FALSE) + { + i2c_x->ctrl2 |= source; + } + else + { + i2c_x->ctrl2 &= (uint16_t)~source; + } +} + +/** + * @brief generate start condition. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @retval none. + */ +void i2c_start_generate(i2c_type *i2c_x) +{ + i2c_x->ctrl1_bit.genstart = TRUE; +} + +/** + * @brief generate stop condition. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @retval none. + */ +void i2c_stop_generate(i2c_type *i2c_x) +{ + i2c_x->ctrl1_bit.genstop = TRUE; +} + +/** + * @brief transmit the slave address. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param address: specifies the slave address which will be transmitted + * @param direction + * this parameter can be one of the following values: + * - I2C_DIRECTION_TRANSMIT: transmit mode. + * - I2C_DIRECTION_RECEIVE: receive mode. + * @retval none. + */ +void i2c_7bit_address_send(i2c_type *i2c_x, uint8_t address, i2c_direction_type direction) +{ + if(direction == I2C_DIRECTION_TRANSMIT) + { + i2c_x->dt = address & 0xFE; + } + else + { + i2c_x->dt = address | 0x01; + } +} + +/** + * @brief send a byte through the i2c periph. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param data: byte to be transmitted. + * @retval none + */ +void i2c_data_send(i2c_type *i2c_x, uint8_t data) +{ + i2c_x->dt = data; +} + +/** + * @brief receive a byte through the i2c periph. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @retval uint8_t: received byte + */ +uint8_t i2c_data_receive(i2c_type *i2c_x) +{ + return (uint8_t)i2c_x->dt; +} + +/** + * @brief get flag status + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param flag + * this parameter can be one of the following values: + * - I2C_STARTF_FLAG: start condition generation complete flag. + * - I2C_ADDR7F_FLAG: 0~7 bit address match flag. + * - I2C_TDC_FLAG: transmit data complete flag. + * - I2C_ADDRHF_FLAG: master 9~8 bit address header match flag. + * - I2C_STOPF_FLAG: stop condition generation complete flag. + * - I2C_RDBF_FLAG: receive data buffer full flag. + * - I2C_TDBE_FLAG: transmit data buffer empty flag. + * - I2C_BUSERR_FLAG: bus error flag. + * - I2C_ARLOST_FLAG: arbitration lost flag. + * - I2C_ACKFAIL_FLAG: acknowledge failure flag. + * - I2C_OUF_FLAG: overflow or underflow flag. + * - I2C_PECERR_FLAG: pec receive error flag. + * - I2C_TMOUT_FLAG: smbus timeout flag. + * - I2C_ALERTF_FLAG: smbus alert flag. + * - I2C_TRMODE_FLAG: transmission mode. + * - I2C_BUSYF_FLAG: bus busy flag transmission mode. + * - I2C_DIRF_FLAG: transmission direction flag. + * - I2C_GCADDRF_FLAG: general call address received flag. + * - I2C_DEVADDRF_FLAG: smbus device address received flag. + * - I2C_HOSTADDRF_FLAG: smbus host address received flag. + * - I2C_ADDR2_FLAG: own address 2 received flag. + * @retval flag_status (SET or RESET) + */ +flag_status i2c_flag_get(i2c_type *i2c_x, uint32_t flag) +{ + __IO uint32_t reg = 0, value = 0; + + reg = flag >> 28; + + flag &= (uint32_t)0x00FFFFFF; + + if(reg == 0) + { + value = i2c_x->sts1; + } + else + { + flag = (uint32_t)(flag >> 16); + + value = i2c_x->sts2; + } + + if((value & flag) != (uint32_t)RESET) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief clear flag status + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @param flag + * this parameter can be any combination of the following values: + * - I2C_BUSERR_FLAG: bus error flag. + * - I2C_ARLOST_FLAG: arbitration lost flag. + * - I2C_ACKFAIL_FLAG: acknowledge failure flag. + * - I2C_OUF_FLAG: overflow or underflow flag. + * - I2C_PECERR_FLAG: pec receive error flag. + * - I2C_TMOUT_FLAG: smbus timeout flag. + * - I2C_ALERTF_FLAG: smbus alert flag. + * @retval none + */ +void i2c_flag_clear(i2c_type *i2c_x, uint32_t flag) +{ + i2c_x->sts1 = (uint16_t)~(flag & (uint32_t)0x00FFFFFF); +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_misc.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_misc.c new file mode 100644 index 0000000..25b34c1 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_misc.c @@ -0,0 +1,173 @@ +/** + ************************************************************************** + * @file at32f403a_407_misc.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the misc firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* includes ------------------------------------------------------------------*/ +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup MISC + * @brief MISC driver modules + * @{ + */ + +#ifdef MISC_MODULE_ENABLED + +/** @defgroup MISC_private_functions + * @{ + */ + +#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) + +/** + * @brief system reset + * @param none + * @retval none + */ +void nvic_system_reset(void) +{ + NVIC_SystemReset(); +} + +/** + * @brief enable nvic irq + * @param irqn (IRQn_Type number) + * @param preempt_priority: preemptive priority value (starting from 0) + * @param sub_priority: subpriority value (starting from 0) + * @retval none + */ +void nvic_irq_enable(IRQn_Type irqn, uint32_t preempt_priority, uint32_t sub_priority) +{ + uint32_t temp_priority = 0; + + /* encode priority */ + temp_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), preempt_priority, sub_priority); + /* set priority */ + NVIC_SetPriority(irqn, temp_priority); + /* enable irqn */ + NVIC_EnableIRQ(irqn); +} + +/** + * @brief disable nvic irq number + * @param irqn (IRQn_Type number) + * @retval none + */ +void nvic_irq_disable(IRQn_Type irqn) +{ + NVIC_DisableIRQ(irqn); +} + +/** + * @brief config nvic priority group + * @param priority_group + * this parameter can be one of the following values: + * - NVIC_PRIORITY_GROUP_0 + * - NVIC_PRIORITY_GROUP_1 + * - NVIC_PRIORITY_GROUP_2 + * - NVIC_PRIORITY_GROUP_3 + * - NVIC_PRIORITY_GROUP_4 + * @retval none + */ +void nvic_priority_group_config(nvic_priority_group_type priority_group) +{ + /* set the prigroup[10:8] bits according to nvic_prioritygroup value */ + NVIC_SetPriorityGrouping(priority_group); +} + +/** + * @brief set the vector table location and offset. + * @param base + * this parameter can be one of the following values: + * - NVIC_VECTTAB_RAM + * - NVIC_VECTTAB_FLASH + * @param offset (vector table base offset field. this value must be a multiple of 0x200) + * @retval none + */ +void nvic_vector_table_set(uint32_t base, uint32_t offset) +{ + SCB->VTOR = base | (offset & (uint32_t)0x1FFFFF80); +} + +/** + * @brief config nvic lowpower mode + * @param lp_mode + * this parameter can be one of the following values: + * - NVIC_LP_SEVONPEND + * - NVIC_LP_SLEEPDEEP + * - NVIC_LP_SLEEPONEXIT + * @param new_state (new state of lp condition. ENABLE or DISABLE) + * @retval none + */ +void nvic_lowpower_mode_config(nvic_lowpower_mode_type lp_mode, confirm_state new_state) +{ + if(new_state != FALSE) + { + SCB->SCR |= lp_mode; + } + else + { + SCB->SCR &= (uint32_t)(~(uint32_t)lp_mode); + } +} + +/** + * @brief config systick clock source + * @param source + * this parameter can be one of the following values: + * - SYSTICK_CLOCK_SOURCE_AHBCLK_DIV8 + * - SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV + * @retval none + */ +void systick_clock_source_config(systick_clock_source_type source) +{ + if(source == SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV) + { + SysTick->CTRL |= SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV; + } + else + { + SysTick->CTRL &= ~(uint32_t)SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV; + } +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ + + diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_pwc.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_pwc.c new file mode 100644 index 0000000..fc945a9 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_pwc.c @@ -0,0 +1,246 @@ +/** + ************************************************************************** + * @file at32f403a_407_pwc.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the pwc firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup PWC + * @brief PWC driver modules + * @{ + */ + +#ifdef PWC_MODULE_ENABLED + +/** @defgroup PWC_private_functions + * @{ + */ + +/** + * @brief deinitialize the pwc peripheral registers to their default reset values. + * @param none + * @retval none + */ +void pwc_reset(void) +{ + crm_periph_reset(CRM_PWC_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_PWC_PERIPH_RESET, FALSE); +} + +/** + * @brief enable or disable access to the battery powered domain. + * @param new_state: new state of battery powered domain access. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void pwc_battery_powered_domain_access(confirm_state new_state) +{ + PWC->ctrl_bit.bpwen = new_state; +} + +/** + * @brief select the voltage threshold detected by the power voltage detector. + * @param pvm_voltage: select pwc pvm voltage + * this parameter can be one of the following values: + * - PWC_PVM_VOLTAGE_2V3 + * - PWC_PVM_VOLTAGE_2V4 + * - PWC_PVM_VOLTAGE_2V5 + * - PWC_PVM_VOLTAGE_2V6 + * - PWC_PVM_VOLTAGE_2V7 + * - PWC_PVM_VOLTAGE_2V8 + * - PWC_PVM_VOLTAGE_2V9 + * @retval none + */ +void pwc_pvm_level_select(pwc_pvm_voltage_type pvm_voltage) +{ + PWC->ctrl_bit.pvmsel = pvm_voltage; +} + +/** + * @brief enable or disable pwc power voltage monitor (pvm) + * @param new_state: new state of pvm. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void pwc_power_voltage_monitor_enable(confirm_state new_state) +{ + PWC->ctrl_bit.pvmen = new_state; +} + +/** + * @brief enable or disable pwc standby wakeup pin + * @param pin_num: choose the wakeup pin. + * this parameter can be be any combination of the following values: + * - PWC_WAKEUP_PIN_1 + * @param new_state: new state of the standby wakeup pin. + * this parameter can be one of the following values: + * - TRUE + * - FALSE + * @retval none + */ +void pwc_wakeup_pin_enable(uint32_t pin_num, confirm_state new_state) +{ + if(new_state == TRUE) + { + PWC->ctrlsts |= pin_num; + } + else + { + PWC->ctrlsts &= ~pin_num; + } +} + +/** + * @brief clear flag of pwc + * @param pwc_flag: select the pwc flag. + * this parameter can be any combination of the following values: + * - PWC_WAKEUP_FLAG + * - PWC_STANDBY_FLAG + * - note:"PWC_PVM_OUTPUT_FLAG" cannot be choose!this bit is readonly bit,it means the voltage monitoring output state + * @retval none + */ +void pwc_flag_clear(uint32_t pwc_flag) +{ + if(pwc_flag & PWC_STANDBY_FLAG) + PWC->ctrl_bit.clsef = TRUE; + if(pwc_flag & PWC_WAKEUP_FLAG) + PWC->ctrl_bit.clswef = TRUE; +} + +/** + * @brief get flag of pwc + * @param pwc_flag: select the pwc flag. + * this parameter can be one of the following values: + * - PWC_WAKEUP_FLAG + * - PWC_STANDBY_FLAG + * - PWC_PVM_OUTPUT_FLAG + * @retval state of select flag(SET or RESET). + */ +flag_status pwc_flag_get(uint32_t pwc_flag) +{ + flag_status status = RESET; + if ((PWC->ctrlsts & pwc_flag) == RESET) + { + status = RESET; + } + else + { + status = SET; + } + return status; +} + +/** + * @brief enter pwc sleep mode + * @param sleep_mode_enter: choose the instruction to enter sleep mode. + * this parameter can be one of the following values: + * - PWC_SLEEP_ENTER_WFI + * - PWC_SLEEP_ENTER_WFE + * @retval none + */ +void pwc_sleep_mode_enter(pwc_sleep_enter_type pwc_sleep_enter) +{ + SCB->SCR &= (uint32_t)~0x4; + if(pwc_sleep_enter == PWC_SLEEP_ENTER_WFE) + { + __SEV(); + __WFE(); + __WFE(); + } + else if(pwc_sleep_enter == PWC_SLEEP_ENTER_WFI) + { + __WFI(); + } +} + +/** + * @brief enter pwc deep-sleep mode + * @param pwc_deep_sleep_enter: choose the instruction to enter deep sleep mode. + * this parameter can be one of the following values: + * - PWC_DEEP_SLEEP_ENTER_WFI + * - PWC_DEEP_SLEEP_ENTER_WFE + * @retval none + */ +void pwc_deep_sleep_mode_enter(pwc_deep_sleep_enter_type pwc_deep_sleep_enter) +{ + SCB->SCR |= 0x04; + if(pwc_deep_sleep_enter == PWC_DEEP_SLEEP_ENTER_WFE) + { + __SEV(); + __WFE(); + __WFE(); + } + else if(pwc_deep_sleep_enter == PWC_DEEP_SLEEP_ENTER_WFI) + { + __WFI(); + } + SCB->SCR &= (uint32_t)~0x4; +} + +/** + * @brief regulate low power consumption in the deep sleep mode + * @param pwc_regulator: set the regulator state. + * this parameter can be one of the following values: + * - PWC_REGULATOR_ON + * - PWC_REGULATOR_LOW_POWER + * @retval none + */ +void pwc_voltage_regulate_set(pwc_regulator_type pwc_regulator) +{ + PWC->ctrl_bit.vrsel = pwc_regulator; +} + +/** + * @brief enter pwc standby mode + * @param none + * @retval none + */ +void pwc_standby_mode_enter(void) +{ + PWC->ctrl_bit.clswef = TRUE; + PWC->ctrl_bit.lpsel = TRUE; + SCB->SCR |= 0x04; +#if defined (__CC_ARM) + __force_stores(); +#endif + __WFI(); +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_rtc.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_rtc.c new file mode 100644 index 0000000..f6f453c --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_rtc.c @@ -0,0 +1,224 @@ +/** + ************************************************************************** + * @file at32f403a_407_rtc.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the rtc firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup RTC + * @brief RTC driver modules + * @{ + */ + +#ifdef RTC_MODULE_ENABLED + +/** @defgroup RTC_private_functions + * @{ + */ + +/** + * @brief rtc counter set + * @param counter_value (0x0000_0000 ~ 0xFFFF_FFFF) + * @retval none + */ +void rtc_counter_set(uint32_t counter_value) +{ + /* enter rtc config mode */ + RTC->ctrll = 0x003F; + + /* set rtc counter */ + RTC->cnth_bit.cnt = (uint16_t)(counter_value >> 16); + RTC->cntl_bit.cnt = (uint16_t)(counter_value & 0x0000FFFF); + + /* exit rtc config mode */ + RTC->ctrll = 0x000F; +} + +/** + * @brief rtc counter get + * @param none + * @retval rtc counter + */ +uint32_t rtc_counter_get(void) +{ + uint32_t cnt = 0; + + cnt = RTC->cnth; + cnt = (cnt << 16) | RTC->cntl; + + return cnt; +} + +/** + * @brief rtc divider set + * @param div_value (0x0000_0000 ~ 0xFFFF_FFFF) + * @retval none + */ +void rtc_divider_set(uint32_t div_value) +{ + /* enter rtc config mode */ + RTC->ctrll = 0x003F; + + /* set rtc divider */ + RTC->divh_bit.div = (uint16_t)(div_value >> 16); + RTC->divl_bit.div = (uint16_t)(div_value & 0x0000FFFF); + + /* exit rtc config mode */ + RTC->ctrll = 0x000F; +} + +/** + * @brief rtc divider get + * @param none + * @retval rtc counter + */ +uint32_t rtc_divider_get(void) +{ + uint32_t div = 0; + + div = RTC->divcnth; + div = (div << 16) | RTC->divcntl; + + return div; +} + +/** + * @brief rtc alarm value set + * @param alarm_value (0x0000_0000 ~ 0xFFFF_FFFF) + * @retval none + */ +void rtc_alarm_set(uint32_t alarm_value) +{ + /* enter rtc config mode */ + RTC->ctrll = 0x003F; + + /* set rtc alarm value */ + RTC->tah_bit.ta = (uint16_t)(alarm_value >> 16); + RTC->tal_bit.ta = (uint16_t)(alarm_value & 0x0000FFFF); + + /* exit rtc config mode */ + RTC->ctrll = 0x000F; +} + +/** + * @brief rtc interrupt enable + * @param source + * this parameter can be any combination of the following values: + * - RTC_TS_INT: time second interrupt. + * - RTC_TA_INT: time alarm interrupt. + * - RTC_OVF_INT: overflow interrupt. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void rtc_interrupt_enable(uint16_t source, confirm_state new_state) +{ + if(new_state == FALSE) + { + RTC->ctrlh &= ~source; + } + else + { + RTC->ctrlh |= source; + } +} + +/** + * @brief rtc flag get + * @param flag + * this parameter can be one of the following values: + * - RTC_TS_FLAG: time second flag. + * - RTC_TA_FLAG: time alarm flag. + * - RTC_OVF_FLAG: overflow flag. + * - RTC_UPDF_FLAG: rtc update finish flag. + * - RTC_CFGF_FLAG: rtc configuration finish flag. + * @retval state of rtc flag + */ +flag_status rtc_flag_get(uint16_t flag) +{ + flag_status status = RESET; + + if ((RTC->ctrll & flag) != (uint16_t)RESET) + { + status = SET; + } + else + { + status = RESET; + } + + return status; +} + +/** + * @brief rtc flag clear + * @param interrupt_flag + * this parameter can be any combination of the following values: + * - RTC_TS_FLAG: time second flag. + * - RTC_TA_FLAG: time alarm flag. + * - RTC_OVF_FLAG: overflow flag. + * - RTC_CFGF_FLAG: rtc configuration finish flag. + * @retval none + */ +void rtc_flag_clear(uint16_t flag) +{ + RTC->ctrll = ~(flag | 0x10) | (RTC->ctrll_bit.cfgen << 4); +} + +/** + * @brief rtc wait configuration finish + * @param none + * @retval none + */ +void rtc_wait_config_finish(void) +{ + while (RTC->ctrll_bit.cfgf == 0); +} + +/** + * @brief rtc wait update finish + * @param none + * @retval none + */ +void rtc_wait_update_finish(void) +{ + while (RTC->ctrll_bit.updf == 0); +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_sdio.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_sdio.c new file mode 100644 index 0000000..8b66019 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_sdio.c @@ -0,0 +1,586 @@ +/** + ************************************************************************** + * @file at32f403a_407_sdio.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the sdio firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup SDIO + * @brief SDIO driver modules + * @{ + */ + +#ifdef SDIO_MODULE_ENABLED + +/** @defgroup SDIO_private_functions + * @{ + */ + +/** + * @brief reset the sdio register + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @retval none + */ +void sdio_reset(sdio_type *sdio_x) +{ + sdio_x->pwrctrl = 0x0; + sdio_x->clkctrl = 0x0; + sdio_x->argu = 0x0; + sdio_x->cmdctrl = 0x0; + sdio_x->dttmr = 0x0; + sdio_x->dtlen = 0x0; + sdio_x->dtctrl = 0x0; + sdio_x->inten = 0x0; + sdio_x->intclr = 0x004007FF; +} + +/** + * @brief set the power status of the controller + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param power_state + * this parameter can be one of the following values: + * - SDIO_POWER_OFF + * - SDIO_POWER_ON + * @retval none + */ +void sdio_power_set(sdio_type *sdio_x, sdio_power_state_type power_state) +{ + sdio_x->pwrctrl_bit.ps = power_state; +} + +/** + * @brief get power status. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @retval flag_status (SET or RESET) + */ +flag_status sdio_power_status_get(sdio_type *sdio_x) +{ + flag_status flag = RESET; + + if(sdio_x->pwrctrl_bit.ps == SDIO_POWER_ON) + { + flag = SET; + } + else if(sdio_x->pwrctrl_bit.ps == SDIO_POWER_OFF) + { + flag = RESET; + } + + return flag; +} + +/** + * @brief config sdio clock + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param clk_div: sdio clock divide factor(frequency = sdio_clk / [clk_psc + 2]). + * @param clk_edg + * this parameter can be one of the following values: + * - SDIO_CLOCK_EDGE_RISING + * - SDIO_CLOCK_EDGE_FALLING + * @retval none + */ +void sdio_clock_config(sdio_type *sdio_x, uint16_t clk_div, sdio_edge_phase_type clk_edg) +{ + /* config clock edge */ + sdio_x->clkctrl_bit.clkegs = clk_edg; + + /* config clock divide [7:0] */ + sdio_x->clkctrl_bit.clkdiv_l = (clk_div & 0xFF); + + /* config clock divide [9:8] */ + sdio_x->clkctrl_bit.clkdiv_h = ((clk_div & 0x300) >> 8); +} + +/** + * @brief config sdio bus width + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param width + * this parameter can be one of the following values: + * - SDIO_BUS_WIDTH_D1 + * - SDIO_BUS_WIDTH_D4 + * - SDIO_BUS_WIDTH_D8 + * @retval none + */ +void sdio_bus_width_config(sdio_type *sdio_x, sdio_bus_width_type width) +{ + sdio_x->clkctrl_bit.busws = width; +} + +/** + * @brief enable or disable clock divider bypss + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_clock_bypass(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->clkctrl_bit.bypsen = new_state; +} + +/** + * @brief enable or disable power saving mode, config sdio_ck clock output + * when the bus is idle. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_power_saving_mode_enable(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->clkctrl_bit.pwrsven = new_state; +} + +/** + * @brief enable or disable hardware flow control. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_flow_control_enable(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->clkctrl_bit.hfcen = new_state; +} + +/** + * @brief enable or disable sdio_ck output. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_clock_enable(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->clkctrl_bit.clkoen = new_state; +} + +/** + * @brief enable or disable dma. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_dma_enable(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->dtctrl_bit.dmaen = new_state; +} + +/** + * @brief config corresponding interrupt. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param int_opt + * this parameter can be one of the following values: + * - SDIO_CMDFAIL_INT + * - SDIO_DTFAIL_INT + * - SDIO_CMDTIMEOUT_INT + * - SDIO_DTTIMEOUT_INT + * - SDIO_TXERRU_INT + * - SDIO_RXERRO_INT + * - SDIO_CMDRSPCMPL_INT + * - SDIO_CMDCMPL_INT + * - SDIO_DTCMP_INT + * - SDIO_SBITERR_INT + * - SDIO_DTBLKCMPL_INT + * - SDIO_DOCMD_INT + * - SDIO_DOTX_INT + * - SDIO_DORX_INT + * - SDIO_TXBUFH_INT + * - SDIO_RXBUFH_INT + * - SDIO_TXBUFF_INT + * - SDIO_RXBUFF_INT + * - SDIO_TXBUFE_INT + * - SDIO_RXBUFE_INT + * - SDIO_TXBUF_INT + * - SDIO_RXBUF_INT + * - SDIO_SDIOIF_INT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_interrupt_enable(sdio_type *sdio_x, uint32_t int_opt, confirm_state new_state) +{ + /* enable interrupt */ + if(TRUE == new_state) + { + sdio_x->inten |= int_opt; + } + /* disable interrupt */ + else + { + sdio_x->inten &= ~(int_opt); + } +} + +/** + * @brief get sdio flag. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param flag + * this parameter can be one of the following values: + * - SDIO_CMDFAIL_FLAG + * - SDIO_DTFAIL_FLAG + * - SDIO_CMDTIMEOUT_FLAG + * - SDIO_DTTIMEOUT_FLAG + * - SDIO_TXERRU_FLAG + * - SDIO_RXERRO_FLAG + * - SDIO_CMDRSPCMPL_FLAG + * - SDIO_CMDCMPL_FLAG + * - SDIO_DTCMPL_FLAG + * - SDIO_SBITERR_FLAG + * - SDIO_DTBLKCMPL_FLAG + * - SDIO_DOCMD_FLAG + * - SDIO_DOTX_FLAG + * - SDIO_DORX_FLAG + * - SDIO_TXBUFH_FLAG + * - SDIO_RXBUFH_FLAG + * - SDIO_TXBUFF_FLAG + * - SDIO_RXBUFF_FLAG + * - SDIO_TXBUFE_FLAG + * - SDIO_RXBUFE_FLAG + * - SDIO_TXBUF_FLAG + * - SDIO_RXBUF_FLAG + * - SDIO_SDIOIF_FLAG + * @retval flag_status (SET or RESET) + */ +flag_status sdio_flag_get(sdio_type *sdio_x, uint32_t flag) +{ + flag_status status = RESET; + + if((sdio_x->sts & flag) == flag) + { + status = SET; + } + else + { + status = RESET; + } + + return status; +} + +/** + * @brief clear sdio flag. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param int_opt + * this parameter can be any combination of the following values: + * - SDIO_CMDFAIL_FLAG + * - SDIO_DTFAIL_FLAG + * - SDIO_CMDTIMEOUT_FLAG + * - SDIO_DTTIMEOUT_FLAG + * - SDIO_TXERRU_FLAG + * - SDIO_RXERRO_FLAG + * - SDIO_CMDRSPCMPL_FLAG + * - SDIO_CMDCMPL_FLAG + * - SDIO_DTCMPL_FLAG + * - SDIO_SBITERR_FLAG + * - SDIO_DTBLKCMPL_FLAG + * - SDIO_SDIOIF_FLAG + * @retval none + */ +void sdio_flag_clear(sdio_type *sdio_x, uint32_t flag) +{ + sdio_x->intclr = flag; +} + +/** + * @brief config sdio command. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param command_struct : pointer to a sdio_command_struct_type structure + * that contains the configuration information for the sdio command. + * @retval none + */ +void sdio_command_config(sdio_type *sdio_x, sdio_command_struct_type *command_struct) +{ + /* disable command path state machine */ + sdio_x->cmdctrl_bit.ccsmen = FALSE; + + /* config command argument */ + sdio_x->argu = command_struct->argument; + + /* config command register */ + sdio_x->cmdctrl_bit.cmdidx = command_struct->cmd_index; + sdio_x->cmdctrl_bit.rspwt = command_struct->rsp_type; + sdio_x->cmdctrl_bit.intwt = (command_struct->wait_type & 0x1); /* [1:0] -> [0] */ + sdio_x->cmdctrl_bit.pndwt = (command_struct->wait_type & 0x2)>>1; /* [1:0] -> [1] */ +} + +/** + * @brief enable or disable command path state machine(CPSM). + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_command_state_machine_enable(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->cmdctrl_bit.ccsmen = new_state; +} + +/** + * @brief get command index of last command for which response received. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval uint8_t: command index + */ +uint8_t sdio_command_response_get(sdio_type *sdio_x) +{ + return sdio_x->rspcmd_bit.rspcmd; +} + +/** + * @brief get response received from the card for the last command. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param reg_index + * this parameter can be one of the following values: + * - SDIO_RSP1_INDEX + * - SDIO_RSP2_INDEX + * - SDIO_RSP3_INDEX + * - SDIO_RSP4_INDEX + * @retval uint32_t: response register value + */ +uint32_t sdio_response_get(sdio_type *sdio_x, sdio_rsp_index_type reg_index) +{ + uint32_t response_value = 0; + + switch(reg_index) + { + case SDIO_RSP1_INDEX: + response_value = sdio_x->rsp1; + break; + case SDIO_RSP2_INDEX: + response_value = sdio_x->rsp2; + break; + case SDIO_RSP3_INDEX: + response_value = sdio_x->rsp3; + break; + case SDIO_RSP4_INDEX: + response_value = sdio_x->rsp4; + break; + default: break; + } + + return response_value; +} + +/** + * @brief config sdio data. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param data_struct : pointer to a sdio_data_struct_type structure + * that contains the configuration information for the sdio data. + * @retval none + */ +void sdio_data_config(sdio_type *sdio_x, sdio_data_struct_type *data_struct) +{ + /* disable data path state machine */ + sdio_x->dtctrl_bit.tfren = FALSE; + + /* config data block, transfer mode and transfer direction */ + sdio_x->dtctrl_bit.blksize = data_struct->block_size; + sdio_x->dtctrl_bit.tfrdir = data_struct->transfer_direction; + sdio_x->dtctrl_bit.tfrmode = data_struct->transfer_mode; + + /* config data length */ + sdio_x->dtlen_bit.dtlen = data_struct->data_length; + + /* config data transfer timeout */ + sdio_x->dttmr_bit.timeout = data_struct->timeout; +} + +/** + * @brief enable or disable data path state machine(DPSM). + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_data_state_machine_enable(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->dtctrl_bit.tfren = new_state; +} + +/** + * @brief get the number of remaining data bytes to be transferred. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @retval uint32_t: number of bytes + */ +uint32_t sdio_data_counter_get(sdio_type *sdio_x) +{ + return sdio_x->dtcnt; +} + +/** + * @brief read a word data from sdio fifo. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @retval uint32_t: data received + */ +uint32_t sdio_data_read(sdio_type *sdio_x) +{ + return sdio_x->buf; +} + +/** + * @brief get the number of words left to be written to or read from fifo.. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @retval uint32_t: number of words + */ +uint32_t sdio_buffer_counter_get(sdio_type *sdio_x) +{ + return sdio_x->bufcnt; +} + +/** + * @brief write one word data to fifo. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param data: data to be transferred. + * @retval none + */ +void sdio_data_write(sdio_type *sdio_x, uint32_t data) +{ + sdio_x->buf = data; +} + +/** + * @brief set the read wait mode. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param mode + * this parameter can be one of the following values: + * - SDIO_READ_WAIT_CONTROLLED_BY_D2 + * - SDIO_READ_WAIT_CONTROLLED_BY_CK + * @retval none + */ +void sdio_read_wait_mode_set(sdio_type *sdio_x, sdio_read_wait_mode_type mode) +{ + sdio_x->dtctrl_bit.rdwtmode = mode; +} + +/** + * @brief enable or disable to start sd i/o read wait operation. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_read_wait_start(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->dtctrl_bit.rdwtstart = new_state; +} + +/** + * @brief enable or disable to stop sd i/o read wait operation. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_read_wait_stop(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->dtctrl_bit.rdwtstop = new_state; +} + +/** + * @brief enable or disable the sd i/o function. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_io_function_enable(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->dtctrl_bit.ioen = new_state; +} + +/** + * @brief enable or disable sd i/o suspend command sending. + * @param sdio_x: to select the sdio peripheral. + * this parameter can be one of the following values: + * SDIO1, SDIO2. + * @param new_state (TRUE or FALSE) + * @retval none + */ +void sdio_io_suspend_command_set(sdio_type *sdio_x, confirm_state new_state) +{ + sdio_x->cmdctrl_bit.iosusp = new_state; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_spi.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_spi.c new file mode 100644 index 0000000..720aa92 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_spi.c @@ -0,0 +1,618 @@ +/** + ************************************************************************** + * @file at32f403a_407_spi.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the spi firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup SPI + * @brief SPI driver modules + * @{ + */ + +#ifdef SPI_MODULE_ENABLED + +/** @defgroup SPI_private_functions + * @{ + */ + +/** + * @brief spi reset by crm reset register + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @retval none + */ +void spi_i2s_reset(spi_type *spi_x) +{ + if(spi_x == SPI1) + { + crm_periph_reset(CRM_SPI1_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_SPI1_PERIPH_RESET, FALSE); + } + else if(spi_x == SPI2) + { + crm_periph_reset(CRM_SPI2_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_SPI2_PERIPH_RESET, FALSE); + } + else if(spi_x == SPI3) + { + crm_periph_reset(CRM_SPI3_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_SPI3_PERIPH_RESET, FALSE); + } + else if(spi_x == SPI4) + { + crm_periph_reset(CRM_SPI4_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_SPI4_PERIPH_RESET, FALSE); + } +} + +/** + * @brief spi init config with its default value. + * @param spi_init_struct : pointer to a spi_init_type structure which will + * be initialized. + * @retval none + */ +void spi_default_para_init(spi_init_type* spi_init_struct) +{ + spi_init_struct->transmission_mode = SPI_TRANSMIT_FULL_DUPLEX; + spi_init_struct->master_slave_mode = SPI_MODE_SLAVE; + spi_init_struct->mclk_freq_division = SPI_MCLK_DIV_2; + spi_init_struct->first_bit_transmission = SPI_FIRST_BIT_MSB; + spi_init_struct->frame_bit_num = SPI_FRAME_8BIT; + spi_init_struct->clock_polarity = SPI_CLOCK_POLARITY_LOW; + spi_init_struct->clock_phase = SPI_CLOCK_PHASE_1EDGE; + spi_init_struct->cs_mode_selection = SPI_CS_SOFTWARE_MODE; +} + +/** + * @brief spi init config with its setting value. + * @param spi_init_struct : pointer to a spi_init_type structure which will be initialized. + * @retval none + */ +void spi_init(spi_type* spi_x, spi_init_type* spi_init_struct) +{ + spi_x->i2sctrl_bit.i2smsel = FALSE; + if(spi_init_struct->transmission_mode == SPI_TRANSMIT_FULL_DUPLEX) + { + spi_x->ctrl1_bit.slben = FALSE; + spi_x->ctrl1_bit.slbtd = FALSE; + spi_x->ctrl1_bit.ora = FALSE; + } + else if(spi_init_struct->transmission_mode == SPI_TRANSMIT_SIMPLEX_RX) + { + spi_x->ctrl1_bit.slben = FALSE; + spi_x->ctrl1_bit.slbtd = FALSE; + spi_x->ctrl1_bit.ora = TRUE; + } + else if(spi_init_struct->transmission_mode == SPI_TRANSMIT_HALF_DUPLEX_RX) + { + spi_x->ctrl1_bit.slben = TRUE; + spi_x->ctrl1_bit.slbtd = FALSE; + spi_x->ctrl1_bit.ora = FALSE; + } + else if(spi_init_struct->transmission_mode == SPI_TRANSMIT_HALF_DUPLEX_TX) + { + spi_x->ctrl1_bit.slben = TRUE; + spi_x->ctrl1_bit.slbtd = TRUE; + spi_x->ctrl1_bit.ora = FALSE; + } + + spi_x->ctrl1_bit.swcsen = spi_init_struct->cs_mode_selection; + if((spi_init_struct->master_slave_mode == SPI_MODE_MASTER) && (spi_init_struct->cs_mode_selection == SPI_CS_SOFTWARE_MODE)) + { + spi_x->ctrl1_bit.swcsil = TRUE; + } + else + { + spi_x->ctrl1_bit.swcsil = FALSE; + } + spi_x->ctrl1_bit.msten = spi_init_struct->master_slave_mode; + if(spi_init_struct->mclk_freq_division > SPI_MCLK_DIV_256) + { + spi_x->ctrl2_bit.mdiv_h = 1; + spi_x->ctrl1_bit.mdiv_l = spi_init_struct->mclk_freq_division & 0x7; + } + else + { + spi_x->ctrl2_bit.mdiv_h = 0; + spi_x->ctrl1_bit.mdiv_l = spi_init_struct->mclk_freq_division; + } + spi_x->ctrl1_bit.ltf = spi_init_struct->first_bit_transmission; + spi_x->ctrl1_bit.fbn = spi_init_struct->frame_bit_num; + spi_x->ctrl1_bit.clkpol = spi_init_struct->clock_polarity; + spi_x->ctrl1_bit.clkpha = spi_init_struct->clock_phase; +} + +/** + * @brief spi next transmit crc for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @retval none + */ +void spi_crc_next_transmit(spi_type* spi_x) +{ + spi_x->ctrl1_bit.ntc = TRUE; +} + +/** + * @brief set the crc polynomial value for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param crc_poly: crc polynomial value. + * @retval none + */ +void spi_crc_polynomial_set(spi_type* spi_x, uint16_t crc_poly) +{ + spi_x->cpoly_bit.cpoly = crc_poly; +} + +/** + * @brief return the crc polynomial register value for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @retval the select crc polynomial register value + */ +uint16_t spi_crc_polynomial_get(spi_type* spi_x) +{ + return spi_x->cpoly_bit.cpoly; +} + +/** + * @brief enable or disable the hardware crc calculation for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param new_state: new state of crc calculation. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void spi_crc_enable(spi_type* spi_x, confirm_state new_state) +{ + spi_x->ctrl1_bit.ccen = new_state; +} + +/** + * @brief return the transmit or the receive crc value for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param crc_direction: select transmit or receive crc value to be read + * - SPI_CRC_RX + * - SPI_CRC_TX + * @retval the select crc register value + */ +uint16_t spi_crc_value_get(spi_type* spi_x, spi_crc_direction_type crc_direction) +{ + if(crc_direction == SPI_CRC_RX) + return spi_x->rcrc_bit.rcrc; + else + return spi_x->tcrc_bit.tcrc; +} + +/** + * @brief enable or disable the hardware cs output for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param new_state: new state of spi master cs output. + * this parameter can be: TRUE or FALSE. + * note:the bit only use in spi master mode + * @retval none + */ +void spi_hardware_cs_output_enable(spi_type* spi_x, confirm_state new_state) +{ + spi_x->ctrl2_bit.hwcsoe = new_state; +} + +/** + * @brief set the software cs internal level for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param level: set the state of spi cs level. + * this parameter can be one of the following values: + * - SPI_SWCS_INTERNAL_LEVEL_LOW + * - SPI_SWCS_INTERNAL_LEVEL_HIGHT + * note:the bit only use when swcsen bit is set. + * note:when use this bit,io operation on the cs pin are invalid. + * @retval none + */ +void spi_software_cs_internal_level_set(spi_type* spi_x, spi_software_cs_level_type level) +{ + spi_x->ctrl1_bit.swcsil = level; +} + +/** + * @brief set the data frame bit num for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param bit_num: set the data frame size + * - SPI_FRAME_8BIT + * - SPI_FRAME_16BIT + * @retval none + */ +void spi_frame_bit_num_set(spi_type* spi_x, spi_frame_bit_num_type bit_num) +{ + spi_x->ctrl1_bit.fbn = bit_num; +} + +/** + * @brief set the data transmission direction in single line bidirectiona half duplex mode of the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param direction: data transfer direction + * this parameter can be one of the following values: + * - SPI_HALF_DUPLEX_DIRECTION_RX + * - SPI_HALF_DUPLEX_DIRECTION_TX + * @retval none + */ +void spi_half_duplex_direction_set(spi_type* spi_x, spi_half_duplex_direction_type direction) +{ + spi_x->ctrl1_bit.slbtd = direction; +} + +/** + * @brief enable or disable spi. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param new_state: new state of spi. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void spi_enable(spi_type* spi_x, confirm_state new_state) +{ + spi_x->ctrl1_bit.spien = new_state; +} + +/** + * @brief i2s init config with its default value. + * @param i2s_init_struct : pointer to a i2s_init_type structure which will + * be initialized. + * @retval none + */ +void i2s_default_para_init(i2s_init_type* i2s_init_struct) +{ + i2s_init_struct->operation_mode = I2S_MODE_SLAVE_TX; + i2s_init_struct->audio_protocol = I2S_AUDIO_PROTOCOL_PHILLIPS; + i2s_init_struct->audio_sampling_freq = I2S_AUDIO_FREQUENCY_DEFAULT; + i2s_init_struct->data_channel_format = I2S_DATA_16BIT_CHANNEL_16BIT; + i2s_init_struct->clock_polarity = I2S_CLOCK_POLARITY_LOW; + i2s_init_struct->mclk_output_enable = FALSE; +} + +/** + * @brief i2s init config with its setting value. + * @param i2s_init_struct : pointer to a i2s_init_type structure which will be initialized. + * @retval none + */ +void i2s_init(spi_type* spi_x, i2s_init_type* i2s_init_struct) +{ + crm_clocks_freq_type clocks_freq; + uint32_t i2s_sclk_index = 0; + uint32_t i2sdiv_index = 2, i2sodd_index = 0, frequency_index = 0; + + /* i2s audio frequency config */ + if(i2s_init_struct->audio_sampling_freq == I2S_AUDIO_FREQUENCY_DEFAULT) + { + i2sodd_index = 0; + i2sdiv_index = 2; + } + else + { + crm_clocks_freq_get(&clocks_freq); + i2s_sclk_index = clocks_freq.sclk_freq; + if((i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PCM_SHORT) || (i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PCM_LONG)) + { + if(i2s_init_struct->mclk_output_enable == TRUE) + { + frequency_index = (((i2s_sclk_index / 128) * 10) / i2s_init_struct->audio_sampling_freq) + 5; + } + else + { + if(i2s_init_struct->data_channel_format == I2S_DATA_16BIT_CHANNEL_16BIT) + frequency_index = (((i2s_sclk_index / 16) * 10) / i2s_init_struct->audio_sampling_freq) + 5; + else + frequency_index = (((i2s_sclk_index / 32) * 10) / i2s_init_struct->audio_sampling_freq) + 5; + } + } + else + { + if(i2s_init_struct->mclk_output_enable == TRUE) + { + frequency_index = (((i2s_sclk_index / 256) * 10) / i2s_init_struct->audio_sampling_freq) + 5; + } + else + { + if(i2s_init_struct->data_channel_format == I2S_DATA_16BIT_CHANNEL_16BIT) + frequency_index = (((i2s_sclk_index / 32) * 10) / i2s_init_struct->audio_sampling_freq) + 5; + else + frequency_index = (((i2s_sclk_index / 64) * 10) / i2s_init_struct->audio_sampling_freq) + 5; + } + } + } + frequency_index = frequency_index / 10; + i2sodd_index = frequency_index & (uint16_t)0x0001; + i2sdiv_index = (frequency_index - i2sodd_index) / 2; + if((i2sdiv_index < 2) || (i2sdiv_index > 0x03FF)) + { + i2sodd_index = 0; + i2sdiv_index = 2; + } + spi_x->i2sclk_bit.i2sodd = i2sodd_index; + if(i2sdiv_index > 0x00FF) + { + spi_x->i2sclk_bit.i2sdiv_h = (i2sdiv_index >> 8) & 0x0003; + spi_x->i2sclk_bit.i2sdiv_l = i2sdiv_index & 0x00FF; + } + else + { + spi_x->i2sclk_bit.i2sdiv_h = 0; + spi_x->i2sclk_bit.i2sdiv_l = i2sdiv_index; + } + + /* i2s audio_protocol set*/ + if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PCM_LONG) + { + spi_x->i2sctrl_bit.pcmfssel = 1; + spi_x->i2sctrl_bit.stdsel = 3; + } + else if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PCM_SHORT) + { + spi_x->i2sctrl_bit.pcmfssel = 0; + spi_x->i2sctrl_bit.stdsel = 3; + } + else if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_LSB) + { + spi_x->i2sctrl_bit.pcmfssel = 0; + spi_x->i2sctrl_bit.stdsel = 2; + } + else if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_MSB) + { + spi_x->i2sctrl_bit.pcmfssel = 0; + spi_x->i2sctrl_bit.stdsel = 1; + } + else if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PHILLIPS) + { + spi_x->i2sctrl_bit.pcmfssel = 0; + spi_x->i2sctrl_bit.stdsel = 0; + } + + /* i2s data_channel_format set*/ + if(i2s_init_struct->data_channel_format == I2S_DATA_16BIT_CHANNEL_16BIT) + { + spi_x->i2sctrl_bit.i2scbn = 0; + spi_x->i2sctrl_bit.i2sdbn = 0; + } + else if(i2s_init_struct->data_channel_format == I2S_DATA_16BIT_CHANNEL_32BIT) + { + spi_x->i2sctrl_bit.i2scbn = 1; + spi_x->i2sctrl_bit.i2sdbn = 0; + } + else if(i2s_init_struct->data_channel_format == I2S_DATA_24BIT_CHANNEL_32BIT) + { + spi_x->i2sctrl_bit.i2scbn = 1; + spi_x->i2sctrl_bit.i2sdbn = 1; + } + else if(i2s_init_struct->data_channel_format == I2S_DATA_32BIT_CHANNEL_32BIT) + { + spi_x->i2sctrl_bit.i2scbn = 1; + spi_x->i2sctrl_bit.i2sdbn = 2; + } + + spi_x->i2sctrl_bit.i2sclkpol = i2s_init_struct->clock_polarity; + spi_x->i2sclk_bit.i2smclkoe = i2s_init_struct->mclk_output_enable; + spi_x->i2sctrl_bit.opersel = i2s_init_struct->operation_mode; + spi_x->i2sctrl_bit.i2smsel = TRUE; +} + +/** + * @brief enable or disable i2s. + * @param spi_x: select the i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param new_state: new state of i2s. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void i2s_enable(spi_type* spi_x, confirm_state new_state) +{ + spi_x->i2sctrl_bit.i2sen = new_state; +} + +/** + * @brief enable or disable the specified spi/i2s interrupts. + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param spi_i2s_int: specifies the spi/i2s interrupt sources to be enabled or disabled. + * this parameter can be one of the following values: + * - SPI_I2S_ERROR_INT + * - SPI_I2S_RDBF_INT + * - SPI_I2S_TDBE_INT + * @param new_state: new state of the specified spi/i2s interrupts. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void spi_i2s_interrupt_enable(spi_type* spi_x, uint32_t spi_i2s_int, confirm_state new_state) +{ + if(new_state != FALSE) + { + spi_x->ctrl2 |= spi_i2s_int; + } + else + { + spi_x->ctrl2 &= ~spi_i2s_int; + } +} + +/** + * @brief enable or disable the spi/i2s dma transmitter mode. + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param new_state: new state of the dma request. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void spi_i2s_dma_transmitter_enable(spi_type* spi_x, confirm_state new_state) +{ + spi_x->ctrl2_bit.dmaten = new_state; +} + +/** + * @brief enable or disable the spi/i2s dma receiver mode. + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param new_state: new state of the dma request. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void spi_i2s_dma_receiver_enable(spi_type* spi_x, confirm_state new_state) +{ + spi_x->ctrl2_bit.dmaren = new_state; +} + +/** + * @brief spi/i2s data transmit + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param tx_data: the data to be transmit. + * this parameter can be: + * - (0x0000~0xFFFF) + * @retval none + */ +void spi_i2s_data_transmit(spi_type* spi_x, uint16_t tx_data) +{ + spi_x->dt = tx_data; +} + +/** + * @brief spi/i2s data receive + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @retval the received data value + */ +uint16_t spi_i2s_data_receive(spi_type* spi_x) +{ + return (uint16_t)spi_x->dt; +} + +/** + * @brief get flag of the specified spi/i2s peripheral. + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param spi_i2s_flag: select the spi/i2s flag + * this parameter can be one of the following values: + * - SPI_I2S_RDBF_FLAG + * - SPI_I2S_TDBE_FLAG + * - I2S_ACS_FLAG (this flag only use in i2s mode) + * - I2S_TUERR_FLAG (this flag only use in i2s mode) + * - SPI_CCERR_FLAG (this flag only use in spi mode) + * - SPI_MMERR_FLAG (this flag only use in spi mode) + * - SPI_I2S_ROERR_FLAG + * - SPI_I2S_BF_FLAG + * @retval the new state of spi/i2s flag + */ +flag_status spi_i2s_flag_get(spi_type* spi_x, uint32_t spi_i2s_flag) +{ + flag_status status = RESET; + if ((spi_x->sts & spi_i2s_flag) == RESET) + { + status = RESET; + } + else + { + status = SET; + } + return status; +} + +/** + * @brief clear flag of the specified spi/i2s peripheral. + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 ,SPI4 + * @param spi_i2s_flag: select the spi/i2s flag + * this parameter can be one of the following values: + * - SPI_CCERR_FLAG + * - SPI_I2S_RDBF_FLAG + * - I2S_TUERR_FLAG + * - SPI_MMERR_FLAG + * - SPI_I2S_ROERR_FLAG + * @note + * SPI_I2S_TDBE_FLAG this flag is cleared when the tx buffer already contain data to be transmit. + * I2S_ACS_FLAG this flag cann't cleared by software,the flag indicate the channel side(not use in pcm standard mode). + * SPI_I2S_BF_FLAG this flag cann't cleared by software, it's set and cleared by hardware. + * @retval none + */ +void spi_i2s_flag_clear(spi_type* spi_x, uint32_t spi_i2s_flag) +{ + volatile uint32_t temp = 0; + temp = temp; + if(spi_i2s_flag == SPI_CCERR_FLAG) + spi_x->sts = ~SPI_CCERR_FLAG; + else if(spi_i2s_flag == SPI_I2S_RDBF_FLAG) + temp = REG32(&spi_x->dt); + else if(spi_i2s_flag == I2S_TUERR_FLAG) + temp = REG32(&spi_x->sts); + else if(spi_i2s_flag == SPI_MMERR_FLAG) + { + temp = REG32(&spi_x->sts); + spi_x->ctrl1 = spi_x->ctrl1; + } + else if(spi_i2s_flag == SPI_I2S_ROERR_FLAG) + { + temp = REG32(&spi_x->dt); + temp = REG32(&spi_x->sts); + } +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_tmr.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_tmr.c new file mode 100644 index 0000000..e92df95 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_tmr.c @@ -0,0 +1,1763 @@ +/** + ************************************************************************** + * @file at32f403a_407_tmr.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the tmr firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup TMR + * @brief TMR driver modules + * @{ + */ + +#ifdef TMR_MODULE_ENABLED + +/** @defgroup TMR_private_functions + * @{ + */ + +/** + * @brief tmr reset by crm reset register + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR6, TMR7, TMR8, + * TMR9, TMR10, TMR11, TMR12, TMR13, TMR14 + * @retval none + */ +void tmr_reset(tmr_type *tmr_x) +{ + if(tmr_x == TMR1) + { + crm_periph_reset(CRM_TMR1_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR1_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR2) + { + crm_periph_reset(CRM_TMR2_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR2_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR3) + { + crm_periph_reset(CRM_TMR3_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR3_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR4) + { + crm_periph_reset(CRM_TMR4_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR4_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR5) + { + crm_periph_reset(CRM_TMR5_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR5_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR6) + { + crm_periph_reset(CRM_TMR6_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR6_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR7) + { + crm_periph_reset(CRM_TMR7_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR7_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR8) + { + crm_periph_reset(CRM_TMR8_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR8_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR9) + { + crm_periph_reset(CRM_TMR9_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR9_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR10) + { + crm_periph_reset(CRM_TMR10_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR10_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR11) + { + crm_periph_reset(CRM_TMR11_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR11_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR12) + { + crm_periph_reset(CRM_TMR12_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR12_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR13) + { + crm_periph_reset(CRM_TMR13_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR13_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR14) + { + crm_periph_reset(CRM_TMR14_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR14_PERIPH_RESET, FALSE); + } +} + +/** + * @brief enable or disable tmr counter + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR6, TMR7, TMR8, + * TMR9, TMR10, TMR11, TMR12, TMR13, TMR14 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_counter_enable(tmr_type *tmr_x, confirm_state new_state) +{ + /* tmr counter enable */ + tmr_x->ctrl1_bit.tmren = new_state; +} + +/** + * @brief init tmr output default para + * @param tmr_output_struct + * - to the structure of tmr_output_config_type + * @retval none + */ +void tmr_output_default_para_init(tmr_output_config_type *tmr_output_struct) +{ + tmr_output_struct->oc_mode = TMR_OUTPUT_CONTROL_OFF; + tmr_output_struct->oc_idle_state = FALSE; + tmr_output_struct->occ_idle_state = FALSE; + tmr_output_struct->oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct->occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct->oc_output_state = FALSE; + tmr_output_struct->occ_output_state = FALSE; +} + +/** + * @brief init tmr input default para + * @param tmr_input_struct + * - to the structure of tmr_input_config_type + * @retval none + */ +void tmr_input_default_para_init(tmr_input_config_type *tmr_input_struct) +{ + tmr_input_struct->input_channel_select = TMR_SELECT_CHANNEL_1; + tmr_input_struct->input_polarity_select = TMR_INPUT_RISING_EDGE; + tmr_input_struct->input_mapped_select = TMR_CC_CHANNEL_MAPPED_DIRECT; + tmr_input_struct->input_filter_value = 0x0; +} + +/** + * @brief init tmr brkdt default para + * @param tmr_brkdt_struct + * - to the structure of tmr_brkdt_config_type + * @retval none + */ +void tmr_brkdt_default_para_init(tmr_brkdt_config_type *tmr_brkdt_struct) +{ + tmr_brkdt_struct->deadtime = 0x0; + tmr_brkdt_struct->brk_polarity = TMR_BRK_INPUT_ACTIVE_LOW; + tmr_brkdt_struct->wp_level = TMR_WP_OFF; + tmr_brkdt_struct->auto_output_enable = FALSE ; + tmr_brkdt_struct->fcsoen_state = FALSE ; + tmr_brkdt_struct->fcsodis_state = FALSE ; + tmr_brkdt_struct->brk_enable = FALSE ; +} + +/** + * @brief init tmr base + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR6, TMR7, TMR8, + * TMR9, TMR10, TMR11, TMR12, TMR13, TMR14 + * @param tmr_pr (for 16 bit tmr 0x0000~0xFFFF, + * for 32 bit tmr 0x0000_0000~0xFFFF_FFFF) + * @param tmr_div (timer div value:0x0000~0xFFFF) + * @retval none + */ +void tmr_base_init(tmr_type* tmr_x, uint32_t tmr_pr, uint32_t tmr_div) +{ + /* set the pr value */ + tmr_x->pr = tmr_pr; + + /* set the div value */ + tmr_x->div = tmr_div; + + /* trigger the overflow event to immediately reload pr value and div value */ + tmr_x->swevt_bit.ovfswtr = TRUE; +} + +/** + * @brief set tmr clock source division + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR10, + * TMR11, TMR12, TMR13, TMR14 + * @param tmr_clock_div + * this parameter can be one of the following values: + * - TMR_CLOCK_DIV1 + * - TMR_CLOCK_DIV2 + * - TMR_CLOCK_DIV4 + * @retval none + */ +void tmr_clock_source_div_set(tmr_type *tmr_x, tmr_clock_division_type tmr_clock_div) +{ + /* set tmr clock source division */ + tmr_x->ctrl1_bit.clkdiv = tmr_clock_div; +} + +/** + * @brief set tmr counter count direction + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR10, + * TMR11, TMR12, TMR13, TMR14 + * @param tmr_cnt_dir + * this parameter can be one of the following values: + * - TMR_COUNT_UP + * - TMR_COUNT_DOWN + * - TMR_COUNT_TWO_WAY_1 + * - TMR_COUNT_TWO_WAY_2 + * - TMR_COUNT_TWO_WAY_3 + * @retval none + */ +void tmr_cnt_dir_set(tmr_type *tmr_x, tmr_count_mode_type tmr_cnt_dir) +{ + /* set the cnt direct */ + tmr_x->ctrl1_bit.cnt_dir = tmr_cnt_dir; +} + +/** + * @brief set the repetition counter register(rpr) value + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR8 + * @param tmr_rpr_value (0x00~0xFF) + * @retval none + */ +void tmr_repetition_counter_set(tmr_type *tmr_x, uint8_t tmr_rpr_value) +{ + /* set the repetition counter value */ + if((tmr_x == TMR1) || (tmr_x == TMR8)) + + { + tmr_x->rpr_bit.rpr = tmr_rpr_value; + } +} + +/** + * @brief set tmr counter value + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR6, TMR7, TMR8, + * TMR9, TMR10, TMR11, TMR12, TMR13, TMR14 + * @param tmr_cnt_value (for 16 bit tmr 0x0000~0xFFFF, + * for 32 bit tmr 0x0000_0000~0xFFFF_FFFF) + * @retval none + */ +void tmr_counter_value_set(tmr_type *tmr_x, uint32_t tmr_cnt_value) +{ + /* set the tmr counter value */ + tmr_x->cval = tmr_cnt_value; +} + +/** + * @brief get tmr counter value + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR6, TMR7, TMR8, + * TMR9, TMR10, TMR11, TMR12, TMR13, TMR14 + * @retval tmr counter value + */ +uint32_t tmr_counter_value_get(tmr_type *tmr_x) +{ + return tmr_x->cval; +} + +/** + * @brief set tmr div value + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR6, TMR7, TMR8, + * TMR9, TMR10, TMR11, TMR12, TMR13, TMR14 + * @param tmr_div_value (for 16 bit tmr 0x0000~0xFFFF, + * for 32 bit tmr 0x0000_0000~0xFFFF_FFFF) + * @retval none + */ +void tmr_div_value_set(tmr_type *tmr_x, uint32_t tmr_div_value) +{ + /* set the tmr div value */ + tmr_x->div = tmr_div_value; +} + +/** + * @brief get tmr div value + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR6, TMR7, TMR8, + * TMR9, TMR10, TMR11, TMR12, TMR13, TMR14 + * @retval tmr div value + */ +uint32_t tmr_div_value_get(tmr_type *tmr_x) +{ + return tmr_x->div; +} + +/** + * @brief config tmr output channel + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR10, + * TMR11, TMR12, TMR13, TMR14 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 + * - TMR_SELECT_CHANNEL_2 + * - TMR_SELECT_CHANNEL_3 + * - TMR_SELECT_CHANNEL_4 + * @param tmr_output_struct + * - to the structure of tmr_output_config_type + * @retval none + */ +void tmr_output_channel_config(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, + tmr_output_config_type *tmr_output_struct) +{ + uint16_t channel_index = 0, channel_c_index = 0, channel = 0; + + /* get channel idle state bit position in ctrl2 register */ + channel_index = (uint16_t)(tmr_output_struct->oc_idle_state << (8 + tmr_channel)); + + /* get channel complementary idle state bit position in ctrl2 register */ + channel_c_index = (uint16_t)(tmr_output_struct->occ_idle_state << (9 + tmr_channel)); + + if((tmr_x == TMR1) || (tmr_x == TMR8)) + { + /* set output channel complementary idle state */ + tmr_x->ctrl2 &= ~channel_c_index; + tmr_x->ctrl2 |= channel_c_index; + } + + /* set output channel idle state */ + tmr_x->ctrl2 &= ~channel_index; + tmr_x->ctrl2 |= channel_index; + + /* set channel output mode */ + channel = tmr_channel; + + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cm1_output_bit.c1octrl = tmr_output_struct->oc_mode; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cm1_output_bit.c2octrl = tmr_output_struct->oc_mode; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cm2_output_bit.c3octrl = tmr_output_struct->oc_mode; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cm2_output_bit.c4octrl = tmr_output_struct->oc_mode; + break; + + default: + break; + } + + /* get channel polarity bit position in cctrl register */ + channel_index = (uint16_t)(tmr_output_struct->oc_polarity << ((tmr_channel * 2) + 1)); + + /* get channel complementary polarity bit position in cctrl register */ + channel_c_index = (uint16_t)(tmr_output_struct->occ_polarity << ((tmr_channel * 2) + 3)); + + if((tmr_x == TMR1) || (tmr_x == TMR8)) + { + /* set output channel complementary polarity */ + tmr_x->cctrl &= ~channel_c_index; + tmr_x->cctrl |= channel_c_index; + } + + /* set output channel polarity */ + tmr_x->cctrl &= ~channel_index; + tmr_x->cctrl |= channel_index; + + /* get channel enable bit position in cctrl register */ + channel_index = (uint16_t)(tmr_output_struct->oc_output_state << (tmr_channel * 2)); + + /* get channel complementary enable bit position in cctrl register */ + channel_c_index = (uint16_t)(tmr_output_struct->occ_output_state << ((tmr_channel * 2) + 2)); + + if((tmr_x == TMR1) || (tmr_x == TMR8)) + { + /* set output channel complementary enable bit */ + tmr_x->cctrl &= ~channel_c_index; + tmr_x->cctrl |= channel_c_index; + } + + /* set output channel enable bit */ + tmr_x->cctrl &= ~channel_index; + tmr_x->cctrl |= channel_index; +} + +/** + * @brief select tmr output channel mode + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR10, + * TMR11, TMR12, TMR13, TMR14 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 + * - TMR_SELECT_CHANNEL_2 + * - TMR_SELECT_CHANNEL_3 + * - TMR_SELECT_CHANNEL_4 + * @param oc_mode + * this parameter can be one of the following values: + * - TMR_OUTPUT_CONTROL_OFF + * - TMR_OUTPUT_CONTROL_HIGH + * - TMR_OUTPUT_CONTROL_LOW + * - TMR_OUTPUT_CONTROL_SWITCH + * - TMR_OUTPUT_CONTROL_FORCE_HIGH + * - TMR_OUTPUT_CONTROL_FORCE_LOW + * - TMR_OUTPUT_CONTROL_PWM_MODE_A + * - TMR_OUTPUT_CONTROL_PWM_MODE_B + * @retval none + */ +void tmr_output_channel_mode_select(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, + tmr_output_control_mode_type oc_mode) +{ + uint16_t channel; + + channel = tmr_channel; + + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cm1_output_bit.c1octrl = oc_mode; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cm1_output_bit.c2octrl = oc_mode; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cm2_output_bit.c3octrl = oc_mode; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cm2_output_bit.c4octrl = oc_mode; + break; + + default: + break; + } +} +/** + * @brief set tmr period value + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR6, TMR7, TMR8, + * TMR9, TMR10, TMR11, TMR12, TMR13, TMR14 + * @param tmr_pr_value: timer period register value of counter + * (for 16 bit tmr 0x0000~0xFFFF, + * for 32 bit tmr 0x0000_0000~0xFFFF_FFFF) + * @retval none + */ +void tmr_period_value_set(tmr_type *tmr_x, uint32_t tmr_pr_value) +{ + /* set tmr period value */ + tmr_x->pr = tmr_pr_value; +} + +/** + * @brief get tmr period value + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR6, TMR7, TMR8, + * TMR9, TMR10, TMR11, TMR12, TMR13, TMR14 + * @retval timer period register value of counter + * (for 16 bit tmr 0x0000~0xFFFF, for 32 bit tmr + * 0x0000_0000~0xFFFF_FFFF) + */ +uint32_t tmr_period_value_get(tmr_type *tmr_x) +{ + return tmr_x->pr; +} + +/** + * @brief set tmr channel value + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR10, + * TMR11, TMR12, TMR13, TMR14 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 + * - TMR_SELECT_CHANNEL_2 + * - TMR_SELECT_CHANNEL_3 + * - TMR_SELECT_CHANNEL_4 + * @param tmr_channel_value (for 16 bit tmr 0x0000~0xFFFF, + * for 32 bit tmr 0x0000_0000~0xFFFF_FFFF) + * @retval none + */ +void tmr_channel_value_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, + uint32_t tmr_channel_value) +{ + uint16_t channel; + + channel = tmr_channel; + + /* set tmr channel value */ + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->c1dt = tmr_channel_value; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->c2dt = tmr_channel_value; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->c3dt = tmr_channel_value; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->c4dt = tmr_channel_value; + break; + + default: + break; + } +} + +/** + * @brief get tmr channel value + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR10, + * TMR11, TMR12, TMR13, TMR14 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 + * - TMR_SELECT_CHANNEL_2 + * - TMR_SELECT_CHANNEL_3 + * - TMR_SELECT_CHANNEL_4 + * @retval tmr channel value + */ +uint32_t tmr_channel_value_get(tmr_type *tmr_x, tmr_channel_select_type tmr_channel) +{ + uint32_t cc_value_get = 0; + uint16_t channel; + + channel = tmr_channel; + + /* get tmr channel value */ + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + cc_value_get = tmr_x->c1dt; + break; + + case TMR_SELECT_CHANNEL_2: + cc_value_get = tmr_x->c2dt; + break; + + case TMR_SELECT_CHANNEL_3: + cc_value_get = tmr_x->c3dt; + break; + + case TMR_SELECT_CHANNEL_4: + cc_value_get = tmr_x->c4dt; + break; + + default: + break; + } + + return cc_value_get; +} +/** + * @brief enable tmr period buffer + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR6, TMR7, TMR8, + * TMR9, TMR10, TMR11, TMR12, TMR13, TMR14 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_period_buffer_enable(tmr_type *tmr_x, confirm_state new_state) +{ + /* tmr period buffer set */ + tmr_x->ctrl1_bit.prben = new_state; +} + +/** + * @brief enable tmr output channel buffer + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR10, + * TMR11, TMR12, TMR13, TMR14 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 + * - TMR_SELECT_CHANNEL_2 + * - TMR_SELECT_CHANNEL_3 + * - TMR_SELECT_CHANNEL_4 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_output_channel_buffer_enable(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, + confirm_state new_state) +{ + uint16_t channel; + + channel = tmr_channel; + + /* get tmr channel value */ + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cm1_output_bit.c1oben = new_state; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cm1_output_bit.c2oben = new_state; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cm2_output_bit.c3oben = new_state; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cm2_output_bit.c4oben = new_state; + break; + + default: + break; + } +} + +/** + * @brief set tmr output channel immediately + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR10, + * TMR11, TMR12, TMR13, TMR14 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 + * - TMR_SELECT_CHANNEL_2 + * - TMR_SELECT_CHANNEL_3 + * - TMR_SELECT_CHANNEL_4 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_output_channel_immediately_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, + confirm_state new_state) +{ + uint16_t channel; + + channel = tmr_channel; + + /* get tmr channel value */ + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cm1_output_bit.c1oien = new_state; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cm1_output_bit.c2oien = new_state; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cm2_output_bit.c3oien = new_state; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cm2_output_bit.c4oien = new_state; + break; + + default: + break; + } +} + +/** + * @brief set tmr output channel switch + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR10, + * TMR11, TMR12, TMR13, TMR14 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 + * - TMR_SELECT_CHANNEL_2 + * - TMR_SELECT_CHANNEL_3 + * - TMR_SELECT_CHANNEL_4 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_output_channel_switch_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, + confirm_state new_state) +{ + uint16_t channel; + + channel = tmr_channel; + + /* get tmr channel value */ + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cm1_output_bit.c1osen = new_state; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cm1_output_bit.c2osen = new_state; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cm2_output_bit.c3osen = new_state; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cm2_output_bit.c4osen = new_state; + break; + + default: + break; + } +} + +/** + * @brief enable or disable tmr one cycle mode + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR6, TMR7, TMR8, TMR9, TMR12 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_one_cycle_mode_enable(tmr_type *tmr_x, confirm_state new_state) +{ + /* tmr one cycle mode enable */ + tmr_x->ctrl1_bit.ocmen = new_state; +} + +/** + * @brief enable or disable tmr 32 bit function(plus mode) + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR2, TMR5 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_32_bit_function_enable (tmr_type *tmr_x, confirm_state new_state) +{ + /* tmr 32 bit function(plus mode) enable,only for TMR2/TMR5 */ + if((tmr_x == TMR2) || (tmr_x == TMR5)) + { + tmr_x->ctrl1_bit.pmen = new_state; + } +} + +/** + * @brief select tmr the overflow event sources + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR6, TMR7, TMR8, + * TMR9, TMR10, TMR11, TMR12, TMR13, TMR14 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_overflow_request_source_set(tmr_type *tmr_x, confirm_state new_state) +{ + tmr_x->ctrl1_bit.ovfs = new_state; +} + +/** + * @brief enable or disable tmr overflow event generation + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR6, TMR7, TMR8, + * TMR9, TMR10, TMR11, TMR12, TMR13, TMR14 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_overflow_event_disable(tmr_type *tmr_x, confirm_state new_state) +{ + tmr_x->ctrl1_bit.ovfen = new_state; +} + +/** + * @brief init tmr input channel + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR10, + * TMR11, TMR12, TMR13, TMR14 + * @param input_struct + * - to the structure of tmr_input_config_type + * @param divider_factor + * this parameter can be one of the following values: + * - TMR_CHANNEL_INPUT_DIV_1 + * - TMR_CHANNEL_INPUT_DIV_2 + * - TMR_CHANNEL_INPUT_DIV_4 + * - TMR_CHANNEL_INPUT_DIV_8 + * @retval none + */ +void tmr_input_channel_init(tmr_type *tmr_x, tmr_input_config_type *input_struct, + tmr_channel_input_divider_type divider_factor) +{ + uint16_t channel = 0; + + /* get channel selected */ + channel = input_struct->input_channel_select; + + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cctrl_bit.c1p = (uint32_t)input_struct->input_polarity_select; + tmr_x->cctrl_bit.c1cp = (input_struct->input_polarity_select & 0x2) >> 1; + tmr_x->cm1_input_bit.c1c = input_struct->input_mapped_select; + tmr_x->cm1_input_bit.c1df = input_struct->input_filter_value; + tmr_x->cm1_input_bit.c1idiv = divider_factor; + tmr_x->cctrl_bit.c1en = TRUE; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cctrl_bit.c2p = (uint32_t)input_struct->input_polarity_select; + tmr_x->cctrl_bit.c2cp = (input_struct->input_polarity_select & 0x2) >> 1; + tmr_x->cm1_input_bit.c2c = input_struct->input_mapped_select; + tmr_x->cm1_input_bit.c2df = input_struct->input_filter_value; + tmr_x->cm1_input_bit.c2idiv = divider_factor; + tmr_x->cctrl_bit.c2en = TRUE; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cctrl_bit.c3p = (uint32_t)input_struct->input_polarity_select; + tmr_x->cctrl_bit.c3cp = (input_struct->input_polarity_select & 0x2) >> 1; + tmr_x->cm2_input_bit.c3c = input_struct->input_mapped_select; + tmr_x->cm2_input_bit.c3df = input_struct->input_filter_value; + tmr_x->cm2_input_bit.c3idiv = divider_factor; + tmr_x->cctrl_bit.c3en = TRUE; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cctrl_bit.c4p = (uint32_t)input_struct->input_polarity_select; + tmr_x->cm2_input_bit.c4c = input_struct->input_mapped_select; + tmr_x->cm2_input_bit.c4df = input_struct->input_filter_value; + tmr_x->cm2_input_bit.c4idiv = divider_factor; + tmr_x->cctrl_bit.c4en = TRUE; + break; + + default: + break; + } +} + +/** + * @brief tmr channel enable + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR10, + * TMR11, TMR12, TMR13, TMR14 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 + * - TMR_SELECT_CHANNEL_1C + * - TMR_SELECT_CHANNEL_2 + * - TMR_SELECT_CHANNEL_2C + * - TMR_SELECT_CHANNEL_3 + * - TMR_SELECT_CHANNEL_3C + * - TMR_SELECT_CHANNEL_4 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_channel_enable(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, confirm_state new_state) +{ + uint16_t channel; + + channel = tmr_channel; + + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cctrl_bit.c1en = new_state; + break; + + case TMR_SELECT_CHANNEL_1C: + tmr_x->cctrl_bit.c1cen = new_state; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cctrl_bit.c2en = new_state; + break; + + case TMR_SELECT_CHANNEL_2C: + tmr_x->cctrl_bit.c2cen = new_state; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cctrl_bit.c3en = new_state; + break; + + case TMR_SELECT_CHANNEL_3C: + tmr_x->cctrl_bit.c3cen = new_state; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cctrl_bit.c4en = new_state; + break; + + default: + break; + } +} + +/** + * @brief set tmr input channel filter + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR10, + * TMR11, TMR12, TMR13, TMR14 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 + * - TMR_SELECT_CHANNEL_2 + * - TMR_SELECT_CHANNEL_3 + * - TMR_SELECT_CHANNEL_4 + * @param filter_value (0x0~0xf) + * @retval none + */ +void tmr_input_channel_filter_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, + uint16_t filter_value) +{ + uint16_t channel; + + channel = tmr_channel; + + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cm1_input_bit.c1df = filter_value; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cm1_input_bit.c2df = filter_value; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cm2_input_bit.c3df = filter_value; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cm2_input_bit.c4df = filter_value; + break; + + default: + break; + } +} + +/** + * @brief config tmr pwm input + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR10, + * TMR11, TMR12, TMR13, TMR14 + * @param input_struct + * - to the structure of tmr_input_config_type + * @param divider_factor + * this parameter can be one of the following values: + * - TMR_CHANNEL_INPUT_DIV_1 + * - TMR_CHANNEL_INPUT_DIV_2 + * - TMR_CHANNEL_INPUT_DIV_4 + * - TMR_CHANNEL_INPUT_DIV_8 + * @retval none + */ +void tmr_pwm_input_config(tmr_type *tmr_x, tmr_input_config_type *input_struct, + tmr_channel_input_divider_type divider_factor) +{ + uint16_t channel = 0; + + /* get channel selected */ + channel = input_struct->input_channel_select; + + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + if(input_struct->input_polarity_select == TMR_INPUT_RISING_EDGE) + { + /* set channel polarity */ + tmr_x->cctrl_bit.c1p = TMR_INPUT_RISING_EDGE; + tmr_x->cctrl_bit.c2p = TMR_INPUT_FALLING_EDGE; + } + else if(input_struct->input_polarity_select == TMR_INPUT_FALLING_EDGE) + { + /* set channel polarity */ + tmr_x->cctrl_bit.c1p = TMR_INPUT_FALLING_EDGE; + tmr_x->cctrl_bit.c2p = TMR_INPUT_RISING_EDGE; + } + + if(input_struct->input_mapped_select == TMR_CC_CHANNEL_MAPPED_DIRECT) + { + /* ic1 is mapped on ti1 */ + tmr_x->cm1_input_bit.c1c = TMR_CC_CHANNEL_MAPPED_DIRECT; + + /* ic1 is mapped on ti2 */ + tmr_x->cm1_input_bit.c2c = TMR_CC_CHANNEL_MAPPED_INDIRECT; + } + else if(input_struct->input_mapped_select == TMR_CC_CHANNEL_MAPPED_INDIRECT) + { + /* ic1 is mapped on ti1 */ + tmr_x->cm1_input_bit.c1c = TMR_CC_CHANNEL_MAPPED_INDIRECT; + + /* ic1 is mapped on ti2 */ + tmr_x->cm1_input_bit.c2c = TMR_CC_CHANNEL_MAPPED_DIRECT; + } + + /* set input ch1 and ch2 filter value*/ + tmr_x->cm1_input_bit.c1df = input_struct->input_filter_value; + tmr_x->cm1_input_bit.c2df = input_struct->input_filter_value; + + /*set input ch1 and ch2 divider value*/ + tmr_x->cm1_input_bit.c1idiv = divider_factor; + tmr_x->cm1_input_bit.c2idiv = divider_factor; + + tmr_x->cctrl_bit.c1en = TRUE; + tmr_x->cctrl_bit.c2en = TRUE; + break; + + case TMR_SELECT_CHANNEL_2: + if(input_struct->input_polarity_select == TMR_INPUT_RISING_EDGE) + { + /* set channel polarity */ + tmr_x->cctrl_bit.c2p = TMR_INPUT_RISING_EDGE; + tmr_x->cctrl_bit.c1p = TMR_INPUT_FALLING_EDGE; + } + else if(input_struct->input_polarity_select == TMR_INPUT_FALLING_EDGE) + { + /* set channel polarity */ + tmr_x->cctrl_bit.c2p = TMR_INPUT_FALLING_EDGE; + tmr_x->cctrl_bit.c1p = TMR_INPUT_RISING_EDGE; + } + + if(input_struct->input_mapped_select == TMR_CC_CHANNEL_MAPPED_DIRECT) + { + /* set mapped direct */ + tmr_x->cm1_input_bit.c2c = TMR_CC_CHANNEL_MAPPED_DIRECT; + tmr_x->cm1_input_bit.c1c = TMR_CC_CHANNEL_MAPPED_INDIRECT; + } + else if(input_struct->input_mapped_select == TMR_CC_CHANNEL_MAPPED_INDIRECT) + { + /* set mapped direct */ + tmr_x->cm1_input_bit.c2c = TMR_CC_CHANNEL_MAPPED_INDIRECT; + tmr_x->cm1_input_bit.c1c = TMR_CC_CHANNEL_MAPPED_DIRECT; + } + + /* set input ch1 and ch2 filter value*/ + tmr_x->cm1_input_bit.c1df = input_struct->input_filter_value; + tmr_x->cm1_input_bit.c2df = input_struct->input_filter_value; + + /*set input ch1 and ch2 divider value*/ + tmr_x->cm1_input_bit.c1idiv = divider_factor; + tmr_x->cm1_input_bit.c2idiv = divider_factor; + + tmr_x->cctrl_bit.c1en = TRUE; + tmr_x->cctrl_bit.c2en = TRUE; + break; + + default: + break; + } +} + +/** + * @brief select tmr channel1 input + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8 + * @param ti1_connect + * this parameter can be one of the following values: + * - TMR_CHANEL1_CONNECTED_C1IRAW + * - TMR_CHANEL1_2_3_CONNECTED_C1IRAW_XOR + * @retval none + */ +void tmr_channel1_input_select(tmr_type *tmr_x, tmr_channel1_input_connected_type ti1_connect) +{ + tmr_x->ctrl2_bit.c1insel = ti1_connect; +} + +/** + * @brief set tmr input channel divider + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR10, + * TMR11, TMR12, TMR13, TMR14 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 + * - TMR_SELECT_CHANNEL_2 + * - TMR_SELECT_CHANNEL_3 + * - TMR_SELECT_CHANNEL_4 + * @param divider_factor + * this parameter can be one of the following values: + * - TMR_CHANNEL_INPUT_DIV_1 + * - TMR_CHANNEL_INPUT_DIV_2 + * - TMR_CHANNEL_INPUT_DIV_4 + * - TMR_CHANNEL_INPUT_DIV_8 + * @retval none + */ +void tmr_input_channel_divider_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, + tmr_channel_input_divider_type divider_factor) +{ + uint16_t channel; + + channel = tmr_channel; + + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cm1_input_bit.c1idiv = divider_factor; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cm1_input_bit.c2idiv = divider_factor; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cm2_input_bit.c3idiv = divider_factor; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cm2_input_bit.c4idiv = divider_factor; + break; + + default: + break; + } +} + +/** + * @brief select tmr primary mode + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR6, TMR7, TMR8 + * @param primary_mode + * this parameter can be one of the following values: + * - TMR_PRIMARY_SEL_RESET + * - TMR_PRIMARY_SEL_ENABLE + * - TMR_PRIMARY_SEL_OVERFLOW + * - TMR_PRIMARY_SEL_COMPARE + * - TMR_PRIMARY_SEL_C1ORAW + * - TMR_PRIMARY_SEL_C2ORAW + * - TMR_PRIMARY_SEL_C3ORAW + * - TMR_PRIMARY_SEL_C4ORAW + * @retval none + */ +void tmr_primary_mode_select(tmr_type *tmr_x, tmr_primary_select_type primary_mode) +{ + tmr_x->ctrl2_bit.ptos = primary_mode; +} + +/** + * @brief select tmr subordinate mode + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR12 + * @param sub_mode + * this parameter can be one of the following values: + * - TMR_SUB_MODE_DIABLE + * - TMR_SUB_ENCODER_MODE_A + * - TMR_SUB_ENCODER_MODE_B + * - TMR_SUB_ENCODER_MODE_C + * - TMR_SUB_RESET_MODE + * - TMR_SUB_HANG_MODE + * - TMR_SUB_TRIGGER_MODE + * - TMR_SUB_EXTERNAL_CLOCK_MODE_A + * @retval none + */ +void tmr_sub_mode_select(tmr_type *tmr_x, tmr_sub_mode_select_type sub_mode) +{ + tmr_x->stctrl_bit.smsel = sub_mode; +} + +/** + * @brief select tmr channel dma + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR12 + * @param cc_dma_select + * this parameter can be one of the following values: + * - TMR_DMA_REQUEST_BY_CHANNEL + * - TMR_DMA_REQUEST_BY_OVERFLOW + * @retval none + */ +void tmr_channel_dma_select(tmr_type *tmr_x, tmr_dma_request_source_type cc_dma_select) +{ + tmr_x->ctrl2_bit.drs = cc_dma_select; +} + +/** + * @brief select tmr hall + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR8 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_hall_select(tmr_type *tmr_x, confirm_state new_state) +{ + tmr_x->ctrl2_bit.ccfs = new_state; +} + +/** + * @brief enable tmr channel buffer + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR8 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_channel_buffer_enable(tmr_type *tmr_x, confirm_state new_state) +{ + tmr_x->ctrl2_bit.cbctrl = new_state; +} + +/** + * @brief select tmr sub-trigger + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR12 + * @param trigger_select + * this parameter can be one of the following values: + * - TMR_SUB_INPUT_SEL_IS0 + * - TMR_SUB_INPUT_SEL_IS1 + * - TMR_SUB_INPUT_SEL_IS2 + * - TMR_SUB_INPUT_SEL_IS3 + * - TMR_SUB_INPUT_SEL_C1INC + * - TMR_SUB_INPUT_SEL_C1DF1 + * - TMR_SUB_INPUT_SEL_C2DF2 + * - TMR_SUB_INPUT_SEL_EXTIN + * @retval none + */ +void tmr_trigger_input_select(tmr_type *tmr_x, sub_tmr_input_sel_type trigger_select) +{ + tmr_x->stctrl_bit.stis = trigger_select; +} + +/** + * @brief set tmr subordinate synchronization mode + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR12 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_sub_sync_mode_set(tmr_type *tmr_x, confirm_state new_state) +{ + tmr_x->stctrl_bit.sts = new_state; +} + +/** + * @brief enable or disable tmr dma request + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR6, TMR7, TMR8, + * TMR9, TMR10, TMR11, TMR12, TMR13, TMR14 + * @param dma_request + * this parameter can be one of the following values: + * - TMR_OVERFLOW_DMA_REQUEST + * - TMR_C1_DMA_REQUEST + * - TMR_C2_DMA_REQUEST + * - TMR_C3_DMA_REQUEST + * - TMR_C4_DMA_REQUEST + * - TMR_HALL_DMA_REQUEST + * - TMR_TRIGGER_DMA_REQUEST + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_dma_request_enable(tmr_type *tmr_x, tmr_dma_request_type dma_request, confirm_state new_state) +{ + if(new_state == TRUE) + { + tmr_x->iden |= dma_request; + } + else if(new_state == FALSE) + { + tmr_x->iden &= ~dma_request; + } +} + +/** + * @brief enable or disable tmr interrupt + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR6, TMR7, TMR8, + * TMR9, TMR10, TMR11, TMR12, TMR13, TMR14 + * @param tmr_interrupt + * this parameter can be one of the following values: + * - TMR_OVF_INT + * - TMR_C1_INT + * - TMR_C2_INT + * - TMR_C3_INT + * - TMR_C4_INT + * - TMR_HALL_INT + * - TMR_TRIGGER_INT + * - TMR_BRK_INT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_interrupt_enable(tmr_type *tmr_x, uint32_t tmr_interrupt, confirm_state new_state) +{ + if(new_state == TRUE) + { + tmr_x->iden |= tmr_interrupt; + } + else if(new_state == FALSE) + { + tmr_x->iden &= ~tmr_interrupt; + } +} + +/** + * @brief get tmr flag + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR6, TMR7, TMR8, + * TMR9, TMR10, TMR11, TMR12, TMR13, TMR14 + * @param tmr_flag + * this parameter can be one of the following values: + * - TMR_OVF_FLAG + * - TMR_C1_FLAG + * - TMR_C2_FLAG + * - TMR_C3_FLAG + * - TMR_C4_FLAG + * - TMR_HALL_FLAG + * - TMR_TRIGGER_FLAG + * - TMR_BRK_FLAG + * - TMR_C1_RECAPTURE_FLAG + * - TMR_C2_RECAPTURE_FLAG + * - TMR_C3_RECAPTURE_FLAG + * - TMR_C4_RECAPTURE_FLAG + * @retval state of tmr flag + */ +flag_status tmr_flag_get(tmr_type *tmr_x, uint32_t tmr_flag) +{ + flag_status status = RESET; + + if((tmr_x->ists & tmr_flag) != RESET) + { + status = SET; + } + else + { + status = RESET; + } + + return status; +} + +/** + * @brief clear tmr flag + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR6, TMR7, TMR8, + * TMR9, TMR10, TMR11, TMR12, TMR13, TMR14 + * @param tmr_flag + * this parameter can be any combination of the following values: + * - TMR_OVF_FLAG + * - TMR_C1_FLAG + * - TMR_C2_FLAG + * - TMR_C3_FLAG + * - TMR_C4_FLAG + * - TMR_HALL_FLAG + * - TMR_TRIGGER_FLAG + * - TMR_BRK_FLAG + * - TMR_C1_RECAPTURE_FLAG + * - TMR_C2_RECAPTURE_FLAG + * - TMR_C3_RECAPTURE_FLAG + * - TMR_C4_RECAPTURE_FLAG + * @retval none + */ +void tmr_flag_clear(tmr_type *tmr_x, uint32_t tmr_flag) +{ + tmr_x->ists = ~tmr_flag; +} + +/** + * @brief generate tmr event + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR6, TMR7, TMR8, + * TMR9, TMR10, TMR11, TMR12, TMR13, TMR14 + * @param tmr_event + * this parameter can be one of the following values: + * - TMR_OVERFLOW_SWTRIG + * - TMR_C1_SWTRIG + * - TMR_C2_SWTRIG + * - TMR_C3_SWTRIG + * - TMR_C4_SWTRIG + * - TMR_HALL_SWTRIG + * - TMR_TRIGGER_SWTRIG + * - TMR_BRK_SWTRIG + * @retval none + */ +void tmr_event_sw_trigger(tmr_type *tmr_x, tmr_event_trigger_type tmr_event) +{ + tmr_x->swevt |= tmr_event; +} + +/** + * @brief tmr output enable(oen),this function is important for advtm output enable + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR8 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_output_enable(tmr_type *tmr_x, confirm_state new_state) +{ + tmr_x->brk_bit.oen = new_state; +} + +/** + * @brief set tmr select internal clock + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR12 + * @retval none + */ +void tmr_internal_clock_set(tmr_type *tmr_x) +{ + tmr_x->stctrl_bit.smsel = TMR_SUB_MODE_DIABLE; +} + +/** + * @brief set tmr output channel polarity + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR10, + * TMR11, TMR12, TMR13, TMR14 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 + * - TMR_SELECT_CHANNEL_2 + * - TMR_SELECT_CHANNEL_3 + * - TMR_SELECT_CHANNEL_4 + * - TMR_SELECT_CHANNEL_1C + * - TMR_SELECT_CHANNEL_2C + * - TMR_SELECT_CHANNEL_3C + * @param oc_polarity + * this parameter can be one of the following values: + * - TMR_POLARITY_ACTIVE_HIGH + * - TMR_POLARITY_ACTIVE_LOW + * @retval none + */ +void tmr_output_channel_polarity_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, + tmr_polarity_active_type oc_polarity) +{ + uint16_t channel; + + channel = tmr_channel; + + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cctrl_bit.c1p = (uint32_t)oc_polarity; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cctrl_bit.c2p = (uint32_t)oc_polarity; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cctrl_bit.c3p = (uint32_t)oc_polarity; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cctrl_bit.c4p = (uint32_t)oc_polarity; + break; + + case TMR_SELECT_CHANNEL_1C: + tmr_x->cctrl_bit.c1cp = (uint32_t)oc_polarity; + break; + + case TMR_SELECT_CHANNEL_2C: + tmr_x->cctrl_bit.c2cp = (uint32_t)oc_polarity; + break; + + case TMR_SELECT_CHANNEL_3C: + tmr_x->cctrl_bit.c3cp = (uint32_t)oc_polarity; + break; + + default: + break; + } +} + +/** + * @brief config tmr external clock + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8 + * @param es_divide + * this parameter can be one of the following values: + * - TMR_ES_FREQUENCY_DIV_1 + * - TMR_ES_FREQUENCY_DIV_2 + * - TMR_ES_FREQUENCY_DIV_4 + * - TMR_ES_FREQUENCY_DIV_8 + * @param es_polarity + * this parameter can be one of the following values: + * - TMR_ES_POLARITY_NON_INVERTED + * - TMR_ES_POLARITY_INVERTED + * @param es_filter (0x0~0xf) + * @retval none + */ +void tmr_external_clock_config(tmr_type *tmr_x, tmr_external_signal_divider_type es_divide, + tmr_external_signal_polarity_type es_polarity, uint16_t es_filter) +{ + tmr_x->stctrl_bit.esdiv = es_divide; + tmr_x->stctrl_bit.esp = es_polarity; + tmr_x->stctrl_bit.esf = es_filter; +} + +/** + * @brief config tmr external clock mode1 + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR12 + * @param es_divide + * this parameter can be one of the following values: + * - TMR_ES_FREQUENCY_DIV_1 + * - TMR_ES_FREQUENCY_DIV_2 + * - TMR_ES_FREQUENCY_DIV_4 + * - TMR_ES_FREQUENCY_DIV_8 + * @param es_polarity + * this parameter can be one of the following values: + * - TMR_ES_POLARITY_NON_INVERTED + * - TMR_ES_POLARITY_INVERTED + * @param es_filter (0x0~0xf) + * @retval none + */ +void tmr_external_clock_mode1_config(tmr_type *tmr_x, tmr_external_signal_divider_type es_divide, + tmr_external_signal_polarity_type es_polarity, uint16_t es_filter) +{ + tmr_external_clock_config(tmr_x, es_divide, es_polarity, es_filter); + tmr_x->stctrl_bit.smsel = TMR_SUB_EXTERNAL_CLOCK_MODE_A; + tmr_x->stctrl_bit.stis = TMR_SUB_INPUT_SEL_EXTIN; +} + +/** + * @brief config tmr external clock mode2 + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8 + * @param es_divide + * this parameter can be one of the following values: + * - TMR_ES_FREQUENCY_DIV_1 + * - TMR_ES_FREQUENCY_DIV_2 + * - TMR_ES_FREQUENCY_DIV_4 + * - TMR_ES_FREQUENCY_DIV_8 + * @param es_polarity + * this parameter can be one of the following values: + * - TMR_ES_POLARITY_NON_INVERTED + * - TMR_ES_POLARITY_INVERTED + * @param es_filter (0x0~0xf) + * @retval none + */ +void tmr_external_clock_mode2_config(tmr_type *tmr_x, tmr_external_signal_divider_type es_divide, + tmr_external_signal_polarity_type es_polarity, uint16_t es_filter) +{ + tmr_external_clock_config(tmr_x, es_divide, es_polarity, es_filter); + tmr_x->stctrl_bit.ecmben = TRUE; +} + +/** + * @brief config tmr encoder mode + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8 + * @param encoder_mode + * this parameter can be one of the following values: + * - TMR_ENCODER_MODE_A + * - TMR_ENCODER_MODE_B + * - TMR_ENCODER_MODE_C + * @param ic1_polarity + * this parameter can be one of the following values: + * - TMR_INPUT_RISING_EDGE + * - TMR_INPUT_FALLING_EDGE + * - TMR_INPUT_BOTH_EDGE + * @param ic2_polarity + * this parameter can be one of the following values: + * - TMR_INPUT_RISING_EDGE + * - TMR_INPUT_FALLING_EDGE + * - TMR_INPUT_BOTH_EDGE + * @retval none + */ +void tmr_encoder_mode_config(tmr_type *tmr_x, tmr_encoder_mode_type encoder_mode, tmr_input_polarity_type + ic1_polarity, tmr_input_polarity_type ic2_polarity) +{ + tmr_x->stctrl_bit.smsel = encoder_mode; + + /* set ic1 polarity */ + tmr_x->cctrl_bit.c1p = (ic1_polarity & 0x1); + tmr_x->cctrl_bit.c1cp = (ic1_polarity >> 1); + /* set ic1 as input channel */ + tmr_x->cm1_input_bit.c1c = TMR_CC_CHANNEL_MAPPED_DIRECT; + + /* set ic2 polarity */ + tmr_x->cctrl_bit.c2p = (ic2_polarity & 0x1); + tmr_x->cctrl_bit.c2cp = (ic2_polarity >> 1); + /* set ic2 as input channel */ + tmr_x->cm1_input_bit.c2c = TMR_CC_CHANNEL_MAPPED_DIRECT; +} + +/** + * @brief set tmr force output + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8, TMR9, TMR10, + * TMR11, TMR12, TMR13, TMR14 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 + * - TMR_SELECT_CHANNEL_2 + * - TMR_SELECT_CHANNEL_3 + * - TMR_SELECT_CHANNEL_4 + * @param force_output + * this parameter can be one of the following values: + * - TMR_FORCE_OUTPUT_HIGH + * - TMR_FORCE_OUTPUT_LOW + * @retval none + */ +void tmr_force_output_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, + tmr_force_output_type force_output) +{ + uint16_t channel; + + channel = tmr_channel; + + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cm1_output_bit.c1octrl = force_output; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cm1_output_bit.c2octrl = force_output; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cm2_output_bit.c3octrl = force_output; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cm2_output_bit.c4octrl = force_output; + break; + + default: + break; + } +} + +/** + * @brief config tmr dma control + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR4, TMR5, TMR8 + * @param dma_length + * this parameter can be one of the following values: + * - TMR_DMA_TRANSFER_1BYTE + * - TMR_DMA_TRANSFER_2BYTES + * - TMR_DMA_TRANSFER_3BYTES + * ... + * - TMR_DMA_TRANSFER_17BYTES + * - TMR_DMA_TRANSFER_18BYTES + * @param dma_base_address + * this parameter can be one of the following values: + * - TMR_CTRL1_ADDRESS + * - TMR_CTRL2_ADDRESS + * - TMR_STCTRL_ADDRESS + * - TMR_IDEN_ADDRESS + * - TMR_ISTS_ADDRESS + * - TMR_SWEVT_ADDRESS + * - TMR_CM1_ADDRESS + * - TMR_CM2_ADDRESS + * - TMR_CCTRL_ADDRESS + * - TMR_CVAL_ADDRESS + * - TMR_DIV_ADDRESS + * - TMR_PR_ADDRESS + * - TMR_RPR_ADDRESS + * - TMR_C1DT_ADDRESS + * - TMR_C2DT_ADDRESS + * - TMR_C3DT_ADDRESS + * - TMR_C4DT_ADDRESS + * - TMR_BRK_ADDRESS + * - TMR_DMACTRL_ADDRESS + * @retval none + */ +void tmr_dma_control_config(tmr_type *tmr_x, tmr_dma_transfer_length_type dma_length, + tmr_dma_address_type dma_base_address) +{ + tmr_x->dmactrl_bit.dtb = dma_length; + tmr_x->dmactrl_bit.addr = dma_base_address; +} + +/** + * @brief config tmr break mode and dead-time + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR8 + * @param brkdt_struct + * - to the structure of tmr_brkdt_config_type + * @retval none + */ +void tmr_brkdt_config(tmr_type *tmr_x, tmr_brkdt_config_type *brkdt_struct) +{ + tmr_x->brk_bit.brken = brkdt_struct->brk_enable; + tmr_x->brk_bit.dtc = brkdt_struct->deadtime; + tmr_x->brk_bit.fcsodis = brkdt_struct->fcsodis_state; + tmr_x->brk_bit.fcsoen = brkdt_struct->fcsoen_state; + tmr_x->brk_bit.brkv = brkdt_struct->brk_polarity; + tmr_x->brk_bit.aoen = brkdt_struct->auto_output_enable; + tmr_x->brk_bit.wpc = brkdt_struct->wp_level; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_usart.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_usart.c new file mode 100644 index 0000000..2fde5c6 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_usart.c @@ -0,0 +1,624 @@ +/** + ************************************************************************** + * @file at32f403a_407_usart.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the usart firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* includes ------------------------------------------------------------------*/ +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup USART + * @brief USART driver modules + * @{ + */ + +#ifdef USART_MODULE_ENABLED + +/** @defgroup USART_private_functions + * @{ + */ + +/** + * @brief deinitialize the usart peripheral registers to their default reset values. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4, UART5, USART6, UART7,or UART8. + * @retval none + */ +void usart_reset(usart_type* usart_x) +{ + if(usart_x == USART1) + { + crm_periph_reset(CRM_USART1_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_USART1_PERIPH_RESET, FALSE); + } + else if(usart_x == USART2) + { + crm_periph_reset(CRM_USART2_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_USART2_PERIPH_RESET, FALSE); + } + else if(usart_x == USART3) + { + crm_periph_reset(CRM_USART3_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_USART3_PERIPH_RESET, FALSE); + } + else if(usart_x == UART4) + { + crm_periph_reset(CRM_UART4_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_UART4_PERIPH_RESET, FALSE); + } + else if(usart_x == UART5) + { + crm_periph_reset(CRM_UART5_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_UART5_PERIPH_RESET, FALSE); + } + else if(usart_x == USART6) + { + crm_periph_reset(CRM_USART6_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_USART6_PERIPH_RESET, FALSE); + } + else if(usart_x == UART7) + { + crm_periph_reset(CRM_UART7_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_UART7_PERIPH_RESET, FALSE); + } + else if(usart_x == UART8) + { + crm_periph_reset(CRM_UART8_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_UART8_PERIPH_RESET, FALSE); + } +} + +/** + * @brief initialize the usart peripheral according to the specified parameters. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4 ,UART5, USART6, UART7 or UART8. + * @param baud_rate: configure the usart communication baud rate. + * @param data_bit: data bits transmitted or received in a frame + * this parameter can be one of the following values: + * - USART_DATA_8BITS + * - USART_DATA_9BITS. + * @param stop_bit: stop bits transmitted + * this parameter can be one of the following values: + * - USART_STOP_1_BIT + * - USART_STOP_0_5_BIT. + * - USART_STOP_2_BIT + * - USART_STOP_1_5_BIT. + * @retval none + */ +void usart_init(usart_type* usart_x, uint32_t baud_rate, usart_data_bit_num_type data_bit, usart_stop_bit_num_type stop_bit) +{ + crm_clocks_freq_type clocks_freq; + uint32_t apb_clock, temp_val; + crm_clocks_freq_get(&clocks_freq); + if((usart_x == USART1) || (usart_x == USART6) || (usart_x == UART7) || (usart_x == UART8)) + { + apb_clock = clocks_freq.apb2_freq; + } + else + { + apb_clock = clocks_freq.apb1_freq; + } + temp_val = (apb_clock * 10 / baud_rate); + if((temp_val % 10) < 5) + { + temp_val = (temp_val / 10); + } + else + { + temp_val = (temp_val / 10) + 1; + } + usart_x->baudr_bit.div = temp_val; + usart_x->ctrl1_bit.dbn = data_bit; + usart_x->ctrl2_bit.stopbn = stop_bit; +} + +/** + * @brief usart parity selection config. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4 ,UART5, USART6, UART7 or UART8. + * @param parity: select the none, odd or even parity. + * this parameter can be one of the following values: + * - USART_PARITY_NONE + * - USART_PARITY_EVEN. + * - USART_PARITY_ODD + * @retval none + */ +void usart_parity_selection_config(usart_type* usart_x, usart_parity_selection_type parity) +{ + if(parity == USART_PARITY_NONE) + { + usart_x->ctrl1_bit.psel = FALSE; + usart_x->ctrl1_bit.pen = FALSE; + } + else if(parity == USART_PARITY_EVEN) + { + usart_x->ctrl1_bit.psel = FALSE; + usart_x->ctrl1_bit.pen = TRUE; + } + else if(parity == USART_PARITY_ODD) + { + usart_x->ctrl1_bit.psel = TRUE; + usart_x->ctrl1_bit.pen = TRUE; + } +} + +/** + * @brief enable or disable the specified usart peripheral. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8. + * @param new_state: new state of the usart peripheral. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl1_bit.uen = new_state; +} + +/** + * @brief usart transmitter enable. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4 ,UART5, USART6, UART7 or UART8. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void usart_transmitter_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl1_bit.ten = new_state; +} + +/** + * @brief usart receiver enable. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4 ,UART5, USART6, UART7 or UART8. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void usart_receiver_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl1_bit.ren = new_state; +} + +/** + * @brief usart clock config. + * @note clock config are not available for UART4, UART5, UART7 and UART8. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART6. + * @param clk_pol: polarity of the clock output on the ck pin. + * this parameter can be one of the following values: + * - USART_CLOCK_POLARITY_LOW + * - USART_CLOCK_POLARITY_HIGH + * @param clk_pha: phase of the clock output on the ck pin. + * this parameter can be one of the following values: + * - USART_CLOCK_PHASE_1EDGE + * - USART_CLOCK_PHASE_2EDGE + * @param clk_lb: whether the clock pulse of the last data bit transmitted (MSB) is outputted on the ck pin. + * this parameter can be one of the following values: + * - USART_CLOCK_LAST_BIT_NONE + * - USART_CLOCK_LAST_BIT_OUTPUT + * @retval none + */ +void usart_clock_config(usart_type* usart_x, usart_clock_polarity_type clk_pol, usart_clock_phase_type clk_pha, usart_lbcp_type clk_lb) +{ + usart_x->ctrl2_bit.clkpol = clk_pol; + usart_x->ctrl2_bit.clkpha = clk_pha; + usart_x->ctrl2_bit.lbcp = clk_lb; +} + +/** + * @brief usart enable the ck pin. + * @note clock enable are not available for UART4, UART5, UART7 and UART8. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART6. + * @param new_state: TRUE or FALSE + * @retval none + */ +void usart_clock_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl2_bit.clken = new_state; +} + +/** + * @brief enable or disable the specified usart interrupts. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8. + * @param usart_int: specifies the USART interrupt sources to be enabled or disabled. + * this parameter can be one of the following values: + * - USART_IDLE_INT: idle interrupt + * - USART_RDBF_INT: rdbf interrupt + * - USART_TDC_INT: tdc interrupt + * - USART_TDBE_INT: tdbe interrupt + * - USART_PERR_INT: perr interrupt + * - USART_BF_INT: break frame interrupt + * - USART_ERR_INT: err interrupt + * - USART_CTSCF_INT: ctscf interrupt + * @param new_state: new state of the specified usart interrupts. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_interrupt_enable(usart_type* usart_x, uint32_t usart_int, confirm_state new_state) +{ + if(new_state == TRUE) + PERIPH_REG((uint32_t)usart_x, usart_int) |= PERIPH_REG_BIT(usart_int); + else + PERIPH_REG((uint32_t)usart_x, usart_int) &= ~PERIPH_REG_BIT(usart_int); +} + +/** + * @brief enable or disable the usart's dma transmitter interface. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8. + * @param new_state: new state of the dma request sources. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_dma_transmitter_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl3_bit.dmaten = new_state; +} + +/** + * @brief enable or disable the usart's dma receiver interface. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8. + * @param new_state: new state of the dma request sources. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_dma_receiver_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl3_bit.dmaren = new_state; +} + +/** + * @brief set the wakeup id of the usart. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8. + * @param usart_id: the matching id(0x0~0xF). + * @retval none + */ +void usart_wakeup_id_set(usart_type* usart_x, uint8_t usart_id) +{ + usart_x->ctrl2_bit.id = usart_id; +} + +/** + * @brief select the usart wakeup method in multi-processor communication. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8. + * @param wakeup_mode: determines the way to wake up usart method. + * this parameter can be one of the following values: + * - USART_WAKEUP_BY_IDLE_FRAME + * - USART_WAKEUP_BY_MATCHING_ID + * @retval none + */ +void usart_wakeup_mode_set(usart_type* usart_x, usart_wakeup_mode_type wakeup_mode) +{ + usart_x->ctrl1_bit.wum = wakeup_mode; +} + +/** + * @brief config the usart in mute mode in multi-processor communication. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8. + * @param new_state: new state of the usart mute mode. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_receiver_mute_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl1_bit.rm = new_state; +} + +/** + * @brief set the usart break frame bit num. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8. + * @param break_bit: specifies the break bit num. + * this parameter can be one of the following values: + * - USART_BREAK_10BITS + * - USART_BREAK_11BITS + * @retval none + */ +void usart_break_bit_num_set(usart_type* usart_x, usart_break_bit_num_type break_bit) +{ + usart_x->ctrl2_bit.bfbn = break_bit; +} + +/** + * @brief enable or disable the usart lin mode. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8. + * @param new_state: new state of the usart lin mode. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_lin_mode_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl2_bit.linen = new_state; +} + +/** + * @brief transmit single data through the usart peripheral. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8. + * @param data: the data to transmit. + * @retval none + */ +void usart_data_transmit(usart_type* usart_x, uint16_t data) +{ + usart_x->dt = (data & 0x01FF); +} + +/** + * @brief return the most recent received data by the usart peripheral. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8. + * @retval the received data. + */ +uint16_t usart_data_receive(usart_type* usart_x) +{ + return (uint16_t)(usart_x->dt); +} + +/** + * @brief transmit break characters. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8. + * @retval none + */ +void usart_break_send(usart_type* usart_x) +{ + usart_x->ctrl1_bit.sbf = TRUE; +} + +/** + * @brief config the specified usart smartcard guard time. + * @note The guard time bits are not available for UART4, UART5, UART7 or UART8. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART6. + * @param guard_time_val: specifies the guard time (0x00~0xFF). + * @retval none + */ +void usart_smartcard_guard_time_set(usart_type* usart_x, uint8_t guard_time_val) +{ + usart_x->gdiv_bit.scgt = guard_time_val; +} + +/** + * @brief config the irda/smartcard division. + * @note the division are not available for UART4, UART5, UART7 or UART8. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART6. + * @param div_val: specifies the division. + * @retval none + */ +void usart_irda_smartcard_division_set(usart_type* usart_x, uint8_t div_val) +{ + usart_x->gdiv_bit.isdiv = div_val; +} + +/** + * @brief enable or disable the usart smart card mode. + * @note the smart card mode are not available for UART4, UART5, UART7 or UART8. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART6. + * @param new_state: new state of the smart card mode. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_smartcard_mode_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl3_bit.scmen = new_state; +} + +/** + * @brief enable or disable nack transmission in smartcard mode. + * @note the smart card nack are not available for UART4, UART5, UART7 or UART8. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART6. + * @param new_state: new state of the nack transmission. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_smartcard_nack_set(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl3_bit.scnacken = new_state; +} + +/** + * @brief enable or disable the usart single line bidirectional half-duplex communication. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8. + * @param new_state: new state of the single line half-duplex select. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_single_line_halfduplex_select(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl3_bit.slben = new_state; +} + +/** + * @brief enable or disable the usart's irda interface. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8. + * @param new_state: new state of the irda mode. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_irda_mode_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl3_bit.irdaen = new_state; +} + +/** + * @brief configure the usart's irda low power. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8. + * @param new_state: new state of the irda mode. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_irda_low_power_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl3_bit.irdalp = new_state; +} + +/** + * @brief configure the usart's hardware flow control. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 + * @param flow_state: specifies the hardware flow control. + * this parameter can be one of the following values: + * - USART_HARDWARE_FLOW_NONE + * - USART_HARDWARE_FLOW_RTS, + * - USART_HARDWARE_FLOW_CTS, + * - USART_HARDWARE_FLOW_RTS_CTS + * @retval none + */ +void usart_hardware_flow_control_set(usart_type* usart_x,usart_hardware_flow_control_type flow_state) +{ + if(flow_state == USART_HARDWARE_FLOW_NONE) + { + usart_x->ctrl3_bit.rtsen = FALSE; + usart_x->ctrl3_bit.ctsen = FALSE; + } + else if(flow_state == USART_HARDWARE_FLOW_RTS) + { + usart_x->ctrl3_bit.rtsen = TRUE; + usart_x->ctrl3_bit.ctsen = FALSE; + } + else if(flow_state == USART_HARDWARE_FLOW_CTS) + { + usart_x->ctrl3_bit.rtsen = FALSE; + usart_x->ctrl3_bit.ctsen = TRUE; + } + else if(flow_state == USART_HARDWARE_FLOW_RTS_CTS) + { + usart_x->ctrl3_bit.rtsen = TRUE; + usart_x->ctrl3_bit.ctsen = TRUE; + } +} + +/** + * @brief check whether the specified usart flag is set or not. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8. + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - USART_CTSCF_FLAG: cts change flag (not available for UART4,UART5,USART6,UART7 and UART8) + * - USART_BFF_FLAG: break frame flag + * - USART_TDBE_FLAG: transmit data buffer empty flag + * - USART_TDC_FLAG: transmit data complete flag + * - USART_RDBF_FLAG: receive data buffer full flag + * - USART_IDLEF_FLAG: idle flag + * - USART_ROERR_FLAG: receiver overflow error flag + * - USART_NERR_FLAG: noise error flag + * - USART_FERR_FLAG: framing error flag + * - USART_PERR_FLAG: parity error flag + * @retval the new state of usart_flag (SET or RESET). + */ +flag_status usart_flag_get(usart_type* usart_x, uint32_t flag) +{ + if(usart_x->sts & flag) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief clear the usart's pending flags. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8. + * @param flag: specifies the flag to clear. + * this parameter can be any combination of the following values: + * - USART_CTSCF_FLAG: (not available for UART4,UART5,USART6,UART7 and UART8). + * - USART_BFF_FLAG: + * - USART_TDC_FLAG: + * - USART_RDBF_FLAG: + * @note + * - USART_PERR_FLAG, USART_FERR_FLAG, USART_NERR_FLAG, USART_ROERR_FLAG and USART_IDLEF_FLAG are cleared by software + * sequence: a read operation to usart sts register (usart_flag_get()) + * followed by a read operation to usart dt register (usart_data_receive()). + * - USART_RDBF_FLAG can be also cleared by a read to the usart dt register(usart_data_receive()). + * - USART_TDC_FLAG can be also cleared by software sequence: a read operation to usart sts register (usart_flag_get()) + * followed by a write operation to usart dt register (usart_data_transmit()). + * - USART_TDBE_FLAG is cleared only by a write to the usart dt register(usart_data_transmit()). + * @retval none + */ +void usart_flag_clear(usart_type* usart_x, uint32_t flag) +{ + usart_x->sts = ~flag; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_usb.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_usb.c new file mode 100644 index 0000000..a177da5 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_usb.c @@ -0,0 +1,561 @@ +/** + ************************************************************************** + * @file at32f403a_407_usb.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains the functions for the usb firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup USB + * @brief USB driver modules + * @{ + */ + +#include "at32f403a_407_conf.h" + + +#ifdef USB_MODULE_ENABLED + +/** @defgroup USB_private_functions + * @{ + */ + +/** + * @brief usb packet buffer start address + */ +#define USB_ENDP_DESC_TABLE_OFFSET 0x40 +uint32_t g_usb_packet_address = USB_PACKET_BUFFER_ADDRESS; +static uint16_t g_usb_offset_addr = USB_ENDP_DESC_TABLE_OFFSET; + +/** + * @brief initialize usb peripheral controller register + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @retval none + */ +void usb_dev_init(usbd_type *usbx) +{ + /* clear usb core reset */ + usbx->ctrl_bit.csrst = 0; + + /* clear usb interrupt status */ + usbx->intsts = 0; + + /* set usb packet buffer descirption table address */ + usbx->buftbl = USB_BUFFER_TABLE_ADDRESS; + + /* enable usb core and set device address to 0 */ + usbx->devaddr = 0x80; + + usb_interrupt_enable(usbx, USB_SOF_INT | USB_RST_INT | USB_SP_INT | USB_WK_INT | USB_TC_INT, TRUE); +} + +/** + * @brief connect usb device + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @retval none + */ +void usb_connect(usbd_type *usbx) +{ + /* enable usb phy */ + usbx->ctrl_bit.disusb = 0; + + /* Dp 1.5k pull-up enable */ + usbx->cfg_bit.puo = 0; +} + +/** + * @brief disconnect usb device + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @retval none + */ +void usb_disconnect(usbd_type *usbx) +{ + /* disable usb phy */ + usbx->ctrl_bit.disusb = TRUE; + + /* D+ 1.5k pull-up disable */ + usbx->cfg_bit.puo = TRUE; +} + + +/** + * @brief mapping usb packet buffer area + * two mapping intervals are available for packet buffer area, + * and are select by the usbbufs in the crm misc1 register. + * when usbbufs is 0,sram size is 512 bytes, packet buffer start + * address is 0x40006000.when usbbufs is 1, sram size is fixed to + * 768~1280 bytes, and the packet buffer start address is fixed to + * 0x40007800,packet buffer size decided by whether can1 and can2 are + * enabled;when both can1 and can2 are disabled, usb packet buffer can be set to the + * maximum of 1280 bytes; when either can1 or can2 is enabled, usb packet buffer can be set to the + * maximum of 1024 bytes; when both CAN1 and CAN2 are enabled, usb packet buffer can be set to the + * maximum of 768 bytes. + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @retval none + */ +void usb_usbbufs_enable(usbd_type *usbx, confirm_state state) +{ + if(state == TRUE) + { + /* enable usbbufs */ + g_usb_packet_address = USB_PACKET_BUFFER_ADDRESS_EX; + CRM->misc1_bit.usbbufs = TRUE; + } + else + { + /* disable usbbufs */ + g_usb_packet_address = USB_PACKET_BUFFER_ADDRESS; + CRM->misc1_bit.usbbufs = FALSE; + } +} + +/** + * @brief open usb endpoint + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @param ept_info: endpoint information structure + * @retval none + */ +void usb_ept_open(usbd_type *usbx, usb_ept_info *ept_info) +{ + uint16_t type = 0; + + /* set endpoint address */ + USB_SET_EPT_ADDRESS(ept_info->eptn, ept_info->ept_address); + + /* select endpoint transfer type */ + if(ept_info->trans_type == EPT_CONTROL_TYPE) + { + type = USB_EPT_CONTROL; + } + else if(ept_info->trans_type == EPT_BULK_TYPE) + { + type = USB_EPT_BULK; + } + else if(ept_info->trans_type == EPT_INT_TYPE) + { + type = USB_EPT_INT; + } + else if(ept_info->trans_type == EPT_ISO_TYPE) + { + type = USB_EPT_ISO; + ept_info->is_double_buffer = TRUE; + } + + /* configure endpoint transfer type (control, bulk, interrupt, isochronous) */ + USB_SET_TRANS_TYPE(ept_info->eptn, type); + + /* endpoint is in transfer */ + if(ept_info->inout == DATA_TRANS_IN) + { + if(ept_info->is_double_buffer == 0) + { + /* set in endpoint tx offset address */ + USB_SET_TX_ADDRESS(ept_info->eptn, ept_info->tx_addr); + + /* clear in endpoint data toggle */ + USB_CLEAR_TXDTS(ept_info->eptn); + + /* set endpoint transmission status: nak */ + USB_SET_TXSTS(ept_info->eptn, USB_TX_NAK); + } + else + { + /* set double buffer endpoint*/ + USB_SET_EPT_DOUBLE_BUFFER(ept_info->eptn); + + /* set in endpoint offset address0 and address1 */ + USB_SET_DOUBLE_BUFF0_ADDRESS(ept_info->eptn, ept_info->tx_addr); + USB_SET_DOUBLE_BUFF1_ADDRESS(ept_info->eptn, ept_info->rx_addr); + + /* clear in and out data toggle */ + USB_CLEAR_TXDTS(ept_info->eptn); + USB_CLEAR_RXDTS(ept_info->eptn); + + /* toggle rx data toggle flag */ + USB_TOGGLE_RXDTS(ept_info->eptn); + + /* set endpoint reception status: disable */ + USB_SET_RXSTS(ept_info->eptn, USB_RX_DISABLE); + + /* set endpoint transmision status: nak */ + USB_SET_TXSTS(ept_info->eptn, USB_TX_NAK); + } + } + else + { + if(ept_info->is_double_buffer == 0) + { + /* set out endpoint rx offset address */ + USB_SET_RX_ADDRESS(ept_info->eptn, ept_info->rx_addr); + + /* clear out endpoint data toggle */ + USB_CLEAR_RXDTS(ept_info->eptn); + + /* set out endpoint max reception buffer size */ + USB_SET_RXLEN(ept_info->eptn, ept_info->maxpacket); + + /* set endpoint reception status: valid */ + USB_SET_RXSTS(ept_info->eptn, USB_RX_VALID); + } + else + { + /* set double buffer endpoint */ + USB_SET_EPT_DOUBLE_BUFFER(ept_info->eptn); + + /* set out endpoint offset address0 and address1 */ + USB_SET_DOUBLE_BUFF0_ADDRESS(ept_info->eptn, ept_info->tx_addr); + USB_SET_DOUBLE_BUFF1_ADDRESS(ept_info->eptn, ept_info->rx_addr); + + /* set out endpoint max reception buffer size */ + USB_SET_EPT_DOUBLE_BUF0_LEN(ept_info->eptn, ept_info->maxpacket, DATA_TRANS_OUT); + USB_SET_EPT_DOUBLE_BUF1_LEN(ept_info->eptn, ept_info->maxpacket, DATA_TRANS_OUT); + + /* clear in and out data toggle */ + USB_CLEAR_TXDTS(ept_info->eptn); + USB_CLEAR_RXDTS(ept_info->eptn); + + /* toggle tx data toggle flag */ + USB_TOGGLE_TXDTS(ept_info->eptn); + + /* set endpoint reception status: valid */ + USB_SET_RXSTS(ept_info->eptn, USB_RX_VALID); + + /* set endpoint transmision status: disable */ + USB_SET_TXSTS(ept_info->eptn, USB_TX_DISABLE); + } + } +} + + +/** + * @brief close usb endpoint + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @param ept_info: endpoint information structure + * @retval none + */ +void usb_ept_close(usbd_type *usbx, usb_ept_info *ept_info) +{ + if(ept_info->is_double_buffer == 0) + { + if(ept_info->inout == DATA_TRANS_IN) + { + /*clear tx data toggle */ + USB_CLEAR_TXDTS(ept_info->eptn); + + /* set tx status: disable */ + USB_SET_TXSTS(ept_info->eptn, USB_TX_DISABLE); + } + else + { + /*clear rx data toggle */ + USB_CLEAR_RXDTS(ept_info->eptn); + + /* set rx status: disable */ + USB_SET_RXSTS(ept_info->eptn, USB_RX_DISABLE); + + } + } + else + { + /* double buffer */ + + /*clear rx and tx data toggle */ + USB_CLEAR_TXDTS(ept_info->eptn); + USB_CLEAR_RXDTS(ept_info->eptn); + + if(ept_info->inout == DATA_TRANS_IN) + { + /* toggle tx */ + USB_TOGGLE_TXDTS(ept_info->eptn); + + /* set tx and rx status: disable */ + USB_SET_TXSTS(ept_info->eptn, USB_TX_DISABLE); + USB_SET_RXSTS(ept_info->eptn, USB_RX_DISABLE); + } + else + { + /* toggle rx */ + USB_TOGGLE_RXDTS(ept_info->eptn); + + /* set tx and rx status: disable */ + USB_SET_TXSTS(ept_info->eptn, USB_TX_DISABLE); + USB_SET_RXSTS(ept_info->eptn, USB_RX_DISABLE); + } + } +} + +/** + * @brief write data from user memory to usb buffer + * @param pusr_buf: point to user buffer + * @param offset_addr: endpoint tx offset address + * @param nbytes: number of bytes data write to usb buffer + * @retval none + */ +void usb_write_packet(uint8_t *pusr_buf, uint16_t offset_addr, uint16_t nbytes) +{ + /* endpoint tx buffer address */ + __IO uint16_t *d_addr = (__IO uint16_t *)(offset_addr * 2 + g_usb_packet_address); + + uint32_t nhbytes = (nbytes + 1) >> 1; + uint32_t n_index; + uint16_t *pbuf = (uint16_t *)pusr_buf; + for(n_index = 0; n_index < nhbytes; n_index ++) + { +#if defined (__ICCARM__) && (__VER__ < 7000000) + *d_addr++ = *(__packed uint16_t *)pbuf; +#else + *d_addr++ = __UNALIGNED_UINT16_READ(pbuf); +#endif + d_addr ++; + pbuf ++; + } +} + +/** + * @brief read data from usb buffer to user buffer + * @param pusr_buf: point to user buffer + * @param offset_addr: endpoint rx offset address + * @param nbytes: number of bytes data write to usb buffer + * @retval none + */ +void usb_read_packet(uint8_t *pusr_buf, uint16_t offset_addr, uint16_t nbytes) +{ + __IO uint16_t *s_addr = (__IO uint16_t *)(offset_addr * 2 + g_usb_packet_address); + uint32_t nhbytes = (nbytes + 1) >> 1; + uint32_t n_index; + uint16_t *pbuf = (uint16_t *)pusr_buf; + for(n_index = 0; n_index < nhbytes; n_index ++) + { +#if defined (__ICCARM__) && (__VER__ < 7000000) + *(__packed uint16_t *)pbuf = *(__IO uint16_t *)s_addr ++; +#else + __UNALIGNED_UINT16_WRITE(pbuf, *(__IO uint16_t *)s_addr ++); +#endif + s_addr ++; + pbuf ++; + } +} + + +/** + * @brief usb interrupt enable + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @param interrupt: + * this parameter can be any combination of the following values: + * - USB_LSOF_INT + * - USB_SOF_INT + * - USB_RST_INT + * - USB_SP_INT + * - USB_WK_INT + * - USB_BE_INT + * - USB_UCFOR_INT + * - USB_TC_INT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void usb_interrupt_enable(usbd_type *usbx, uint16_t interrupt, confirm_state new_state) +{ + if(new_state == TRUE) + { + usbx->ctrl |= interrupt; + } + else + { + usbx->ctrl &= ~interrupt; + } +} + +/** + * @brief set the host assignment address + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @param address: host assignment address + * @retval none + */ +void usb_set_address(usbd_type *usbx, uint8_t address) +{ + usbx->devaddr_bit.addr = address; + usbx->devaddr_bit.cen = TRUE; +} + +/** + * @brief set endpoint tx or rx status to stall + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @param ept_info: endpoint information structure + * @retval none + */ +void usb_ept_stall(usbd_type *usbx, usb_ept_info *ept_info) +{ + if(ept_info->inout == DATA_TRANS_IN) + { + USB_SET_TXSTS(ept_info->eptn, USB_TX_STALL) + } + else + { + USB_SET_RXSTS(ept_info->eptn, USB_RX_STALL) + } +} + +/** + * @brief usb device enter suspend mode + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @retval none + */ +void usb_enter_suspend(usbd_type *usbx) +{ + usbx->ctrl_bit.ssp = TRUE; + usbx->ctrl_bit.lpm = TRUE; +} + +/** + * @brief usb device exit suspend mode + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @retval none + */ +void usb_exit_suspend(usbd_type *usbx) +{ + usbx->ctrl_bit.ssp = FALSE; + usbx->ctrl_bit.lpm = FALSE; +} + +/** + * @brief usb remote wakeup set + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @retval none + */ +void usb_remote_wkup_set(usbd_type *usbx) +{ + usbx->ctrl_bit.gresume = TRUE; +} + +/** + * @brief usb remote wakeup clear + * @param usbx: to select the usb peripheral. + * parameter as following values: USB + * @retval none + */ +void usb_remote_wkup_clear(usbd_type *usbx) +{ + usbx->ctrl_bit.gresume = FALSE; +} + +/** + * @brief usb auto malloc endpoint buffer + * @param mapacket: endpoint support max packet size + * @retval none + */ +uint16_t usb_buffer_malloc(uint16_t maxpacket) +{ + uint16_t offset = g_usb_offset_addr; + g_usb_offset_addr += maxpacket; + return offset; +} + +/** + * @brief free usb endpoint buffer + * @param none + * @retval none + */ +void usb_buffer_free(void) +{ + g_usb_offset_addr = USB_ENDP_DESC_TABLE_OFFSET; +} + +/** + * @brief get flag of usb. + * @param usbx: select the usb peripheral + * @param flag: select the usb flag + * this parameter can be one of the following values: + * - USB_INOUT_FLAG + * - USB_LSOF_FLAG + * - USB_SOF_FLAG + * - USB_RST_FLAG + * - USB_SP_FLAG + * - USB_WK_FLAG + * - USB_BE_FLAG + * - USB_UCFOR_FLAG + * - USB_TC_FLAG + * @retval none + */ +flag_status usb_flag_get(usbd_type *usbx, uint16_t flag) +{ + flag_status status = RESET; + + if((usbx->intsts & flag) == RESET) + { + status = RESET; + } + else + { + status = SET; + } + return status; +} + +/** + * @brief clear flag of usb. + * @param usbx: select the usb peripheral + * @param flag: select the usb flag + * this parameter can be one of the following values: + * - USB_INOUT_FLAG + * - USB_LSOF_FLAG + * - USB_SOF_FLAG + * - USB_RST_FLAG + * - USB_SP_FLAG + * - USB_WK_FLAG + * - USB_BE_FLAG + * - USB_UCFOR_FLAG + * - USB_TC_FLAG + * @retval none + */ +void usb_flag_clear(usbd_type *usbx, uint16_t flag) +{ + usbx->intsts = ~flag; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_wdt.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_wdt.c new file mode 100644 index 0000000..782123f --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_wdt.c @@ -0,0 +1,145 @@ +/** + ************************************************************************** + * @file at32f403a_407_wdt.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the wdt firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup WDT + * @brief WDT driver modules + * @{ + */ + +#ifdef WDT_MODULE_ENABLED + +/** @defgroup WDT_private_functions + * @{ + */ + +/** + * @brief wdt enable ,the reload value will be sent to the counter + * @param none + * @retval none + */ +void wdt_enable(void) +{ + WDT->cmd = WDT_CMD_ENABLE; +} + +/** + * @brief reload wdt counter + * @param none + * @retval none + */ +void wdt_counter_reload(void) +{ + WDT->cmd = WDT_CMD_RELOAD; +} + +/** + * @brief set wdt counter reload value + * @param reload_value (0x0000~0x0FFF) + * @retval none + */ +void wdt_reload_value_set(uint16_t reload_value) +{ + WDT->rld = reload_value; +} + +/** + * @brief set wdt division divider + * @param division + * this parameter can be one of the following values: + * - WDT_CLK_DIV_4 + * - WDT_CLK_DIV_8 + * - WDT_CLK_DIV_16 + * - WDT_CLK_DIV_32 + * - WDT_CLK_DIV_64 + * - WDT_CLK_DIV_128 + * - WDT_CLK_DIV_256 + * @retval none + */ +void wdt_divider_set(wdt_division_type division) +{ + WDT->div_bit.div = division; +} + +/** + * @brief enable or disable wdt cmd register write + * @param new_state (TRUE or FALSE) + * @retval none + */ +void wdt_register_write_enable( confirm_state new_state) +{ + if(new_state == FALSE) + { + WDT->cmd = WDT_CMD_LOCK; + } + else + { + WDT->cmd = WDT_CMD_UNLOCK; + } +} + +/** + * @brief get wdt flag + * @param wdt_flag + * this parameter can be one of the following values: + * - WDT_DIVF_UPDATE_FLAG: division value update complete flag. + * - WDT_RLDF_UPDATE_FLAG: reload value update complete flag. + * @retval state of wdt flag + */ +flag_status wdt_flag_get(uint16_t wdt_flag) +{ + flag_status status = RESET; + + if ((WDT->sts & wdt_flag) != (uint16_t)RESET) + { + status = SET; + } + else + { + status = RESET; + } + + return status; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_wwdt.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_wwdt.c new file mode 100644 index 0000000..8b54385 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_wwdt.c @@ -0,0 +1,141 @@ +/** + ************************************************************************** + * @file at32f403a_407_wwdt.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the wwdt firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup WWDT + * @brief WWDT driver modules + * @{ + */ + +#ifdef WWDT_MODULE_ENABLED + +/** @defgroup WWDT_private_functions + * @{ + */ + +/** + * @brief wwdt reset by crm reset register + * @retval none + */ +void wwdt_reset(void) +{ + crm_periph_reset(CRM_WWDT_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_WWDT_PERIPH_RESET, FALSE); +} + +/** + * @brief wwdt division set + * @param division + * this parameter can be one of the following values: + * - WWDT_PCLK1_DIV_4096 (wwdt counter clock = (pclk1/4096)/1) + * - WWDT_PCLK1_DIV_8192 (wwdt counter clock = (pclk1/4096)/2) + * - WWDT_PCLK1_DIV_16384 (wwdt counter clock = (pclk1/4096)/4) + * - WWDT_PCLK1_DIV_32768 (wwdt counter clock = (pclk1/4096)/8) + * @retval none + */ +void wwdt_divider_set(wwdt_division_type division) +{ + WWDT->cfg_bit.div = division; +} + +/** + * @brief wwdt reload counter interrupt flag clear + * @param none + * @retval none + */ +void wwdt_flag_clear(void) +{ + WWDT->sts = 0; +} + +/** + * @brief wwdt enable and the counter value load + * @param wwdt_cnt (0x40~0x7f) + * @retval none + */ +void wwdt_enable(uint8_t wwdt_cnt) +{ + WWDT->ctrl = wwdt_cnt | WWDT_EN_BIT; +} + +/** + * @brief wwdt reload counter interrupt enable + * @param none + * @retval none + */ +void wwdt_interrupt_enable(void) +{ + WWDT->cfg_bit.rldien = TRUE; +} + +/** + * @brief wwdt reload counter interrupt flag get + * @param none + * @retval state of reload counter interrupt flag + */ +flag_status wwdt_flag_get(void) +{ + return (flag_status)WWDT->sts_bit.rldf; +} + +/** + * @brief wwdt counter value set + * @param wwdt_cnt (0x40~0x7f) + * @retval none + */ +void wwdt_counter_set(uint8_t wwdt_cnt) +{ + WWDT->ctrl_bit.cnt = wwdt_cnt; +} + +/** + * @brief wwdt window counter value set + * @param window_cnt (0x40~0x7f) + * @retval none + */ +void wwdt_window_counter_set(uint8_t window_cnt) +{ + WWDT->cfg_bit.win = window_cnt; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_xmc.c b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_xmc.c new file mode 100644 index 0000000..6b215e9 --- /dev/null +++ b/ArduinoCore-AT32F403A/system/Drivers/Firmware/src/at32f403a_407_xmc.c @@ -0,0 +1,508 @@ +/** + ************************************************************************** + * @file at32f403a_407_xmc.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for the xmc firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f403a_407_conf.h" + +/** @addtogroup AT32F403A_407_periph_driver + * @{ + */ + +/** @defgroup XMC + * @brief XMC driver modules + * @{ + */ + +#ifdef XMC_MODULE_ENABLED + +/** @defgroup XMC_private_functions + * @{ + */ + +/** + * @brief xmc nor or sram registers reset + * @param xmc_subbank + * this parameter can be one of the following values: + * - XMC_BANK1_NOR_SRAM1 + * - XMC_BANK1_NOR_SRAM4 + * @retval none + */ +void xmc_nor_sram_reset(xmc_nor_sram_subbank_type xmc_subbank) +{ + /* XMC_BANK1_NORSRAM1 */ + if(xmc_subbank == XMC_BANK1_NOR_SRAM1) + { + XMC_BANK1->ctrl_tmg_group[xmc_subbank].bk1ctrl = 0x000030DB; + } + /* XMC_BANK1_NORSRAM2, XMC_BANK1_NORSRAM3 or XMC_BANK1_NORSRAM4 */ + else + { + XMC_BANK1->ctrl_tmg_group[xmc_subbank].bk1ctrl = 0x000030D2; + } + XMC_BANK1->ctrl_tmg_group[xmc_subbank].bk1tmg = 0x0FFFFFFF; + XMC_BANK1->tmgwr_group[xmc_subbank].bk1tmgwr = 0x0FFFFFFF; +} + +/** + * @brief initialize the xmc nor/sram banks according to the specified + * parameters in the xmc_norsraminitstruct. + * @param xmc_norsram_init_struct : pointer to a xmc_norsram_init_type + * structure that contains the configuration information for + * the xmc nor/sram specified banks. + * @retval none + */ +void xmc_nor_sram_init(xmc_norsram_init_type* xmc_norsram_init_struct) +{ + /* bank1 nor/sram control register configuration */ + XMC_BANK1->ctrl_tmg_group[xmc_norsram_init_struct->subbank].bk1ctrl = + (uint32_t)xmc_norsram_init_struct->data_addr_multiplex | + xmc_norsram_init_struct->device | + xmc_norsram_init_struct->bus_type | + xmc_norsram_init_struct->burst_mode_enable | + xmc_norsram_init_struct->asynwait_enable | + xmc_norsram_init_struct->wait_signal_lv | + xmc_norsram_init_struct->wrapped_mode_enable | + xmc_norsram_init_struct->wait_signal_config | + xmc_norsram_init_struct->write_enable | + xmc_norsram_init_struct->wait_signal_enable | + xmc_norsram_init_struct->write_timing_enable | + xmc_norsram_init_struct->write_burst_syn; + + /* if nor flash device */ + if(xmc_norsram_init_struct->device == XMC_DEVICE_NOR) + { + XMC_BANK1->ctrl_tmg_group[xmc_norsram_init_struct->subbank].bk1ctrl_bit.noren = 0x1; + } +} + +/** + * @brief initialize the xmc nor/sram banks according to the specified + * parameters in the xmc_rw_timing_struct and xmc_w_timing_struct. + * @param xmc_rw_timing_struct : pointer to a xmc_norsram_timing_init_type + * structure that contains the configuration information for + * the xmc nor/sram specified banks. + * @param xmc_w_timing_struct : pointer to a xmc_norsram_timing_init_type + * structure that contains the configuration information for + * the xmc nor/sram specified banks. + * @retval none + */ +void xmc_nor_sram_timing_config(xmc_norsram_timing_init_type* xmc_rw_timing_struct, + xmc_norsram_timing_init_type* xmc_w_timing_struct) +{ + /* bank1 nor/sram timing register configuration */ + XMC_BANK1->ctrl_tmg_group[xmc_rw_timing_struct->subbank].bk1tmg = + (uint32_t)xmc_rw_timing_struct->addr_setup_time | + (xmc_rw_timing_struct->addr_hold_time << 4) | + (xmc_rw_timing_struct->data_setup_time << 8) | + (xmc_rw_timing_struct->bus_latency_time <<16) | + (xmc_rw_timing_struct->clk_psc << 20) | + (xmc_rw_timing_struct->data_latency_time << 24) | + xmc_rw_timing_struct->mode; + + /* bank1 nor/sram timing register for write configuration, if extended mode is used */ + if(xmc_rw_timing_struct->write_timing_enable == XMC_WRITE_TIMING_ENABLE) + { + XMC_BANK1->tmgwr_group[xmc_w_timing_struct->subbank].bk1tmgwr = + (uint32_t)xmc_w_timing_struct->addr_setup_time | + (xmc_w_timing_struct->addr_hold_time << 4) | + (xmc_w_timing_struct->data_setup_time << 8) | + (xmc_w_timing_struct->bus_latency_time << 16) | + (xmc_w_timing_struct->clk_psc << 20) | + (xmc_w_timing_struct->data_latency_time << 24) | + xmc_w_timing_struct->mode; + } + else + { + XMC_BANK1->tmgwr_group[xmc_w_timing_struct->subbank].bk1tmgwr = 0x0FFFFFFF; + } +} + +/** + * @brief fill each xmc_nor_sram_init_struct member with its default value. + * @param xmc_nor_sram_init_struct: pointer to a xmc_norsram_init_type + * structure which will be initialized. + * @retval none + */ +void xmc_norsram_default_para_init(xmc_norsram_init_type* xmc_nor_sram_init_struct) +{ + /* reset nor/sram init structure parameters values */ + xmc_nor_sram_init_struct->subbank = XMC_BANK1_NOR_SRAM1; + xmc_nor_sram_init_struct->data_addr_multiplex = XMC_DATA_ADDR_MUX_ENABLE; + xmc_nor_sram_init_struct->device = XMC_DEVICE_SRAM; + xmc_nor_sram_init_struct->bus_type = XMC_BUSTYPE_8_BITS; + xmc_nor_sram_init_struct->burst_mode_enable = XMC_BURST_MODE_DISABLE; + xmc_nor_sram_init_struct->asynwait_enable = XMC_ASYN_WAIT_DISABLE; + xmc_nor_sram_init_struct->wait_signal_lv = XMC_WAIT_SIGNAL_LEVEL_LOW; + xmc_nor_sram_init_struct->wrapped_mode_enable = XMC_WRAPPED_MODE_DISABLE; + xmc_nor_sram_init_struct->wait_signal_config = XMC_WAIT_SIGNAL_SYN_BEFORE; + xmc_nor_sram_init_struct->write_enable = XMC_WRITE_OPERATION_ENABLE; + xmc_nor_sram_init_struct->wait_signal_enable = XMC_WAIT_SIGNAL_ENABLE; + xmc_nor_sram_init_struct->write_timing_enable = XMC_WRITE_TIMING_DISABLE; + xmc_nor_sram_init_struct->write_burst_syn = XMC_WRITE_BURST_SYN_DISABLE; +} + +/** + * @brief fill each xmc_rw_timing_struct and xmc_w_timing_struct member with its default value. + * @param xmc_rw_timing_struct: pointer to a xmc_norsram_timing_init_type + * structure which will be initialized. + * @param xmc_w_timing_struct: pointer to a xmc_norsram_timing_init_type + * structure which will be initialized. + * @retval none + */ +void xmc_norsram_timing_default_para_init(xmc_norsram_timing_init_type* xmc_rw_timing_struct, + xmc_norsram_timing_init_type* xmc_w_timing_struct) +{ + xmc_rw_timing_struct->subbank = XMC_BANK1_NOR_SRAM1; + xmc_rw_timing_struct->write_timing_enable = XMC_WRITE_TIMING_DISABLE; + xmc_rw_timing_struct->addr_setup_time = 0xF; + xmc_rw_timing_struct->addr_hold_time = 0xF; + xmc_rw_timing_struct->data_setup_time = 0xFF; + xmc_rw_timing_struct->bus_latency_time = 0xF; + xmc_rw_timing_struct->clk_psc = 0xF; + xmc_rw_timing_struct->data_latency_time = 0xF; + xmc_rw_timing_struct->mode = XMC_ACCESS_MODE_A; + xmc_w_timing_struct->subbank = XMC_BANK1_NOR_SRAM1; + xmc_w_timing_struct->write_timing_enable = XMC_WRITE_TIMING_DISABLE; + xmc_w_timing_struct->addr_setup_time = 0xF; + xmc_w_timing_struct->addr_hold_time = 0xF; + xmc_w_timing_struct->data_setup_time = 0xFF; + xmc_w_timing_struct->bus_latency_time = 0xF; + xmc_w_timing_struct->clk_psc = 0xF; + xmc_w_timing_struct->data_latency_time = 0xF; + xmc_w_timing_struct->mode = XMC_ACCESS_MODE_A; +} + +/** + * @brief enable or disable the specified nor/sram memory bank. + * @param xmc_subbank + * this parameter can be one of the following values: + * - XMC_BANK1_NOR_SRAM1 + * - XMC_BANK1_NOR_SRAM4 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void xmc_nor_sram_enable(xmc_nor_sram_subbank_type xmc_subbank, confirm_state new_state) +{ + XMC_BANK1->ctrl_tmg_group[xmc_subbank].bk1ctrl_bit.en = new_state; +} + +/** + * @brief config the bus turnaround phase. + * @param xmc_sub_bank + * this parameter can be one of the following values: + * - XMC_BANK1_NOR_SRAM1 + * - XMC_BANK1_NOR_SRAM4 + * @param w2w_timing :write timing + * @param r2r_timing :read timing + * @retval none + */ +void xmc_ext_timing_config(xmc_nor_sram_subbank_type xmc_sub_bank, uint16_t w2w_timing, uint16_t r2r_timing) +{ + XMC_BANK1->ext_bit[xmc_sub_bank].buslatr2r = r2r_timing<<8; + XMC_BANK1->ext_bit[xmc_sub_bank].buslatw2w = w2w_timing; +} + +/** + * @brief xmc nand flash registers reset + * @param xmc_bank + * this parameter can be one of the following values: + * - XMC_BANK2_NAND + * @retval none + */ +void xmc_nand_reset(xmc_class_bank_type xmc_bank) +{ + /* set the XMC_BANK2_NAND registers to their reset values */ + if(xmc_bank == XMC_BANK2_NAND) + { + XMC_BANK2->bk2ctrl = 0x00000018; + XMC_BANK2->bk2is = 0x00000040; + XMC_BANK2->bk2tmgatt = 0xFCFCFCFC; + XMC_BANK2->bk2tmgmem = 0xFCFCFCFC; + } +} + +/** + * @brief initialize the xmc nand banks according to the specified + * parameters in the xmc_nandinitstruct. + * @param xmc_nand_init_struct : pointer to a xmc_nand_init_type + * structure that contains the configuration information for the xmc + * nand specified banks. + * @retval none + */ +void xmc_nand_init(xmc_nand_init_type* xmc_nand_init_struct) +{ + uint32_t tempctrl = 0x0; + + /* Set the tempctrl value according to xmc_nand_init_struct parameters */ + tempctrl = (uint32_t)xmc_nand_init_struct->wait_enable | + xmc_nand_init_struct->bus_type | + xmc_nand_init_struct->ecc_enable | + xmc_nand_init_struct->ecc_pagesize | + (xmc_nand_init_struct->delay_time_cycle << 9) | + (xmc_nand_init_struct->delay_time_ar << 13) | + 0x00000008; + + /* xmc_bank2_nand registers configuration */ + if(xmc_nand_init_struct->nand_bank == XMC_BANK2_NAND) + { + XMC_BANK2->bk2ctrl = tempctrl; + } +} + +/** + * @brief initialize the xmc nand banks according to the specified + * parameters in the xmc_nandinitstruct. + * @param xmc_regular_spacetiming_struct : pointer to a xmc_nand_timinginit_type + * structure that contains the configuration information for the xmc + * nand specified banks. + * @param xmc_special_spacetiming_struct : pointer to a xmc_nand_timinginit_type + * structure that contains the configuration information for the xmc + * nand specified banks. + * @retval none + */ +void xmc_nand_timing_config(xmc_nand_timinginit_type* xmc_regular_spacetiming_struct, + xmc_nand_timinginit_type* xmc_special_spacetiming_struct) +{ + uint32_t tempmem = 0x0, tempatt = 0x0; + + /* set the tempmem value according to xmc_nand_init_struct parameters */ + tempmem = (uint32_t)xmc_regular_spacetiming_struct->mem_setup_time | + (xmc_regular_spacetiming_struct->mem_waite_time << 8) | + (xmc_regular_spacetiming_struct->mem_hold_time << 16) | + (xmc_regular_spacetiming_struct->mem_hiz_time << 24); + + /* set the tempatt value according to xmc_nand_init_struct parameters */ + tempatt = (uint32_t)xmc_special_spacetiming_struct->mem_setup_time | + (xmc_special_spacetiming_struct->mem_waite_time << 8) | + (xmc_special_spacetiming_struct->mem_hold_time << 16) | + (xmc_special_spacetiming_struct->mem_hiz_time << 24); + /* xmc_bank2_nand registers configuration */ + if(xmc_regular_spacetiming_struct->class_bank == XMC_BANK2_NAND) + { + XMC_BANK2->bk2tmgatt = tempatt; + XMC_BANK2->bk2tmgmem = tempmem; + } +} + +/** + * @brief fill each xmc_nand_init_struct member with its default value. + * @param xmc_nand_init_struct: pointer to a xmc_nand_init_type + * structure which will be initialized. + * @retval none + */ +void xmc_nand_default_para_init(xmc_nand_init_type* xmc_nand_init_struct) +{ + /* reset nand init structure parameters values */ + xmc_nand_init_struct->nand_bank = XMC_BANK2_NAND; + xmc_nand_init_struct->wait_enable = XMC_WAIT_OPERATION_DISABLE; + xmc_nand_init_struct->bus_type = XMC_BUSTYPE_8_BITS; + xmc_nand_init_struct->ecc_enable = XMC_ECC_OPERATION_DISABLE; + xmc_nand_init_struct->ecc_pagesize = XMC_ECC_PAGESIZE_256_BYTES; + xmc_nand_init_struct->delay_time_cycle = 0x0; + xmc_nand_init_struct->delay_time_ar = 0x0; +} + +/** + * @brief fill each xmc_common_spacetiming_struct and xmc_attribute_spacetiming_struct member with its default value. + * @param xmc_common_spacetiming_struct: pointer to a xmc_nand_timinginit_type + * structure which will be initialized. + * @param xmc_special_spacetiming_struct: pointer to a xmc_nand_timinginit_type + * structure which will be initialized. + * @retval none + */ +void xmc_nand_timing_default_para_init(xmc_nand_timinginit_type* xmc_regular_spacetiming_struct, + xmc_nand_timinginit_type* xmc_special_spacetiming_struct) +{ + xmc_regular_spacetiming_struct->class_bank = XMC_BANK2_NAND; + xmc_regular_spacetiming_struct->mem_hold_time = 0xFC; + xmc_regular_spacetiming_struct->mem_waite_time = 0xFC; + xmc_regular_spacetiming_struct->mem_setup_time = 0xFC; + xmc_regular_spacetiming_struct->mem_hiz_time = 0xFC; + xmc_special_spacetiming_struct->class_bank = XMC_BANK2_NAND; + xmc_special_spacetiming_struct->mem_hold_time = 0xFC; + xmc_special_spacetiming_struct->mem_waite_time = 0xFC; + xmc_special_spacetiming_struct->mem_setup_time = 0xFC; + xmc_special_spacetiming_struct->mem_hiz_time = 0xFC; +} + +/** + * @brief enable or disable the specified nand memory bank. + * @param xmc_bank: specifies the xmc bank to be used + * this parameter can be one of the following values: + * - XMC_BANK2_NAND + * @param new_state (TRUE or FALSE) + * @retval none + */ +void xmc_nand_enable(xmc_class_bank_type xmc_bank, confirm_state new_state) +{ + /* enable or disable the nand bank2 by setting the en bit in the bk2ctrl register */ + if(xmc_bank == XMC_BANK2_NAND) + { + XMC_BANK2->bk2ctrl_bit.en = new_state; + } +} + +/** + * @brief enable or disable the xmc nand ecc feature. + * @param xmc_bank: specifies the xmc bank to be used + * this parameter can be one of the following values: + * - XMC_BANK2_NAND + * @param new_state (TRUE or FALSE) + * @retval none + */ +void xmc_nand_ecc_enable(xmc_class_bank_type xmc_bank, confirm_state new_state) +{ + /* enable the selected nand bank2 ecc function by setting the eccen bit in the bk2ctrl register */ + if(xmc_bank == XMC_BANK2_NAND) + { + XMC_BANK2->bk2ctrl_bit.eccen = new_state; + } +} + +/** + * @brief return the error correction code register value. + * @param xmc_bank: specifies the xmc bank to be used + * this parameter can be one of the following values: + * - XMC_BANK2_NAND + * @retval the error correction code (ecc) value. + */ +uint32_t xmc_ecc_get(xmc_class_bank_type xmc_bank) +{ + uint32_t eccvaule = 0x0; + + /* get the bk2ecc register value */ + if(xmc_bank == XMC_BANK2_NAND) + { + eccvaule = XMC_BANK2->bk2ecc; + } + + /* return the error correction code value */ + return eccvaule; +} + +/** + * @brief enable or disable the specified xmc interrupts. + * @param xmc_bank: specifies the xmc bank to be used + * this parameter can be one of the following values: + * - XMC_BANK2_NAND + * @param xmc_int: specifies the xmc interrupt sources to be enabled or disabled. + * this parameter can be any combination of the following values: + * - XMC_INT_RISING_EDGE + * - XMC_INT_LEVEL + * - XMC_INT_FALLING_EDGE + * @param new_state (TRUE or FALSE) + * @retval none + */ +void xmc_interrupt_enable(xmc_class_bank_type xmc_bank, xmc_interrupt_sources_type xmc_int, confirm_state new_state) +{ + if(new_state != FALSE) + { + /* enable the selected xmc_bank2 interrupts */ + if(xmc_bank == XMC_BANK2_NAND) + { + XMC_BANK2->bk2is |= xmc_int; + } + } + else + { + /* disable the selected xmc_bank2 interrupts */ + if(xmc_bank == XMC_BANK2_NAND) + { + XMC_BANK2->bk2is &= ~xmc_int; + } + } +} + +/** + * @brief check whether the specified xmc flag is set or not. + * @param xmc_bank: specifies the xmc bank to be used + * this parameter can be one of the following values: + * - XMC_BANK2_NAND + * @param xmc_flag: specifies the flag to check. + * this parameter can be any combination of the following values: + * - XMC_RISINGEDGE_FLAG + * - XMC_LEVEL_FLAG + * - XMC_FALLINGEDGE_FLAG + * - XMC_FEMPT_FLAG + * @retval none + */ +flag_status xmc_flag_status_get(xmc_class_bank_type xmc_bank, xmc_interrupt_flag_type xmc_flag) +{ + flag_status status = RESET; + uint32_t temp = 0; + + if(xmc_bank == XMC_BANK2_NAND) + { + temp = XMC_BANK2->bk2is; + } + /* get the flag status */ + if((temp & xmc_flag) == RESET) + { + status = RESET; + } + else + { + status = SET; + } + /* return the flag status */ + return status; +} + +/** + * @brief clear the xmc's pending flags. + * @param xmc_bank: specifies the xmc bank to be used + * this parameter can be one of the following values: + * - XMC_BANK2_NAND + * @param xmc_flag: specifies the flag to check. + * this parameter can be any combination of the following values: + * - XMC_RISINGEDGE_FLAG + * - XMC_LEVEL_FLAG + * - XMC_FALLINGEDGE_FLAG + * - XMC_FEMPT_FLAG + * @retval none + */ +void xmc_flag_clear(xmc_class_bank_type xmc_bank, xmc_interrupt_flag_type xmc_flag) +{ + __IO uint32_t int_state; + if(xmc_bank == XMC_BANK2_NAND) + { + int_state = XMC_BANK2->bk2is & 0x38; /* keep interrupt state */ + XMC_BANK2->bk2is = (~(xmc_flag | 0x38) | int_state); + } +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/ArduinoCore-AT32F403A/variants/AT32F403ACGU7/FrameLib.a b/ArduinoCore-AT32F403A/variants/AT32F403ACGU7/FrameLib.a new file mode 100644 index 0000000..bdfb101 Binary files /dev/null and b/ArduinoCore-AT32F403A/variants/AT32F403ACGU7/FrameLib.a differ diff --git a/ArduinoCore-AT32F403A/variants/AT32F403ACGU7/at32f403a_407_conf.h b/ArduinoCore-AT32F403A/variants/AT32F403ACGU7/at32f403a_407_conf.h new file mode 100644 index 0000000..97e0d98 --- /dev/null +++ b/ArduinoCore-AT32F403A/variants/AT32F403ACGU7/at32f403a_407_conf.h @@ -0,0 +1,163 @@ +/** + ************************************************************************** + * @file at32f403a_407_conf.h + * @version v2.0.9 + * @date 2022-04-25 + * @brief at32f403a_407 config header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_CONF_H +#define __AT32F403A_407_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief in the following line adjust the value of high speed exernal crystal (hext) + * used in your application + * tip: to avoid modifying this file each time you need to use different hext, you + * can define the hext value in your toolchain compiler preprocessor. + */ +#if !defined HEXT_VALUE +#define HEXT_VALUE ((uint32_t)8000000) /*!< value of the high speed exernal crystal in hz */ +#endif + +/** + * @brief in the following line adjust the high speed exernal crystal (hext) startup + * timeout value + */ +#define HEXT_STARTUP_TIMEOUT ((uint16_t)0x3000) /*!< time out for hext start up */ +#define HICK_VALUE ((uint32_t)8000000) /*!< value of the high speed internal clock in hz */ + +/* module define -------------------------------------------------------------*/ +#define CRM_MODULE_ENABLED +#define TMR_MODULE_ENABLED +#define RTC_MODULE_ENABLED +#define BPR_MODULE_ENABLED +#define GPIO_MODULE_ENABLED +#define I2C_MODULE_ENABLED +#define USART_MODULE_ENABLED +#define PWC_MODULE_ENABLED +#define CAN_MODULE_ENABLED +#define ADC_MODULE_ENABLED +#define DAC_MODULE_ENABLED +#define SPI_MODULE_ENABLED +#define DMA_MODULE_ENABLED +#define DEBUG_MODULE_ENABLED +#define FLASH_MODULE_ENABLED +#define CRC_MODULE_ENABLED +#define WWDT_MODULE_ENABLED +#define WDT_MODULE_ENABLED +#define EXINT_MODULE_ENABLED +#define SDIO_MODULE_ENABLED +#define XMC_MODULE_ENABLED +#define USB_MODULE_ENABLED +#define ACC_MODULE_ENABLED +#define MISC_MODULE_ENABLED +#define EMAC_MODULE_ENABLED + +/* includes ------------------------------------------------------------------*/ +#ifdef CRM_MODULE_ENABLED +#include "at32f403a_407_crm.h" +#endif +#ifdef TMR_MODULE_ENABLED +#include "at32f403a_407_tmr.h" +#endif +#ifdef RTC_MODULE_ENABLED +#include "at32f403a_407_rtc.h" +#endif +#ifdef BPR_MODULE_ENABLED +#include "at32f403a_407_bpr.h" +#endif +#ifdef GPIO_MODULE_ENABLED +#include "at32f403a_407_gpio.h" +#endif +#ifdef I2C_MODULE_ENABLED +#include "at32f403a_407_i2c.h" +#endif +#ifdef USART_MODULE_ENABLED +#include "at32f403a_407_usart.h" +#endif +#ifdef PWC_MODULE_ENABLED +#include "at32f403a_407_pwc.h" +#endif +#ifdef CAN_MODULE_ENABLED +#include "at32f403a_407_can.h" +#endif +#ifdef ADC_MODULE_ENABLED +#include "at32f403a_407_adc.h" +#endif +#ifdef DAC_MODULE_ENABLED +#include "at32f403a_407_dac.h" +#endif +#ifdef SPI_MODULE_ENABLED +#include "at32f403a_407_spi.h" +#endif +#ifdef DMA_MODULE_ENABLED +#include "at32f403a_407_dma.h" +#endif +#ifdef DEBUG_MODULE_ENABLED +#include "at32f403a_407_debug.h" +#endif +#ifdef FLASH_MODULE_ENABLED +#include "at32f403a_407_flash.h" +#endif +#ifdef CRC_MODULE_ENABLED +#include "at32f403a_407_crc.h" +#endif +#ifdef WWDT_MODULE_ENABLED +#include "at32f403a_407_wwdt.h" +#endif +#ifdef WDT_MODULE_ENABLED +#include "at32f403a_407_wdt.h" +#endif +#ifdef EXINT_MODULE_ENABLED +#include "at32f403a_407_exint.h" +#endif +#ifdef SDIO_MODULE_ENABLED +#include "at32f403a_407_sdio.h" +#endif +#ifdef XMC_MODULE_ENABLED +#include "at32f403a_407_xmc.h" +#endif +#ifdef ACC_MODULE_ENABLED +#include "at32f403a_407_acc.h" +#endif +#ifdef MISC_MODULE_ENABLED +#include "at32f403a_407_misc.h" +#endif +#ifdef USB_MODULE_ENABLED +#include "at32f403a_407_usb.h" +#endif +#ifdef EMAC_MODULE_ENABLED +#include "at32f403a_407_emac.h" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __AT32F403A_407_CONF_H */ + + diff --git a/ArduinoCore-AT32F403A/variants/AT32F403ACGU7/at32f403a_407_conf_template.h b/ArduinoCore-AT32F403A/variants/AT32F403ACGU7/at32f403a_407_conf_template.h new file mode 100644 index 0000000..97e0d98 --- /dev/null +++ b/ArduinoCore-AT32F403A/variants/AT32F403ACGU7/at32f403a_407_conf_template.h @@ -0,0 +1,163 @@ +/** + ************************************************************************** + * @file at32f403a_407_conf.h + * @version v2.0.9 + * @date 2022-04-25 + * @brief at32f403a_407 config header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F403A_407_CONF_H +#define __AT32F403A_407_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief in the following line adjust the value of high speed exernal crystal (hext) + * used in your application + * tip: to avoid modifying this file each time you need to use different hext, you + * can define the hext value in your toolchain compiler preprocessor. + */ +#if !defined HEXT_VALUE +#define HEXT_VALUE ((uint32_t)8000000) /*!< value of the high speed exernal crystal in hz */ +#endif + +/** + * @brief in the following line adjust the high speed exernal crystal (hext) startup + * timeout value + */ +#define HEXT_STARTUP_TIMEOUT ((uint16_t)0x3000) /*!< time out for hext start up */ +#define HICK_VALUE ((uint32_t)8000000) /*!< value of the high speed internal clock in hz */ + +/* module define -------------------------------------------------------------*/ +#define CRM_MODULE_ENABLED +#define TMR_MODULE_ENABLED +#define RTC_MODULE_ENABLED +#define BPR_MODULE_ENABLED +#define GPIO_MODULE_ENABLED +#define I2C_MODULE_ENABLED +#define USART_MODULE_ENABLED +#define PWC_MODULE_ENABLED +#define CAN_MODULE_ENABLED +#define ADC_MODULE_ENABLED +#define DAC_MODULE_ENABLED +#define SPI_MODULE_ENABLED +#define DMA_MODULE_ENABLED +#define DEBUG_MODULE_ENABLED +#define FLASH_MODULE_ENABLED +#define CRC_MODULE_ENABLED +#define WWDT_MODULE_ENABLED +#define WDT_MODULE_ENABLED +#define EXINT_MODULE_ENABLED +#define SDIO_MODULE_ENABLED +#define XMC_MODULE_ENABLED +#define USB_MODULE_ENABLED +#define ACC_MODULE_ENABLED +#define MISC_MODULE_ENABLED +#define EMAC_MODULE_ENABLED + +/* includes ------------------------------------------------------------------*/ +#ifdef CRM_MODULE_ENABLED +#include "at32f403a_407_crm.h" +#endif +#ifdef TMR_MODULE_ENABLED +#include "at32f403a_407_tmr.h" +#endif +#ifdef RTC_MODULE_ENABLED +#include "at32f403a_407_rtc.h" +#endif +#ifdef BPR_MODULE_ENABLED +#include "at32f403a_407_bpr.h" +#endif +#ifdef GPIO_MODULE_ENABLED +#include "at32f403a_407_gpio.h" +#endif +#ifdef I2C_MODULE_ENABLED +#include "at32f403a_407_i2c.h" +#endif +#ifdef USART_MODULE_ENABLED +#include "at32f403a_407_usart.h" +#endif +#ifdef PWC_MODULE_ENABLED +#include "at32f403a_407_pwc.h" +#endif +#ifdef CAN_MODULE_ENABLED +#include "at32f403a_407_can.h" +#endif +#ifdef ADC_MODULE_ENABLED +#include "at32f403a_407_adc.h" +#endif +#ifdef DAC_MODULE_ENABLED +#include "at32f403a_407_dac.h" +#endif +#ifdef SPI_MODULE_ENABLED +#include "at32f403a_407_spi.h" +#endif +#ifdef DMA_MODULE_ENABLED +#include "at32f403a_407_dma.h" +#endif +#ifdef DEBUG_MODULE_ENABLED +#include "at32f403a_407_debug.h" +#endif +#ifdef FLASH_MODULE_ENABLED +#include "at32f403a_407_flash.h" +#endif +#ifdef CRC_MODULE_ENABLED +#include "at32f403a_407_crc.h" +#endif +#ifdef WWDT_MODULE_ENABLED +#include "at32f403a_407_wwdt.h" +#endif +#ifdef WDT_MODULE_ENABLED +#include "at32f403a_407_wdt.h" +#endif +#ifdef EXINT_MODULE_ENABLED +#include "at32f403a_407_exint.h" +#endif +#ifdef SDIO_MODULE_ENABLED +#include "at32f403a_407_sdio.h" +#endif +#ifdef XMC_MODULE_ENABLED +#include "at32f403a_407_xmc.h" +#endif +#ifdef ACC_MODULE_ENABLED +#include "at32f403a_407_acc.h" +#endif +#ifdef MISC_MODULE_ENABLED +#include "at32f403a_407_misc.h" +#endif +#ifdef USB_MODULE_ENABLED +#include "at32f403a_407_usb.h" +#endif +#ifdef EMAC_MODULE_ENABLED +#include "at32f403a_407_emac.h" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __AT32F403A_407_CONF_H */ + + diff --git a/ArduinoCore-AT32F403A/variants/AT32F403ACGU7/linker_scripts/AT32F403AxG_FLASH.ld b/ArduinoCore-AT32F403A/variants/AT32F403ACGU7/linker_scripts/AT32F403AxG_FLASH.ld new file mode 100644 index 0000000..0d65082 --- /dev/null +++ b/ArduinoCore-AT32F403A/variants/AT32F403ACGU7/linker_scripts/AT32F403AxG_FLASH.ld @@ -0,0 +1,154 @@ +/* +***************************************************************************** +** +** File : AT32F403AxG_FLASH.ld +** +** Abstract : Linker script for AT32F403AxG Device with +** 1000KByte FLASH, 96KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : Artery Tek AT32 +** +** Environment : Arm gcc toolchain +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20018000; /* end of RAM */ + +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1000K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 96K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/ArduinoCore-AT32F403A/variants/AT32F403ACGU7/startup_at32f403a_407.S b/ArduinoCore-AT32F403A/variants/AT32F403ACGU7/startup_at32f403a_407.S new file mode 100644 index 0000000..22f5631 --- /dev/null +++ b/ArduinoCore-AT32F403A/variants/AT32F403ACGU7/startup_at32f403a_407.S @@ -0,0 +1,480 @@ +/** + ****************************************************************************** + * @file startup_at32f403a_407.s + * @version v2.0.9 + * @date 2022-04-25 + * @brief at32f403a_407xx devices vector table for gcc toolchain. + * this module performs: + * - set the initial sp + * - set the initial pc == reset_handler, + * - set the vector table entries with the exceptions isr address + * - configure the clock system and the external sram to + * be used as data memory (optional, to be enabled by user) + * - branches to main in the c library (which eventually + * calls main()). + * after reset the cortex-m4 processor is in thread mode, + * priority is privileged, and the stack is set to main. + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m4 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss +/* stack used for SystemInit_ExtMemCtl; always internal RAM used */ + +/** + * @brief This is the code that gets called when the processor first + * starts execution following a reset event. Only the absolutely + * necessary set is performed, after which the application + * supplied main() routine is called. + * @param None + * @retval None +*/ + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + +/* Copy the data segment initializers from flash to SRAM */ + movs r1, #0 + b LoopCopyDataInit + +CopyDataInit: + ldr r3, =_sidata + ldr r3, [r3, r1] + str r3, [r0, r1] + adds r1, r1, #4 + +LoopCopyDataInit: + ldr r0, =_sdata + ldr r3, =_edata + adds r2, r0, r1 + cmp r2, r3 + bcc CopyDataInit + ldr r2, =_sbss + b LoopFillZerobss +/* Zero fill the bss segment. */ +FillZerobss: + movs r3, #0 + str r3, [r2], #4 + +LoopFillZerobss: + ldr r3, = _ebss + cmp r2, r3 + bcc FillZerobss + +/* Call the clock system intitialization function.*/ + bl SystemInit +/* Call static constructors */ + bl __libc_init_array +/* Call the application's entry point.*/ + bl main + bx lr +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * @param None + * @retval None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex M3. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +*******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + + /* External Interrupts */ + .word WWDT_IRQHandler /* Window Watchdog Timer */ + .word PVM_IRQHandler /* PVM through EXINT Line detect */ + .word TAMPER_IRQHandler /* Tamper */ + .word RTC_IRQHandler /* RTC */ + .word FLASH_IRQHandler /* Flash */ + .word CRM_IRQHandler /* CRM */ + .word EXINT0_IRQHandler /* EXINT Line 0 */ + .word EXINT1_IRQHandler /* EXINT Line 1 */ + .word EXINT2_IRQHandler /* EXINT Line 2 */ + .word EXINT3_IRQHandler /* EXINT Line 3 */ + .word EXINT4_IRQHandler /* EXINT Line 4 */ + .word DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */ + .word DMA1_Channel2_IRQHandler /* DMA1 Channel 2 */ + .word DMA1_Channel3_IRQHandler /* DMA1 Channel 3 */ + .word DMA1_Channel4_IRQHandler /* DMA1 Channel 4 */ + .word DMA1_Channel5_IRQHandler /* DMA1 Channel 5 */ + .word DMA1_Channel6_IRQHandler /* DMA1 Channel 6 */ + .word DMA1_Channel7_IRQHandler /* DMA1 Channel 7 */ + .word ADC1_2_IRQHandler /* ADC1 & ADC2 */ + .word USBFS_H_CAN1_TX_IRQHandler /* USB High Priority or CAN1 TX */ + .word USBFS_L_CAN1_RX0_IRQHandler /* USB Low Priority or CAN1 RX0 */ + .word CAN1_RX1_IRQHandler /* CAN1 RX1 */ + .word CAN1_SE_IRQHandler /* CAN1 SE */ + .word EXINT9_5_IRQHandler /* EXINT Line [9:5] */ + .word TMR1_BRK_TMR9_IRQHandler /* TMR1 Brake and TMR9 */ + .word TMR1_OVF_TMR10_IRQHandler /* TMR1 Overflow and TMR10 */ + .word TMR1_TRG_HALL_TMR11_IRQHandler /* TMR1 Trigger and hall and TMR11 */ + .word TMR1_CH_IRQHandler /* TMR1 Channel */ + .word TMR2_GLOBAL_IRQHandler /* TMR2 */ + .word TMR3_GLOBAL_IRQHandler /* TMR3 */ + .word TMR4_GLOBAL_IRQHandler /* TMR4 */ + .word I2C1_EVT_IRQHandler /* I2C1 Event */ + .word I2C1_ERR_IRQHandler /* I2C1 Error */ + .word I2C2_EVT_IRQHandler /* I2C2 Event */ + .word I2C2_ERR_IRQHandler /* I2C2 Error */ + .word SPI1_IRQHandler /* SPI1 */ + .word SPI2_I2S2EXT_IRQHandler /* SPI2 & I2S2EXT */ + .word USART1_IRQHandler /* USART1 */ + .word USART2_IRQHandler /* USART2 */ + .word USART3_IRQHandler /* USART3 */ + .word EXINT15_10_IRQHandler /* EXINT Line [15:10] */ + .word RTCAlarm_IRQHandler /* RTC Alarm through EXINT Line */ + .word USBFSWakeUp_IRQHandler /* USB Wakeup from suspend */ + .word TMR8_BRK_TMR12_IRQHandler /* TMR8 Brake and TMR12 */ + .word TMR8_OVF_TMR13_IRQHandler /* TMR8 Overflow and TMR13 */ + .word TMR8_TRG_HALL_TMR14_IRQHandler /* TMR8 Trigger and hall and TMR14 */ + .word TMR8_CH_IRQHandler /* TMR8 Channel */ + .word ADC3_IRQHandler /* ADC3 */ + .word XMC_IRQHandler /* XMC */ + .word SDIO1_IRQHandler /* SDIO1 */ + .word TMR5_GLOBAL_IRQHandler /* TMR5 */ + .word SPI3_I2S3EXT_IRQHandler /* SPI3 & I2S3EXT */ + .word UART4_IRQHandler /* UART4 */ + .word UART5_IRQHandler /* UART5 */ + .word TMR6_GLOBAL_IRQHandler /* TMR6 */ + .word TMR7_GLOBAL_IRQHandler /* TMR7 */ + .word DMA2_Channel1_IRQHandler /* DMA2 Channel1 */ + .word DMA2_Channel2_IRQHandler /* DMA2 Channel2 */ + .word DMA2_Channel3_IRQHandler /* DMA2 Channel3 */ + .word DMA2_Channel4_5_IRQHandler /* DMA2 Channel4 & Channel5 */ + .word SDIO2_IRQHandler /* SDIO2 */ + .word I2C3_EVT_IRQHandler /* I2C3 Event */ + .word I2C3_ERR_IRQHandler /* I2C3 Error */ + .word SPI4_IRQHandler /* SPI4 */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word CAN2_TX_IRQHandler /* CAN2 TX */ + .word CAN2_RX0_IRQHandler /* CAN2 RX0 */ + .word CAN2_RX1_IRQHandler /* CAN2 RX1 */ + .word CAN2_SE_IRQHandler /* CAN2 SE */ + .word ACC_IRQHandler /* ACC */ + .word USBFS_MAPH_IRQHandler /* USB Map HP */ + .word USBFS_MAPL_IRQHandler /* USB Map LP */ + .word DMA2_Channel6_7_IRQHandler /* DMA2 Channel6 & Channel7 */ + .word USART6_IRQHandler /* USART6 */ + .word UART7_IRQHandler /* UART7 */ + .word UART8_IRQHandler /* UART8 */ + .word EMAC_IRQHandler /* EMAC */ + .word EMAC_WKUP_IRQHandler /* EMAC Wakeup */ + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDT_IRQHandler + .thumb_set WWDT_IRQHandler,Default_Handler + + .weak PVM_IRQHandler + .thumb_set PVM_IRQHandler,Default_Handler + + .weak TAMPER_IRQHandler + .thumb_set TAMPER_IRQHandler,Default_Handler + + .weak RTC_IRQHandler + .thumb_set RTC_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak CRM_IRQHandler + .thumb_set CRM_IRQHandler,Default_Handler + + .weak EXINT0_IRQHandler + .thumb_set EXINT0_IRQHandler,Default_Handler + + .weak EXINT1_IRQHandler + .thumb_set EXINT1_IRQHandler,Default_Handler + + .weak EXINT2_IRQHandler + .thumb_set EXINT2_IRQHandler,Default_Handler + + .weak EXINT3_IRQHandler + .thumb_set EXINT3_IRQHandler,Default_Handler + + .weak EXINT4_IRQHandler + .thumb_set EXINT4_IRQHandler,Default_Handler + + .weak DMA1_Channel1_IRQHandler + .thumb_set DMA1_Channel1_IRQHandler,Default_Handler + + .weak DMA1_Channel2_IRQHandler + .thumb_set DMA1_Channel2_IRQHandler,Default_Handler + + .weak DMA1_Channel3_IRQHandler + .thumb_set DMA1_Channel3_IRQHandler,Default_Handler + + .weak DMA1_Channel4_IRQHandler + .thumb_set DMA1_Channel4_IRQHandler,Default_Handler + + .weak DMA1_Channel5_IRQHandler + .thumb_set DMA1_Channel5_IRQHandler,Default_Handler + + .weak DMA1_Channel6_IRQHandler + .thumb_set DMA1_Channel6_IRQHandler,Default_Handler + + .weak DMA1_Channel7_IRQHandler + .thumb_set DMA1_Channel7_IRQHandler,Default_Handler + + .weak ADC1_2_IRQHandler + .thumb_set ADC1_2_IRQHandler,Default_Handler + + .weak USBFS_H_CAN1_TX_IRQHandler + .thumb_set USBFS_H_CAN1_TX_IRQHandler,Default_Handler + + .weak USBFS_L_CAN1_RX0_IRQHandler + .thumb_set USBFS_L_CAN1_RX0_IRQHandler,Default_Handler + + .weak CAN1_RX1_IRQHandler + .thumb_set CAN1_RX1_IRQHandler,Default_Handler + + .weak CAN1_SE_IRQHandler + .thumb_set CAN1_SE_IRQHandler,Default_Handler + + .weak EXINT9_5_IRQHandler + .thumb_set EXINT9_5_IRQHandler,Default_Handler + + .weak TMR1_BRK_TMR9_IRQHandler + .thumb_set TMR1_BRK_TMR9_IRQHandler,Default_Handler + + .weak TMR1_OVF_TMR10_IRQHandler + .thumb_set TMR1_OVF_TMR10_IRQHandler,Default_Handler + + .weak TMR1_TRG_HALL_TMR11_IRQHandler + .thumb_set TMR1_TRG_HALL_TMR11_IRQHandler,Default_Handler + + .weak TMR1_CH_IRQHandler + .thumb_set TMR1_CH_IRQHandler,Default_Handler + + .weak TMR2_GLOBAL_IRQHandler + .thumb_set TMR2_GLOBAL_IRQHandler,Default_Handler + + .weak TMR3_GLOBAL_IRQHandler + .thumb_set TMR3_GLOBAL_IRQHandler,Default_Handler + + .weak TMR4_GLOBAL_IRQHandler + .thumb_set TMR4_GLOBAL_IRQHandler,Default_Handler + + .weak I2C1_EVT_IRQHandler + .thumb_set I2C1_EVT_IRQHandler,Default_Handler + + .weak I2C1_ERR_IRQHandler + .thumb_set I2C1_ERR_IRQHandler,Default_Handler + + .weak I2C2_EVT_IRQHandler + .thumb_set I2C2_EVT_IRQHandler,Default_Handler + + .weak I2C2_ERR_IRQHandler + .thumb_set I2C2_ERR_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_I2S2EXT_IRQHandler + .thumb_set SPI2_I2S2EXT_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak USART2_IRQHandler + .thumb_set USART2_IRQHandler,Default_Handler + + .weak USART3_IRQHandler + .thumb_set USART3_IRQHandler,Default_Handler + + .weak EXINT15_10_IRQHandler + .thumb_set EXINT15_10_IRQHandler,Default_Handler + + .weak RTCAlarm_IRQHandler + .thumb_set RTCAlarm_IRQHandler,Default_Handler + + .weak USBFSWakeUp_IRQHandler + .thumb_set USBFSWakeUp_IRQHandler,Default_Handler + + .weak TMR8_BRK_TMR12_IRQHandler + .thumb_set TMR8_BRK_TMR12_IRQHandler,Default_Handler + + .weak TMR8_OVF_TMR13_IRQHandler + .thumb_set TMR8_OVF_TMR13_IRQHandler,Default_Handler + + .weak TMR8_TRG_HALL_TMR14_IRQHandler + .thumb_set TMR8_TRG_HALL_TMR14_IRQHandler,Default_Handler + + .weak TMR8_CH_IRQHandler + .thumb_set TMR8_CH_IRQHandler,Default_Handler + + .weak ADC3_IRQHandler + .thumb_set ADC3_IRQHandler,Default_Handler + + .weak XMC_IRQHandler + .thumb_set XMC_IRQHandler,Default_Handler + + .weak SDIO1_IRQHandler + .thumb_set SDIO1_IRQHandler,Default_Handler + + .weak TMR5_GLOBAL_IRQHandler + .thumb_set TMR5_GLOBAL_IRQHandler,Default_Handler + + .weak SPI3_I2S3EXT_IRQHandler + .thumb_set SPI3_I2S3EXT_IRQHandler,Default_Handler + + .weak UART4_IRQHandler + .thumb_set UART4_IRQHandler,Default_Handler + + .weak UART5_IRQHandler + .thumb_set UART5_IRQHandler,Default_Handler + + .weak TMR6_GLOBAL_IRQHandler + .thumb_set TMR6_GLOBAL_IRQHandler,Default_Handler + + .weak TMR7_GLOBAL_IRQHandler + .thumb_set TMR7_GLOBAL_IRQHandler,Default_Handler + + .weak DMA2_Channel1_IRQHandler + .thumb_set DMA2_Channel1_IRQHandler,Default_Handler + + .weak DMA2_Channel2_IRQHandler + .thumb_set DMA2_Channel2_IRQHandler,Default_Handler + + .weak DMA2_Channel3_IRQHandler + .thumb_set DMA2_Channel3_IRQHandler,Default_Handler + + .weak DMA2_Channel4_5_IRQHandler + .thumb_set DMA2_Channel4_5_IRQHandler,Default_Handler + + .weak SDIO2_IRQHandler + .thumb_set SDIO2_IRQHandler,Default_Handler + + .weak I2C3_EVT_IRQHandler + .thumb_set I2C3_EVT_IRQHandler,Default_Handler + + .weak I2C3_ERR_IRQHandler + .thumb_set I2C3_ERR_IRQHandler,Default_Handler + + .weak SPI4_IRQHandler + .thumb_set SPI4_IRQHandler,Default_Handler + + .weak CAN2_TX_IRQHandler + .thumb_set CAN2_TX_IRQHandler,Default_Handler + + .weak CAN2_RX0_IRQHandler + .thumb_set CAN2_RX0_IRQHandler ,Default_Handler + + .weak CAN2_RX1_IRQHandler + .thumb_set CAN2_RX1_IRQHandler ,Default_Handler + + .weak CAN2_SE_IRQHandler + .thumb_set CAN2_SE_IRQHandler,Default_Handler + + .weak ACC_IRQHandler + .thumb_set ACC_IRQHandler,Default_Handler + + .weak USBFS_MAPH_IRQHandler + .thumb_set USBFS_MAPH_IRQHandler,Default_Handler + + .weak USBFS_MAPL_IRQHandler + .thumb_set USBFS_MAPL_IRQHandler,Default_Handler + + .weak DMA2_Channel6_7_IRQHandler + .thumb_set DMA2_Channel6_7_IRQHandler,Default_Handler + + .weak USART6_IRQHandler + .thumb_set USART6_IRQHandler,Default_Handler + + .weak UART7_IRQHandler + .thumb_set UART7_IRQHandler,Default_Handler + + .weak UART8_IRQHandler + .thumb_set UART8_IRQHandler,Default_Handler + + .weak EMAC_IRQHandler + .thumb_set EMAC_IRQHandler,Default_Handler + + .weak EMAC_WKUP_IRQHandler + .thumb_set EMAC_WKUP_IRQHandler,Default_Handler diff --git a/ArduinoCore-AT32F403A/variants/AT32F403ACGU7/system_at32f403a_407.c b/ArduinoCore-AT32F403A/variants/AT32F403ACGU7/system_at32f403a_407.c new file mode 100644 index 0000000..1fea754 --- /dev/null +++ b/ArduinoCore-AT32F403A/variants/AT32F403ACGU7/system_at32f403a_407.c @@ -0,0 +1,193 @@ +/** + ************************************************************************** + * @file system_at32f403a_407.c + * @version v2.0.9 + * @date 2022-04-25 + * @brief contains all the functions for cmsis cortex-m4 system source file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup AT32F403A_407_system + * @{ + */ + +#include "at32f403a_407.h" + +/** @addtogroup AT32F403A_407_system_private_defines + * @{ + */ +#define VECT_TAB_OFFSET 0x0 /*!< vector table base offset field. this value must be a multiple of 0x200. */ +/** + * @} + */ + +/** @addtogroup AT32F403A_407_system_private_variables + * @{ + */ +unsigned int system_core_clock = HICK_VALUE; /*!< system clock frequency (core clock) */ +/** + * @} + */ + +/** @addtogroup AT32F403A_407_system_private_functions + * @{ + */ + +/** + * @brief setup the microcontroller system + * initialize the flash interface. + * @note this function should be used only after reset. + * @param none + * @retval none + */ +void SystemInit (void) +{ +#if defined (__FPU_USED) && (__FPU_USED == 1U) + SCB->CPACR |= ((3U << 10U * 2U) | /* set cp10 full access */ + (3U << 11U * 2U) ); /* set cp11 full access */ +#endif + + /* reset the crm clock configuration to the default reset state(for debug purpose) */ + /* set hicken bit */ + CRM->ctrl_bit.hicken = TRUE; + + /* wait hick stable */ + while(CRM->ctrl_bit.hickstbl != SET); + + /* hick used as system clock */ + CRM->cfg_bit.sclksel = CRM_SCLK_HICK; + + /* wait sclk switch status */ + while(CRM->cfg_bit.sclksts != CRM_SCLK_HICK); + + /* reset cfg register, include sclk switch, ahbdiv, apb1div, apb2div, adcdiv, + clkout pllrcs, pllhextdiv, pllmult, usbdiv and pllrange bits */ + CRM->cfg = 0; + + /* reset hexten, hextbyps, cfden and pllen bits */ + CRM->ctrl &= ~(0x010D0000U); + + /* reset clkout[3], usbbufs, hickdiv, clkoutdiv */ + CRM->misc1 = 0; + + /* disable all interrupts enable and clear pending bits */ + CRM->clkint = 0x009F0000; + +#ifdef VECT_TAB_SRAM + SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* vector table relocation in internal sram. */ +#else + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* vector table relocation in internal flash. */ +#endif +} + +/** + * @brief update system_core_clock variable according to clock register values. + * the system_core_clock variable contains the core clock (hclk), it can + * be used by the user application to setup the systick timer or configure + * other parameters. + * @param none + * @retval none + */ +void system_core_clock_update(void) +{ + uint32_t hext_prediv = 0, pll_mult = 0, pll_mult_h = 0, pll_clock_source = 0, temp = 0, div_value = 0; + crm_sclk_type sclk_source; + + static const uint8_t sys_ahb_div_table[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + + /* get sclk source */ + sclk_source = crm_sysclk_switch_status_get(); + + switch(sclk_source) + { + case CRM_SCLK_HICK: + if(((CRM->misc3_bit.hick_to_sclk) != RESET) && ((CRM->misc1_bit.hickdiv) != RESET)) + system_core_clock = HICK_VALUE * 6; + else + system_core_clock = HICK_VALUE; + break; + case CRM_SCLK_HEXT: + system_core_clock = HEXT_VALUE; + break; + case CRM_SCLK_PLL: + pll_clock_source = CRM->cfg_bit.pllrcs; + { + /* get multiplication factor */ + pll_mult = CRM->cfg_bit.pllmult_l; + pll_mult_h = CRM->cfg_bit.pllmult_h; + /* process high bits */ + if((pll_mult_h != 0U) || (pll_mult == 15U)){ + pll_mult += ((16U * pll_mult_h) + 1U); + } + else + { + pll_mult += 2U; + } + + if (pll_clock_source == 0x00) + { + /* hick divided by 2 selected as pll clock entry */ + system_core_clock = (HICK_VALUE >> 1) * pll_mult; + } + else + { + /* hext selected as pll clock entry */ + if (CRM->cfg_bit.pllhextdiv != RESET) + { + hext_prediv = CRM->misc3_bit.hextdiv; + + /* hext clock divided by 2 */ + system_core_clock = (HEXT_VALUE / (hext_prediv + 2)) * pll_mult; + } + else + { + system_core_clock = HEXT_VALUE * pll_mult; + } + } + } + break; + default: + system_core_clock = HICK_VALUE; + break; + } + + /* compute sclk, ahbclk frequency */ + /* get ahb division */ + temp = CRM->cfg_bit.ahbdiv; + div_value = sys_ahb_div_table[temp]; + /* ahbclk frequency */ + system_core_clock = system_core_clock >> div_value; +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/tools/Artery_ISP_Console-0.0.1-windows.zip b/tools/Artery_ISP_Console-0.0.1-windows.zip new file mode 100644 index 0000000..3c713ce Binary files /dev/null and b/tools/Artery_ISP_Console-0.0.1-windows.zip differ