diff options
author | Ben V. Brown <[email protected]> | 2021-10-02 14:48:58 +1000 |
---|---|---|
committer | GitHub <[email protected]> | 2021-10-02 14:48:58 +1000 |
commit | 3594604efc4a68c0bdcafcb6236303d9c1b4a5ec (patch) | |
tree | 82f8d3c21cd836cdb2020c02e72cad5965a4b350 | |
parent | 04ad5a3bfc6471534caa95be4dd34f94d48209d6 (diff) | |
download | IronOS-3594604efc4a68c0bdcafcb6236303d9c1b4a5ec.tar.gz IronOS-3594604efc4a68c0bdcafcb6236303d9c1b4a5ec.zip |
Fixes for I2C on Pinecil + USB-PD stack (#1099)
* Remove unused includes
* Adding in submodule
* Move fusb functions to the BSP
* Remove old code
* Creating IronOS PD integration wrapper
* Redirect to wrapper
* pd lib updates
* fix Docker build
* Finish linking across
* Cleanup
* Update Makefile
* Update push.yml
* Update push.yml
* PD -> Compensate for different tick rates
* Update codeql-analysis.yml
* Fix PD #define for @Firebie
* Check irq low at start
* Update BSP.h
* Update main.cpp
* Closer delay
* Update OLED.cpp
* Bugfix trying to start QC too early
* Missing fusb shouldnt hang qc
* Update FreeRTOSConfig.h
* Update the GD drivers
* Update Pinecil IRQ setup
* Redirect printf() to uart
* Update Power.cpp
* Adding extras to PD state
* Update USBPD.cpp
* Delay in printf
* Iterate once before delay on start
* Update usb-pd
* master usb-pd now
* Format gd libs
* Update gd32vf103_bkp.c
* Guard with PD timeout
* Remove CodeQL
* Slow for testing, fix runt pulses at start
* Fix runt pulse in read size 1
* Cleaner probing setup
* Testing delay during stop gen in read 1
* Update I2C driver
* Update gd32vf103_i2c.c
* Cleaning up i2c wrapper a little, given up on dma for rx
* Update preRTOS.cpp
* Update Setup.cpp
* Update MOVThread.cpp
* Slow down UART to work with new clock config
* Better ack setup for 2 byte read
* Cleanup POW_PD so cant be lost in #includes
* tipResistance -> TIP_RESISTANCE
* handle NOP race on len==2
* Update configuration.h
* Dont use neg timeout to mask anymore
* Not required for MHP
* Fix up source display Miniware
* Fix race on PD init
* Update POWThread.cpp
* Update formatting
* MHP format
* Update push.yml
* Faster TS80P I2C
* Bugfix for IRQ handlers
* Correctly handle I2C race on PD access
* Fix CI error (unused var) and MHP IRQ
* Test Pinecil alt ADC mode
114 files changed, 3100 insertions, 6436 deletions
diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 92f77bf3..65cfce2d 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -12,6 +12,8 @@ jobs: steps: - uses: actions/checkout@v2 + with: + submodules: true - name: chmod run: chmod +x setup.sh && chmod +x source/build.sh && sudo mkdir -p /build/cache && sudo chmod -R 777 /build @@ -57,6 +59,8 @@ jobs: steps: - uses: actions/checkout@v2 + with: + submodules: true - name: chmod run: chmod +x setup.sh && chmod +x source/build.sh && sudo mkdir -p /build/cache && sudo chmod -R 777 /build @@ -97,6 +101,8 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 + with: + submodules: true - name: Setup run: sudo apt-get update && sudo apt-get install -y python3 && pip3 install bdflib @@ -117,6 +123,8 @@ jobs: steps: - uses: actions/checkout@v2 + with: + submodules: true - name: chmod run: chmod +x setup.sh && chmod +x source/build.sh && sudo mkdir -p /build/cache && sudo chmod -R 777 /build @@ -133,7 +141,7 @@ jobs: ${{ runner.os }}- - name: setup - run: ./setup.sh + run: sudo apt-get update && sudo apt-get install -y make clang git python3 python3-pip && python3 -m pip install bdflib black flake8 - name: Check formatting with clang-format run: cd source && make clean && make check-style diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..6477ac5f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "source/Core/Drivers/usb-pd"] + path = source/Core/Drivers/usb-pd + url = https://github.com/Ralim/usb-pd.git @@ -6,7 +6,7 @@ WORKDIR /build RUN echo "deb mirror://mirrors.ubuntu.com/mirrors.txt focal main restricted universe multiverse" > /etc/apt/sources.list && \
echo "deb mirror://mirrors.ubuntu.com/mirrors.txt focal-updates main restricted universe multiverse" >> /etc/apt/sources.list && \
echo "deb mirror://mirrors.ubuntu.com/mirrors.txt focal-security main restricted universe multiverse" >> /etc/apt/sources.list && \
- DEBIAN_FRONTEND=noninteractive apt-get update
+ DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y ca-certificates
# Install dependencies to build the firmware
RUN apt-get install -y \
make \
diff --git a/source/Core/BSP/BSP.h b/source/Core/BSP/BSP.h index 0caf21bb..82e1fdd6 100644 --- a/source/Core/BSP/BSP.h +++ b/source/Core/BSP/BSP.h @@ -1,4 +1,5 @@ #include "BSP_Flash.h"
+#include "BSP_PD.h"
#include "BSP_Power.h"
#include "BSP_QC.h"
#include "Defines.h"
@@ -58,9 +59,8 @@ void reboot(); uint8_t showBootLogoIfavailable();
// delay wrapper for delay using the hardware timer (used before RTOS)
void delay_ms(uint16_t count);
-// Used to allow knowledge of if usb_pd is being used
-uint8_t usb_pd_detect();
-bool getHallSensorFitted();
+// Probe if the Hall sensor is fitted to the unit
+bool getHallSensorFitted();
// If the iron has a hall effect sensor in the handle, return an signed count of the reading
// If the sensor is single polarity (or polarity insensitive) just return 0..32768
int16_t getRawHallEffect();
diff --git a/source/Core/BSP/BSP_PD.h b/source/Core/BSP/BSP_PD.h index a0dde7c2..4848bdde 100644 --- a/source/Core/BSP/BSP_PD.h +++ b/source/Core/BSP/BSP_PD.h @@ -8,5 +8,8 @@ #ifndef USER_BSP_PD_H_
#define USER_BSP_PD_H_
#include "BSP.h"
-
+bool fusb_write_buf(const uint8_t deviceAddr, const uint8_t registerAdd, const uint8_t size, uint8_t *buf);
+bool fusb_read_buf(const uint8_t deviceAddr, const uint8_t registerAdd, const uint8_t size, uint8_t *buf);
+void setupFUSBIRQ();
+bool getFUS302IRQLow();
#endif /* USER_BSP_PD_H_ */
diff --git a/source/Core/BSP/MHP30/IRQ.cpp b/source/Core/BSP/MHP30/IRQ.cpp index 70a2eb79..b6a574f0 100644 --- a/source/Core/BSP/MHP30/IRQ.cpp +++ b/source/Core/BSP/MHP30/IRQ.cpp @@ -7,7 +7,7 @@ #include "IRQ.h"
#include "Pins.h"
-#include "int_n.h"
+#include "configuration.h"
/*
* Catch the IRQ that says that the conversion is done on the temperature
@@ -34,13 +34,22 @@ void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c __unused) { FRToSI2C::CpltCal void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c __unused) { FRToSI2C::CpltCallback(); }
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c __unused) { FRToSI2C::CpltCallback(); }
-void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
+extern osThreadId POWTaskHandle;
+void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
(void)GPIO_Pin;
- InterruptHandler::irqCallback();
+ // Notify POW thread that an irq occured
+ if (POWTaskHandle != nullptr) {
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ xTaskNotifyFromISR(POWTaskHandle, 1, eSetBits, &xHigherPriorityTaskWoken);
+ /* Force a context switch if xHigherPriorityTaskWoken is now set to pdTRUE.
+ The macro used to do this is dependent on the port and may be called
+ portEND_SWITCHING_ISR. */
+ portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
+ }
}
bool getFUS302IRQLow() {
-#ifdef POW_PD
+#if POW_PD
// Return true if the IRQ line is still held low
return HAL_GPIO_ReadPin(INT_PD_GPIO_Port, INT_PD_Pin) == GPIO_PIN_RESET;
#else
diff --git a/source/Core/BSP/MHP30/Power.cpp b/source/Core/BSP/MHP30/Power.cpp index 80455d2b..661a4bb4 100644 --- a/source/Core/BSP/MHP30/Power.cpp +++ b/source/Core/BSP/MHP30/Power.cpp @@ -3,42 +3,17 @@ #include "Pins.h" #include "QC3.h" #include "Settings.h" +#include "USBPD.h" #include "configuration.h" -#include "fusb_user.h" -#include "fusbpd.h" -#include "int_n.h" -#include "policy_engine.h" -bool FUSB302_present = false; -bool FUSB302_probed = false; void power_check() { -#ifdef POW_PD - if (FUSB302_present) { - PolicyEngine::PPSTimerCallback(); - // Cant start QC until either PD works or fails - if (PolicyEngine::setupCompleteOrTimedOut(getSettingValue(SettingsOptions::PDNegTimeout)) == false) { - return; - } - if (PolicyEngine::pdHasNegotiated()) { - return; - } - } -#endif -#ifdef POW_QC - QC_resync(); -#endif -} -uint8_t usb_pd_detect() { -#ifdef POW_PD - if (FUSB302_probed) { - return FUSB302_present; - } else { - FUSB302_present = fusb302_detect(); - FUSB302_probed = true; +#if POW_PD + + // Cant start QC until either PD works or fails + if (USBPowerDelivery::negotiationComplete()) { + return; } - return FUSB302_present; #endif - return false; } bool getIsPoweredByDCIN() { return false; } diff --git a/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc.h b/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc.h index 72dd294f..b433b7db 100644 --- a/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc.h +++ b/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc.h @@ -1,22 +1,22 @@ /**
- ******************************************************************************
- * @file stm32f1xx_hal_adc.h
- * @author MCD Application Team
- * @brief Header file containing functions prototypes of ADC HAL library.
- ******************************************************************************
- * @attention
- *
- *
- * <h2><center>© Copyright (c) 2016 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * This software component is licensed by ST under BSD 3-Clause license,
- * the "License"; You may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- * opensource.org/licenses/BSD-3-Clause
- *
- ******************************************************************************
- */
+******************************************************************************
+* @file stm32f1xx_hal_adc.h
+* @author MCD Application Team
+* @brief Header file containing functions prototypes of ADC HAL library.
+******************************************************************************
+* @attention
+*
+*
+* <h2><center>© Copyright (c) 2016 STMicroelectronics.
+* All rights reserved.</center></h2>
+*
+* This software component is licensed by ST under BSD 3-Clause license,
+* the "License"; You may not use this file except in compliance with the
+* License. You may obtain a copy of the License at:
+* opensource.org/licenses/BSD-3-Clause
+*
+******************************************************************************
+*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F1xx_HAL_ADC_H
diff --git a/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc_ex.h b/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc_ex.h index 3b8e19d6..ddf361b7 100644 --- a/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc_ex.h +++ b/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc_ex.h @@ -1,21 +1,21 @@ /**
- ******************************************************************************
- * @file stm32f1xx_hal_adc_ex.h
- * @author MCD Application Team
- * @brief Header file of ADC HAL extension module.
- ******************************************************************************
- * @attention
- *
- * <h2><center>© Copyright (c) 2016 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * This software component is licensed by ST under BSD 3-Clause license,
- * the "License"; You may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- * opensource.org/licenses/BSD-3-Clause
- *
- ******************************************************************************
- */
+******************************************************************************
+* @file stm32f1xx_hal_adc_ex.h
+* @author MCD Application Team
+* @brief Header file of ADC HAL extension module.
+******************************************************************************
+* @attention
+*
+* <h2><center>© Copyright (c) 2016 STMicroelectronics.
+* All rights reserved.</center></h2>
+*
+* This software component is licensed by ST under BSD 3-Clause license,
+* the "License"; You may not use this file except in compliance with the
+* License. You may obtain a copy of the License at:
+* opensource.org/licenses/BSD-3-Clause
+*
+******************************************************************************
+*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F1xx_HAL_ADC_EX_H
diff --git a/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h b/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h index ea9b60f0..188b8d9f 100644 --- a/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h +++ b/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h @@ -1,21 +1,21 @@ /**
- ******************************************************************************
- * @file stm32f1xx_hal_cortex.h
- * @author MCD Application Team
- * @brief Header file of CORTEX HAL module.
- ******************************************************************************
- * @attention
- *
- * <h2><center>© Copyright (c) 2017 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * This software component is licensed by ST under BSD 3-Clause license,
- * the "License"; You may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- * opensource.org/licenses/BSD-3-Clause
- *
- ******************************************************************************
- */
+******************************************************************************
+* @file stm32f1xx_hal_cortex.h
+* @author MCD Application Team
+* @brief Header file of CORTEX HAL module.
+******************************************************************************
+* @attention
+*
+* <h2><center>© Copyright (c) 2017 STMicroelectronics.
+* All rights reserved.</center></h2>
+*
+* This software component is licensed by ST under BSD 3-Clause license,
+* the "License"; You may not use this file except in compliance with the
+* License. You may obtain a copy of the License at:
+* opensource.org/licenses/BSD-3-Clause
+*
+******************************************************************************
+*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F1xx_HAL_CORTEX_H
diff --git a/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h b/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h index ab865d8c..885f116d 100644 --- a/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h +++ b/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h @@ -1,22 +1,22 @@ /**
- ******************************************************************************
- * @file stm32f1xx_hal_def.h
- * @author MCD Application Team
- * @brief This file contains HAL common defines, enumeration, macros and
- * structures definitions.
- ******************************************************************************
- * @attention
- *
- * <h2><center>© Copyright (c) 2017 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * This software component is licensed by ST under BSD 3-Clause license,
- * the "License"; You may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- * opensource.org/licenses/BSD-3-Clause
- *
- ******************************************************************************
- */
+******************************************************************************
+* @file stm32f1xx_hal_def.h
+* @author MCD Application Team
+* @brief This file contains HAL common defines, enumeration, macros and
+* structures definitions.
+******************************************************************************
+* @attention
+*
+* <h2><center>© Copyright (c) 2017 STMicroelectronics.
+* All rights reserved.</center></h2>
+*
+* This software component is licensed by ST under BSD 3-Clause license,
+* the "License"; You may not use this file except in compliance with the
+* License. You may obtain a copy of the License at:
+* opensource.org/licenses/BSD-3-Clause
+*
+******************************************************************************
+*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F1xx_HAL_DEF
diff --git a/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h b/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h index aba2ad04..8a7b3d5d 100644 --- a/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h +++ b/source/Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h @@ -1,21 +1,21 @@ /**
- ******************************************************************************
- * @file stm32f1xx_hal_dma_ex.h
- * @author MCD Application Team
- * @brief Header file of DMA HAL extension module.
- ******************************************************************************
- * @attention
- *
- * <h2><center>© Copyright (c) 2016 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * This software component is licensed by ST under BSD 3-Clause license,
- * the "License"; You may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- * opensource.org/licenses/BSD-3-Clause
- *
- ******************************************************************************
- */
+******************************************************************************
+* @file stm32f1xx_hal_dma_ex.h
+* @author MCD Application Team
+* @brief Header file of DMA HAL extension module.
+******************************************************************************
+* @attention
+*
+* <h2><center>© Copyright (c) 2016 STMicroelectronics.
+* All rights reserved.</center></h2>
+*
+* This software component is licensed by ST under BSD 3-Clause license,
+* the "License"; You may not use this file except in compliance with the
+* License. You may obtain a copy of the License at:
+* opensource.org/licenses/BSD-3-Clause
+*
+******************************************************************************
+*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F1xx_HAL_DMA_EX_H
diff --git a/source/Core/BSP/MHP30/configuration.h b/source/Core/BSP/MHP30/configuration.h index 21e39fd9..989f518d 100644 --- a/source/Core/BSP/MHP30/configuration.h +++ b/source/Core/BSP/MHP30/configuration.h @@ -138,7 +138,7 @@ #define NO_DISPLAY_ROTATE // Disable OLED rotation by accel #define SLEW_LIMIT 50 // Limit to 3.0 Watts per 64ms pid loop update rate slew rate #define ACCEL_MSA -#define POW_PD +#define POW_PD 1 #define TEMP_NTC #define I2C_SOFT #define BATTFILTERDEPTH 8 @@ -147,7 +147,7 @@ #define HARDWARE_MAX_WATTAGE_X10 650 #define TIP_THERMAL_MASS 65 // TODO, needs refinement -#define tipResistance 60 // x10 ohms, ~6 typical +#define TIP_RESISTANCE 60 // x10 ohms, ~6 typical #endif #ifdef ACCEL_EXITS_ON_MOVEMENT diff --git a/source/Core/BSP/MHP30/fusb_user.cpp b/source/Core/BSP/MHP30/fusb_user.cpp index e3dfa13c..5e0c3f55 100644 --- a/source/Core/BSP/MHP30/fusb_user.cpp +++ b/source/Core/BSP/MHP30/fusb_user.cpp @@ -1,20 +1,13 @@ #include "configuration.h" -#ifdef POW_PD +#if POW_PD #include "BSP.h" #include "I2C_Wrapper.hpp" #include "Pins.h" #include "Setup.h" -#include "fusb302b.h" -#include "fusb_user.h" +#include "USBPD.h" +bool fusb_read_buf(const uint8_t deviceAddr, const uint8_t registerAdd, const uint8_t size, uint8_t *buf) { return FRToSI2C::Mem_Read(deviceAddr, registerAdd, buf, size); } -bool fusb_read_buf(uint8_t addr, uint8_t size, uint8_t *buf) { return FRToSI2C::Mem_Read(FUSB302B_ADDR, addr, buf, size); } - -bool fusb_write_buf(uint8_t addr, uint8_t size, const uint8_t *buf) { return FRToSI2C::Mem_Write(FUSB302B_ADDR, addr, (uint8_t *)buf, size); } - -bool fusb302_detect() { - // Probe the I2C bus for its address - return FRToSI2C::probe(FUSB302B_ADDR); -} +bool fusb_write_buf(const uint8_t deviceAddr, const uint8_t registerAdd, const uint8_t size, uint8_t *buf) { return FRToSI2C::Mem_Write(deviceAddr, registerAdd, (uint8_t *)buf, size); } void setupFUSBIRQ() { GPIO_InitTypeDef GPIO_InitStruct; diff --git a/source/Core/BSP/MHP30/postRTOS.cpp b/source/Core/BSP/MHP30/postRTOS.cpp index 2daab8b6..bd4dc5d1 100644 --- a/source/Core/BSP/MHP30/postRTOS.cpp +++ b/source/Core/BSP/MHP30/postRTOS.cpp @@ -4,7 +4,6 @@ #include "QC3.h" #include "Settings.h" #include "cmsis_os.h" -#include "fusbpd.h" #include "main.hpp" #include "power.hpp" #include "stdlib.h" diff --git a/source/Core/BSP/MHP30/preRTOS.cpp b/source/Core/BSP/MHP30/preRTOS.cpp index 7efd4da8..f5fe84ae 100644 --- a/source/Core/BSP/MHP30/preRTOS.cpp +++ b/source/Core/BSP/MHP30/preRTOS.cpp @@ -9,8 +9,6 @@ #include "I2CBB.hpp"
#include "Pins.h"
#include "Setup.h"
-#include "configuration.h"
-#include "fusbpd.h"
#include <I2C_Wrapper.hpp>
void preRToSInit() {
diff --git a/source/Core/BSP/Miniware/IRQ.cpp b/source/Core/BSP/Miniware/IRQ.cpp index 5afa4bf1..3240716f 100644 --- a/source/Core/BSP/Miniware/IRQ.cpp +++ b/source/Core/BSP/Miniware/IRQ.cpp @@ -7,7 +7,7 @@ #include "IRQ.h"
#include "Pins.h"
-#include "int_n.h"
+#include "configuration.h"
/*
* Catch the IRQ that says that the conversion is done on the temperature
@@ -30,13 +30,23 @@ void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c __unused) { FRToSI2C::CpltCal void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c __unused) { FRToSI2C::CpltCallback(); }
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c __unused) { FRToSI2C::CpltCallback(); }
+extern osThreadId POWTaskHandle;
+
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
(void)GPIO_Pin;
- InterruptHandler::irqCallback();
+ // Notify POW thread that an irq occured
+ if (POWTaskHandle != nullptr) {
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ xTaskNotifyFromISR(POWTaskHandle, 1, eSetBits, &xHigherPriorityTaskWoken);
+ /* Force a context switch if xHigherPriorityTaskWoken is now set to pdTRUE.
+ The macro used to do this is dependent on the port and may be called
+ portEND_SWITCHING_ISR. */
+ portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
+ }
}
bool getFUS302IRQLow() {
-#ifdef POW_PD
+#if POW_PD
// Return true if the IRQ line is still held low
return HAL_GPIO_ReadPin(INT_PD_GPIO_Port, INT_PD_Pin) == GPIO_PIN_RESET;
#else
diff --git a/source/Core/BSP/Miniware/Pins.h b/source/Core/BSP/Miniware/Pins.h index e8851d26..079c9049 100644 --- a/source/Core/BSP/Miniware/Pins.h +++ b/source/Core/BSP/Miniware/Pins.h @@ -78,8 +78,6 @@ #define SCL2_GPIO_Port GPIOA
#define SDA2_Pin GPIO_PIN_1
#define SDA2_GPIO_Port GPIOA
-#define INT_PD_Pin GPIO_PIN_9
-#define INT_PD_GPIO_Port GPIOA
#endif
#ifdef MODEL_TS80P
diff --git a/source/Core/BSP/Miniware/Power.cpp b/source/Core/BSP/Miniware/Power.cpp index 5aa42b42..b72d984b 100644 --- a/source/Core/BSP/Miniware/Power.cpp +++ b/source/Core/BSP/Miniware/Power.cpp @@ -3,43 +3,23 @@ #include "Pins.h" #include "QC3.h" #include "Settings.h" +#include "USBPD.h" #include "configuration.h" -#include "fusb_user.h" -#include "fusbpd.h" -#include "int_n.h" -#include "policy_engine.h" -bool FUSB302_present = false; -bool FUSB302_probed = false; void power_check() { -#ifdef POW_PD - if (FUSB302_present) { - PolicyEngine::PPSTimerCallback(); - // Cant start QC until either PD works or fails - if (PolicyEngine::setupCompleteOrTimedOut(getSettingValue(SettingsOptions::PDNegTimeout)) == false) { - return; - } - if (PolicyEngine::pdHasNegotiated()) { - return; - } +#if POW_PD + // Cant start QC until either PD works or fails + if (!USBPowerDelivery::negotiationComplete()) { + return; + } + if (USBPowerDelivery::negotiationHasWorked()) { + return; // We are using PD } #endif #ifdef POW_QC QC_resync(); #endif } -uint8_t usb_pd_detect() { -#ifdef POW_PD - if (FUSB302_probed) { - return FUSB302_present; - } else { - FUSB302_present = fusb302_detect(); - FUSB302_probed = true; - } - return FUSB302_present; -#endif - return false; -} bool getIsPoweredByDCIN() { #ifdef MODEL_TS80 diff --git a/source/Core/BSP/Miniware/Software_I2C.h b/source/Core/BSP/Miniware/Software_I2C.h index ceca0131..5b2924ab 100644 --- a/source/Core/BSP/Miniware/Software_I2C.h +++ b/source/Core/BSP/Miniware/Software_I2C.h @@ -20,11 +20,12 @@ #define SOFT_SCL_READ() (HAL_GPIO_ReadPin(SCL2_GPIO_Port, SCL2_Pin) == GPIO_PIN_SET ? 1 : 0)
#define SOFT_I2C_DELAY() \
{ \
- for (int xx = 0; xx < 40; xx++) { \
+ for (int xx = 0; xx < 15; xx++) { \
asm("nop"); \
} \
}
#endif
+// 40 ~= 100kHz; 15 gives around 250kHz or so which is fast _and_ stable
#endif /* BSP_MINIWARE_SOFTWARE_I2C_H_ */
diff --git a/source/Core/BSP/Miniware/configuration.h b/source/Core/BSP/Miniware/configuration.h index 427569df..948bf173 100644 --- a/source/Core/BSP/Miniware/configuration.h +++ b/source/Core/BSP/Miniware/configuration.h @@ -144,6 +144,7 @@ #define MIN_BOOST_TEMP_F 480 // The min settable temp for boost mode °F #define POW_DC #define ACCEL_MMA +#define POW_PD 0 #define ACCEL_LIS #define TEMP_TMP36 #endif @@ -168,6 +169,7 @@ #define MIN_BOOST_TEMP_F 480 // The min settable temp for boost mode °F #define ACCEL_LIS #define POW_QC +#define POW_PD 0 #define TEMP_TMP36 #define LIS_ORI_FLIP #define OLED_FLIP @@ -193,8 +195,8 @@ #define MIN_BOOST_TEMP_F 480 // The min settable temp for boost mode °F #define ACCEL_LIS #define ACCEL_MSA -#define POW_PD -#define POW_QC +#define POW_PD 1 +#define POW_QC 1 #define TEMP_NTC #define I2C_SOFT #define LIS_ORI_FLIP @@ -204,18 +206,18 @@ #ifdef MODEL_TS100 #define HARDWARE_MAX_WATTAGE_X10 750 #define TIP_THERMAL_MASS 65 // X10 watts to raise 1 deg C in 1 second -#define tipResistance 75 // x10 ohms, 7.5 typical for ts100 tips +#define TIP_RESISTANCE 75 // x10 ohms, 7.5 typical for ts100 tips #endif #ifdef MODEL_TS80 #define HARDWARE_MAX_WATTAGE_X10 180 #define TIP_THERMAL_MASS 40 -#define tipResistance 45 // x10 ohms, 4.5 typical for ts80 tips +#define TIP_RESISTANCE 45 // x10 ohms, 4.5 typical for ts80 tips #endif #ifdef MODEL_TS80P #define HARDWARE_MAX_WATTAGE_X10 300 #define TIP_THERMAL_MASS 40 -#define tipResistance 45 // x10 ohms, 4.5 typical for ts80 tips +#define TIP_RESISTANCE 45 // x10 ohms, 4.5 typical for ts80 tips #endif #endif diff --git a/source/Core/BSP/Miniware/fusb_user.cpp b/source/Core/BSP/Miniware/fusb_user.cpp index 13454db7..8c007e9b 100644 --- a/source/Core/BSP/Miniware/fusb_user.cpp +++ b/source/Core/BSP/Miniware/fusb_user.cpp @@ -1,43 +1,20 @@ #include "configuration.h" -#ifdef POW_PD +#if POW_PD #include "BSP.h" #include "I2CBB.hpp" #include "Setup.h" -#include "fusb302b.h" -#include "fusb_user.h" -/* - * Read multiple bytes from the FUSB302B - * - * cfg: The FUSB302B to communicate with - * addr: The memory address from which to read - * size: The number of bytes to read - * buf: The buffer into which data will be read - */ -bool fusb_read_buf(uint8_t addr, uint8_t size, uint8_t *buf) { return I2CBB::Mem_Read(FUSB302B_ADDR, addr, buf, size); } +bool fusb_read_buf(const uint8_t deviceAddr, const uint8_t registerAdd, const uint8_t size, uint8_t *buf) { return I2CBB::Mem_Read(deviceAddr, registerAdd, buf, size); } -/* - * Write multiple bytes to the FUSB302B - * - * cfg: The FUSB302B to communicate with - * addr: The memory address to which we will write - * size: The number of bytes to write - * buf: The buffer to write - */ -bool fusb_write_buf(uint8_t addr, uint8_t size, const uint8_t *buf) { return I2CBB::Mem_Write(FUSB302B_ADDR, addr, buf, size); } - -bool fusb302_detect() { - // Probe the I2C bus for its address - return I2CBB::probe(FUSB302B_ADDR); -} +bool fusb_write_buf(const uint8_t deviceAddr, const uint8_t registerAdd, const uint8_t size, uint8_t *buf) { return I2CBB::Mem_Write(deviceAddr, registerAdd, buf, size); } void setupFUSBIRQ() { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - GPIO_InitStruct.Pin = GPIO_PIN_9; + GPIO_InitStruct.Pin = INT_PD_Pin; GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; GPIO_InitStruct.Pull = GPIO_PULLUP; - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + HAL_GPIO_Init(INT_PD_GPIO_Port, &GPIO_InitStruct); HAL_NVIC_SetPriority(EXTI9_5_IRQn, 10, 0); HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); } diff --git a/source/Core/BSP/Miniware/postRTOS.cpp b/source/Core/BSP/Miniware/postRTOS.cpp index 2daab8b6..4882cdf6 100644 --- a/source/Core/BSP/Miniware/postRTOS.cpp +++ b/source/Core/BSP/Miniware/postRTOS.cpp @@ -1,14 +1,4 @@ #include "BSP.h" -#include "FreeRTOS.h" -#include "I2C_Wrapper.hpp" -#include "QC3.h" -#include "Settings.h" -#include "cmsis_os.h" -#include "fusbpd.h" -#include "main.hpp" -#include "power.hpp" -#include "stdlib.h" -#include "task.h" // Initialisation to be performed with scheduler active void postRToSInit() {} diff --git a/source/Core/BSP/Miniware/preRTOS.cpp b/source/Core/BSP/Miniware/preRTOS.cpp index 931df14e..f355984e 100644 --- a/source/Core/BSP/Miniware/preRTOS.cpp +++ b/source/Core/BSP/Miniware/preRTOS.cpp @@ -9,8 +9,6 @@ #include "I2CBB.hpp"
#include "Pins.h"
#include "Setup.h"
-#include "configuration.h"
-#include "fusbpd.h"
#include <I2C_Wrapper.hpp>
void preRToSInit() {
diff --git a/source/Core/BSP/Pine64/Debug.cpp b/source/Core/BSP/Pine64/Debug.cpp index 3cb296be..c9d5d3bf 100644 --- a/source/Core/BSP/Pine64/Debug.cpp +++ b/source/Core/BSP/Pine64/Debug.cpp @@ -5,8 +5,11 @@ * Author: Ralim
*/
#include "Debug.h"
+#include "FreeRTOS.h"
#include "Pins.h"
+
extern "C" {
+
#include "gd32vf103_usart.h"
}
char uartOutputBuffer[uartOutputBufferLength];
@@ -34,7 +37,18 @@ void log_system_state(int32_t PWMWattsx10) { usart_interrupt_enable(UART_PERIF, USART_INT_TBE);
}
}
-
+ssize_t _write(int fd, const void *ptr, size_t len) {
+ if (len > uartOutputBufferLength) {
+ len = uartOutputBufferLength;
+ }
+ outputLength = len;
+ currentOutputPos = 0;
+ memcpy(uartOutputBuffer, ptr, len);
+ /* enable USART1 Transmit Buffer Empty interrupt */
+ usart_interrupt_enable(UART_PERIF, USART_INT_TBE);
+ delay_ms(1);
+ return len;
+}
void USART1_IRQHandler(void) {
if (RESET != usart_interrupt_flag_get(UART_PERIF, USART_INT_FLAG_TBE)) {
/* write one byte to the transmit data register */
diff --git a/source/Core/BSP/Pine64/Debug.h b/source/Core/BSP/Pine64/Debug.h index a9a60ec2..5c95a132 100644 --- a/source/Core/BSP/Pine64/Debug.h +++ b/source/Core/BSP/Pine64/Debug.h @@ -16,7 +16,7 @@ const unsigned int uartOutputBufferLength = 32;
extern char uartOutputBuffer[uartOutputBufferLength];
extern "C" {
-
-void USART1_IRQHandler(void);
+ssize_t _write(int fd, const void *ptr, size_t len);
+void USART1_IRQHandler(void);
}
#endif /* CORE_BSP_PINE64_DEBUG_H_ */
diff --git a/source/Core/BSP/Pine64/FreeRTOSConfig.h b/source/Core/BSP/Pine64/FreeRTOSConfig.h index 79fed319..91a5e4b6 100644 --- a/source/Core/BSP/Pine64/FreeRTOSConfig.h +++ b/source/Core/BSP/Pine64/FreeRTOSConfig.h @@ -2,9 +2,6 @@ #define FREERTOS_CONFIG_H #include "nuclei_sdk_soc.h" #include <stdint.h> -// RISC-V configuration -#define USER_MODE_TASKS 0 - #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configUSE_TICKLESS_IDLE 0 @@ -25,7 +22,6 @@ #define configUSE_TIME_SLICING 1 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 0 -#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 #define INCLUDE_uxTaskGetStackHighWaterMark 1 #define INCLUDE_xTaskGetSchedulerState 1 @@ -39,7 +35,7 @@ /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 1 #define configUSE_TICK_HOOK 0 -#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_FOR_STACK_OVERFLOW 1 #define configUSE_MALLOC_FAILED_HOOK 0 #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 diff --git a/source/Core/BSP/Pine64/I2C_Wrapper.cpp b/source/Core/BSP/Pine64/I2C_Wrapper.cpp index 04d1e288..f54e0a42 100644 --- a/source/Core/BSP/Pine64/I2C_Wrapper.cpp +++ b/source/Core/BSP/Pine64/I2C_Wrapper.cpp @@ -8,6 +8,7 @@ #include "IRQ.h"
#include "Setup.h"
#include <I2C_Wrapper.hpp>
+
SemaphoreHandle_t FRToSI2C::I2CSemaphore = nullptr;
StaticSemaphore_t FRToSI2C::xSemaphoreBuffer;
#define I2C_TIME_OUT (uint16_t)(12000)
@@ -23,7 +24,7 @@ uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg) { return temp;
}
-enum i2c_step {
+enum class i2c_step {
// Write+read steps
Write_start, // Sending start on bus
Write_device_address, // start sent, send device address
@@ -51,32 +52,20 @@ struct i2c_state { uint16_t numberOfBytes;
dma_parameter_struct dma_init_struct;
};
-volatile i2c_state currentState;
+i2c_state currentState;
void perform_i2c_step() {
// Performs next step of the i2c state machine
if (i2c_flag_get(I2C0, I2C_FLAG_AERR)) {
i2c_flag_clear(I2C0, I2C_FLAG_AERR);
// Arb error - we lost the bus / nacked
- currentState.currentStep = Error_occured;
- } else if (i2c_flag_get(I2C0, I2C_FLAG_BERR)) {
- i2c_flag_clear(I2C0, I2C_FLAG_BERR);
- // Bus Error
- currentState.currentStep = Error_occured;
- } else if (i2c_flag_get(I2C0, I2C_FLAG_LOSTARB)) {
- i2c_flag_clear(I2C0, I2C_FLAG_LOSTARB);
- // Bus Error
- currentState.currentStep = Error_occured;
- } else if (i2c_flag_get(I2C0, I2C_FLAG_PECERR)) {
- i2c_flag_clear(I2C0, I2C_FLAG_PECERR);
- // Bus Error
- currentState.currentStep = Error_occured;
+ currentState.currentStep = i2c_step::Error_occured;
}
switch (currentState.currentStep) {
- case Error_occured:
+ case i2c_step::Error_occured:
i2c_stop_on_bus(I2C0);
break;
- case Write_start:
+ case i2c_step::Write_start:
/* enable acknowledge */
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
@@ -84,133 +73,177 @@ void perform_i2c_step() { if (!i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) {
/* send the start signal */
i2c_start_on_bus(I2C0);
- currentState.currentStep = Write_device_address;
+ currentState.currentStep = i2c_step::Write_device_address;
}
break;
- case Write_device_address:
+ case i2c_step::Write_device_address:
/* i2c master sends START signal successfully */
if (i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) {
- i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
+ i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); // Clear sbsend by reading ctrl banks
i2c_master_addressing(I2C0, currentState.deviceAddress, I2C_TRANSMITTER);
- currentState.currentStep = Write_device_memory_address;
+ currentState.currentStep = i2c_step::Write_device_memory_address;
}
break;
- case Write_device_memory_address:
+ case i2c_step::Write_device_memory_address:
// Send the device memory location
if (i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) { // addr sent
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
- if (i2c_flag_get(I2C0, I2C_FLAG_BERR)) {
- i2c_flag_clear(I2C0, I2C_FLAG_BERR);
- // Bus Error
- currentState.currentStep = Error_occured;
- } else if (i2c_flag_get(I2C0, I2C_FLAG_AERR)) {
- i2c_flag_clear(I2C0, I2C_FLAG_AERR);
- // Arb error - we lost the bus / nacked
- currentState.currentStep = Error_occured;
- } else if (currentState.wakePart) {
+ if (currentState.wakePart) {
// We are stopping here
- currentState.currentStep = Send_stop;
- } else if (i2c_flag_get(I2C0, I2C_FLAG_TBE)) {
- // Write out the 8 byte address
- i2c_data_transmit(I2C0, currentState.memoryAddress);
-
- if (currentState.isMemoryWrite) {
- currentState.currentStep = Write_device_data_start;
- } else {
- currentState.currentStep = Read_start;
- }
+ currentState.currentStep = i2c_step::Send_stop;
+ return;
+ }
+ i2c_flag_clear(I2C0, I2C_FLAG_BTC);
+ // Write out the 8 byte address
+ i2c_data_transmit(I2C0, currentState.memoryAddress);
+ if (currentState.isMemoryWrite) {
+ currentState.currentStep = i2c_step::Write_device_data_start;
+ } else {
+ currentState.currentStep = i2c_step::Read_start;
}
}
break;
- case Write_device_data_start:
-
- /* wait until BTC bit is set */
+ case i2c_step::Write_device_data_start:
+ /* wait until the transmission data register is empty */
if (i2c_flag_get(I2C0, I2C_FLAG_BTC)) {
+ dma_deinit(DMA0, DMA_CH5);
+ dma_init(DMA0, DMA_CH5, ¤tState.dma_init_struct);
+ i2c_dma_last_transfer_config(I2C0, I2C_DMALST_ON);
+ dma_circulation_disable(DMA0, DMA_CH5);
/* enable I2C0 DMA */
i2c_dma_enable(I2C0, I2C_DMA_ON);
/* enable DMA0 channel5 */
dma_channel_enable(DMA0, DMA_CH5);
- currentState.currentStep = Write_device_data_finish;
+ currentState.currentStep = i2c_step::Write_device_data_finish;
}
break;
- case Write_device_data_finish: // Wait for complete then goto stop
+ case i2c_step::Write_device_data_finish: // Wait for complete then goto stop
/* wait until BTC bit is set */
if (dma_flag_get(DMA0, DMA_CH5, DMA_FLAG_FTF)) {
/* wait until BTC bit is set */
if (i2c_flag_get(I2C0, I2C_FLAG_BTC)) {
- currentState.currentStep = Send_stop;
+ currentState.currentStep = i2c_step::Send_stop;
}
}
break;
- case Read_start:
- /* wait until BTC bit is set */
+ case i2c_step::Read_start:
if (i2c_flag_get(I2C0, I2C_FLAG_BTC)) {
+ /* wait until BTC bit is set */
i2c_start_on_bus(I2C0);
- currentState.currentStep = Read_device_address;
+ currentState.currentStep = i2c_step::Read_device_address;
}
break;
- case Read_device_address:
+ case i2c_step::Read_device_address:
if (i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) {
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
- i2c_master_addressing(I2C0, currentState.deviceAddress, I2C_RECEIVER);
- currentState.currentStep = Read_device_data_start;
+ if (currentState.numberOfBytes == 1) {
+ /* disable acknowledge */
+ i2c_master_addressing(I2C0, currentState.deviceAddress, I2C_RECEIVER);
+ while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {}
+ i2c_ack_config(I2C0, I2C_ACK_DISABLE);
+ i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
+ /* wait for the byte to be received */
+ while (!i2c_flag_get(I2C0, I2C_FLAG_RBNE)) {}
+ /* read the byte received from the EEPROM */
+ *currentState.buffer = i2c_data_receive(I2C0);
+ while (i2c_flag_get(I2C0, I2C_FLAG_RBNE)) {
+ i2c_data_receive(I2C0);
+ }
+ i2c_stop_on_bus(I2C0);
+ while ((I2C_CTL0(I2C0) & I2C_CTL0_STOP)) {
+ asm("nop");
+ }
+ currentState.currentStep = i2c_step::Done;
+ } else if (currentState.numberOfBytes == 2) {
+ /* disable acknowledge */
+ i2c_master_addressing(I2C0, currentState.deviceAddress, I2C_RECEIVER);
+ while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {}
+ i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
+ /* wait for the byte to be received */
+ while (!i2c_flag_get(I2C0, I2C_FLAG_RBNE)) {}
+ i2c_ackpos_config(I2C0, I2C_ACKPOS_CURRENT);
+ i2c_ack_config(I2C0, I2C_ACK_DISABLE);
+
+ /* read the byte received from the EEPROM */
+ *currentState.buffer = i2c_data_receive(I2C0);
+ currentState.buffer++;
+
+ /* wait for the byte to be received */
+ while (!i2c_flag_get(I2C0, I2C_FLAG_RBNE)) {}
+ /* read the byte received from the EEPROM */
+ *currentState.buffer = i2c_data_receive(I2C0);
+ while (i2c_flag_get(I2C0, I2C_FLAG_RBNE)) {
+ i2c_data_receive(I2C0);
+ }
+ i2c_stop_on_bus(I2C0);
+ while ((I2C_CTL0(I2C0) & I2C_CTL0_STOP)) {
+ asm("nop");
+ }
+ currentState.currentStep = i2c_step::Done;
+ } else {
+ i2c_master_addressing(I2C0, currentState.deviceAddress, I2C_RECEIVER);
+ currentState.currentStep = i2c_step::Read_device_data_start;
+ }
}
break;
- case Read_device_data_start:
+ case i2c_step::Read_device_data_start:
if (i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) { // addr sent
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
- if (i2c_flag_get(I2C0, I2C_FLAG_AERR)) {
- // Arb error - we lost the bus / nacked
- currentState.currentStep = Error_occured;
- }
/* one byte master reception procedure (polling) */
if (currentState.numberOfBytes == 0) {
- currentState.currentStep = Send_stop;
- } else if (currentState.numberOfBytes == 1) {
- /* disable acknowledge */
- i2c_ack_config(I2C0, I2C_ACK_DISABLE);
- /* clear ADDSEND register by reading I2C_STAT0 then I2C_STAT1 register
- * (I2C_STAT0 has already been read) */
- i2c_flag_get(I2C0, I2C_FLAG_ADDSEND); // sat0
- i2c_flag_get(I2C0, I2C_FLAG_I2CBSY); // sat1
- /* send a stop condition to I2C bus*/
- i2c_stop_on_bus(I2C0);
- /* wait for the byte to be received */
- while (!i2c_flag_get(I2C0, I2C_FLAG_RBNE))
- ;
- /* read the byte received from the EEPROM */
- *currentState.buffer = i2c_data_receive(I2C0);
- currentState.currentStep = Wait_stop;
+ currentState.currentStep = i2c_step::Send_stop;
} else { /* more than one byte master reception procedure (DMA) */
- /* enable I2C0 DMA */
- i2c_dma_enable(I2C0, I2C_DMA_ON);
- /* enable DMA0 channel5 */
- dma_channel_enable(DMA0, DMA_CH6);
- currentState.currentStep = Read_device_data_finish;
+
+ while (currentState.numberOfBytes) {
+
+ if (3 == currentState.numberOfBytes) {
+ /* wait until BTC bit is set */
+ while (!i2c_flag_get(I2C0, I2C_FLAG_BTC)) {}
+ i2c_ackpos_config(I2C0, I2C_ACKPOS_CURRENT);
+ /* disable acknowledge */
+ i2c_ack_config(I2C0, I2C_ACK_DISABLE);
+ } else if (2 == currentState.numberOfBytes) {
+ /* wait until BTC bit is set */
+ while (!i2c_flag_get(I2C0, I2C_FLAG_BTC)) {}
+ /* disable acknowledge */
+ i2c_ack_config(I2C0, I2C_ACK_DISABLE);
+ /* send a stop condition to I2C bus */
+ i2c_stop_on_bus(I2C0);
+ }
+ /* wait until RBNE bit is set */
+ while (!i2c_flag_get(I2C0, I2C_FLAG_RBNE)) {}
+ /* read a byte from the EEPROM */
+ *currentState.buffer = i2c_data_receive(I2C0);
+
+ /* point to the next location where the byte read will be saved */
+ currentState.buffer++;
+
+ /* decrement the read bytes counter */
+ currentState.numberOfBytes--;
+ }
+ currentState.currentStep = i2c_step::Wait_stop;
+ // currentState.currentStep = i2c_step::Read_device_data_finish;
}
}
break;
- case Read_device_data_finish: // Wait for complete then goto stop
+ case i2c_step::Read_device_data_finish: // Wait for complete then goto stop
/* wait until BTC bit is set */
- if (dma_flag_get(DMA0, DMA_CH6, DMA_FLAG_FTF)) {
- currentState.currentStep = Send_stop;
- }
break;
- case Send_stop:
+ case i2c_step::Send_stop:
/* send a stop condition to I2C bus*/
i2c_stop_on_bus(I2C0);
- currentState.currentStep = Wait_stop;
+ currentState.currentStep = i2c_step::Wait_stop;
break;
- case Wait_stop:
+ case i2c_step::Wait_stop:
/* i2c master sends STOP signal successfully */
- if ((I2C_CTL0(I2C0) & 0x0200) != 0x0200) {
- currentState.currentStep = Done;
+ if ((I2C_CTL0(I2C0) & I2C_CTL0_STOP) != I2C_CTL0_STOP) {
+ currentState.currentStep = i2c_step::Done;
}
break;
default:
@@ -220,16 +253,6 @@ void perform_i2c_step() { }
bool perform_i2c_transaction(uint16_t DevAddress, uint16_t memory_address, uint8_t *p_buffer, uint16_t number_of_byte, bool isWrite, bool isWakeOnly) {
- {
- // TODO is this required
- /* disable I2C0 */
- i2c_disable(I2C0);
- /* enable I2C0 */
- i2c_enable(I2C0);
- }
- i2c_interrupt_disable(I2C0, I2C_INT_ERR);
- i2c_interrupt_disable(I2C0, I2C_INT_BUF);
- i2c_interrupt_disable(I2C0, I2C_INT_EV);
currentState.isMemoryWrite = isWrite;
currentState.wakePart = isWakeOnly;
@@ -237,45 +260,38 @@ bool perform_i2c_transaction(uint16_t DevAddress, uint16_t memory_address, uint8 currentState.memoryAddress = memory_address;
currentState.numberOfBytes = number_of_byte;
currentState.buffer = p_buffer;
- if (!isWakeOnly) {
- // Setup DMA
- currentState.dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
- currentState.dma_init_struct.memory_addr = (uint32_t)p_buffer;
- currentState.dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
- currentState.dma_init_struct.number = number_of_byte;
- currentState.dma_init_struct.periph_addr = (uint32_t)&I2C_DATA(I2C0);
- currentState.dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
- currentState.dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
- currentState.dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
- if (currentState.isMemoryWrite) {
- dma_deinit(DMA0, DMA_CH5);
- currentState.dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
- dma_init(DMA0, DMA_CH5, (dma_parameter_struct *)¤tState.dma_init_struct);
- } else {
- dma_deinit(DMA0, DMA_CH6);
- currentState.dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
- dma_init(DMA0, DMA_CH6, (dma_parameter_struct *)¤tState.dma_init_struct);
- }
+ // Setup DMA
+ currentState.dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
+ currentState.dma_init_struct.memory_addr = (uint32_t)p_buffer;
+ currentState.dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
+ currentState.dma_init_struct.number = number_of_byte;
+ currentState.dma_init_struct.periph_addr = (uint32_t)&I2C_DATA(I2C0);
+ currentState.dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
+ currentState.dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
+ currentState.dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
- if (!currentState.isMemoryWrite) {
- i2c_dma_last_transfer_config(I2C0, I2C_DMALST_ON);
- }
+ if (currentState.isMemoryWrite) {
+ currentState.dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
+ } else {
+ currentState.dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
}
// Clear flags
I2C_STAT0(I2C0) = 0;
I2C_STAT1(I2C0) = 0;
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
-
- currentState.currentStep = Write_start; // Always start in write mode
- TickType_t timeout = xTaskGetTickCount() + TICKS_SECOND;
- while ((currentState.currentStep != Done) && (currentState.currentStep != Error_occured)) {
+ i2c_ackpos_config(I2C0, I2C_ACKPOS_CURRENT);
+ i2c_data_receive(I2C0);
+ i2c_data_receive(I2C0);
+ currentState.currentStep = i2c_step::Write_start; // Always start in write mode
+ TickType_t timeout = xTaskGetTickCount() + TICKS_100MS;
+ while ((currentState.currentStep != i2c_step::Done) && (currentState.currentStep != i2c_step::Error_occured)) {
if (xTaskGetTickCount() > timeout) {
i2c_stop_on_bus(I2C0);
return false;
}
perform_i2c_step();
}
- return currentState.currentStep == Done;
+ return currentState.currentStep == i2c_step::Done;
}
bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t read_address, uint8_t *p_buffer, uint16_t number_of_byte) {
diff --git a/source/Core/BSP/Pine64/IRQ.cpp b/source/Core/BSP/Pine64/IRQ.cpp index e0fff8f4..6aa77aef 100644 --- a/source/Core/BSP/Pine64/IRQ.cpp +++ b/source/Core/BSP/Pine64/IRQ.cpp @@ -7,7 +7,7 @@ #include "IRQ.h"
#include "Pins.h"
-#include "int_n.h"
+#include "configuration.h"
volatile uint8_t i2c_read_process = 0;
volatile uint8_t i2c_write_process = 0;
volatile uint8_t i2c_slave_address = 0;
@@ -90,16 +90,20 @@ void setTipPWM(const uint8_t pulse, const bool shouldUseFastModePWM) { pendingPWM = pulse;
fastPWM = shouldUseFastModePWM;
}
+extern osThreadId POWTaskHandle;
void EXTI5_9_IRQHandler(void) {
-#ifdef POW_PD
+#if POW_PD
if (RESET != exti_interrupt_flag_get(EXTI_5)) {
exti_interrupt_flag_clear(EXTI_5);
- if (RESET == gpio_input_bit_get(FUSB302_IRQ_GPIO_Port, FUSB302_IRQ_Pin)) {
- if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
- InterruptHandler::irqCallback();
- }
+ if (POWTaskHandle != nullptr) {
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ xTaskNotifyFromISR(POWTaskHandle, 1, eSetBits, &xHigherPriorityTaskWoken);
+ /* Force a context switch if xHigherPriorityTaskWoken is now set to pdTRUE.
+ The macro used to do this is dependent on the port and may be called
+ portEND_SWITCHING_ISR. */
+ portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
#endif
diff --git a/source/Core/BSP/Pine64/Power.cpp b/source/Core/BSP/Pine64/Power.cpp index 5e60764e..f10dfacd 100644 --- a/source/Core/BSP/Pine64/Power.cpp +++ b/source/Core/BSP/Pine64/Power.cpp @@ -3,54 +3,38 @@ #include "Pins.h" #include "QC3.h" #include "Settings.h" +#include "USBPD.h" #include "configuration.h" -#include "fusb_user.h" -#include "fusbpd.h" -#include "int_n.h" -#include "policy_engine.h" -bool FUSB302_present = false; -bool FUSB302_probed = false; void power_check() { -#ifdef POW_PD - if (FUSB302_present) { - PolicyEngine::PPSTimerCallback(); - // Cant start QC until either PD works or fails - if (PolicyEngine::setupCompleteOrTimedOut(getSettingValue(SettingsOptions::PDNegTimeout)) == false) { - return; - } - if (PolicyEngine::pdHasNegotiated()) { - return; - } +#if POW_PD + // Cant start QC until either PD works or fails + if (!USBPowerDelivery::negotiationComplete()) { + return; + } + if (USBPowerDelivery::negotiationHasWorked()) { + return; // We are using PD } #endif #ifdef POW_QC QC_resync(); #endif } -uint8_t usb_pd_detect() { -#ifdef POW_PD - if (FUSB302_probed) { - return FUSB302_present; - } else { - FUSB302_present = fusb302_detect(); - FUSB302_probed = true; - } - return FUSB302_present; -#endif - return false; -} bool getIsPoweredByDCIN() { - // We return false until we are sure we are not using PD - if (PolicyEngine::setupCompleteOrTimedOut(getSettingValue(SettingsOptions::PDNegTimeout)) == false) { - return false; +#if POW_PD + if (!USBPowerDelivery::negotiationComplete()) { + return false; // We are assuming not dc while negotiating } - if (PolicyEngine::pdHasNegotiated()) { + if (USBPowerDelivery::negotiationHasWorked()) { return false; // We are using PD } +#endif + +#ifdef POW_QC if (hasQCNegotiated()) { return false; // We are using QC } +#endif return true; } diff --git a/source/Core/BSP/Pine64/Setup.cpp b/source/Core/BSP/Pine64/Setup.cpp index 96532b85..a0b33c63 100644 --- a/source/Core/BSP/Pine64/Setup.cpp +++ b/source/Core/BSP/Pine64/Setup.cpp @@ -25,19 +25,20 @@ void setup_iwdg(); void setup_uart(); void hardware_init() { + // I2C + setup_i2c(); // GPIO setup_gpio(); // DMA setup_dma(); - // I2C - setup_i2c(); // ADC's setup_adc(); // Timers setup_timers(); // Watchdog setup_iwdg(); - + // ELIC + eclic_priority_group_set(ECLIC_PRIGROUP_LEVEL0_PRIO4); // uart for debugging setup_uart(); /* enable TIMER1 - PWM control timing*/ @@ -102,7 +103,7 @@ void setup_uart() { /* USART configure */ usart_deinit(UART_PERIF); - usart_baudrate_set(UART_PERIF, 2 * 1000 * 1000U); + usart_baudrate_set(UART_PERIF, 1000000); usart_word_length_set(UART_PERIF, USART_WL_8BIT); usart_stop_bit_set(UART_PERIF, USART_STB_1BIT); usart_parity_config(UART_PERIF, USART_PM_NONE); @@ -126,10 +127,9 @@ void setup_gpio() { gpio_init(KEY_B_GPIO_Port, GPIO_MODE_IPD, GPIO_OSPEED_2MHZ, KEY_B_Pin); // OLED reset as output gpio_init(OLED_RESET_GPIO_Port, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ, OLED_RESET_Pin); - gpio_bit_set(SDA_GPIO_Port, SDA_Pin); - gpio_bit_set(SDA_GPIO_Port, SCL_Pin); // I2C as AF Open Drain - gpio_init(SDA_GPIO_Port, GPIO_MODE_AF_OD, GPIO_OSPEED_2MHZ, SDA_Pin | SCL_Pin); + gpio_init(SDA_GPIO_Port, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, SDA_Pin); + gpio_init(SCL_GPIO_Port, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, SCL_Pin); // PWM output as AF Push Pull gpio_init(PWM_Out_GPIO_Port, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, PWM_Out_Pin); // Analog Inputs ... as analog inputs @@ -139,15 +139,15 @@ void setup_gpio() { // Remap PB4 away from JTAG NJRST gpio_pin_remap_config(GPIO_SWJ_NONJTRST_REMAP, ENABLE); - - // TODO - rest of pins as floating + // FUSB interrupt + gpio_init(FUSB302_IRQ_GPIO_Port, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, FUSB302_IRQ_Pin); } void setup_dma() { // Setup DMA for ADC0 { /* enable DMA0 clock */ rcu_periph_clock_enable(RCU_DMA0); - rcu_periph_clock_enable(RCU_DMA1); + // rcu_periph_clock_enable(RCU_DMA1); /* ADC_DMA_channel configuration */ dma_parameter_struct dma_data_parameter; @@ -175,14 +175,14 @@ void setup_dma() { void setup_i2c() { /* enable I2C0 clock */ rcu_periph_clock_enable(RCU_I2C0); + /* enable DMA0 clock */ + rcu_periph_clock_enable(RCU_DMA0); // Setup I20 at 400kHz i2c_clock_config(I2C0, 400 * 1000, I2C_DTCY_2); - i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0x00); + i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0x7F); i2c_enable(I2C0); /* enable acknowledge */ i2c_ack_config(I2C0, I2C_ACK_ENABLE); - eclic_irq_enable(I2C0_EV_IRQn, 1, 0); - eclic_irq_enable(I2C0_ER_IRQn, 2, 0); } void setup_adc() { @@ -197,7 +197,7 @@ void setup_adc() { /* config ADC clock */ rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV16); // Run in normal parallel + inserted parallel - adc_mode_config(ADC0, ADC_DAUL_INSERTED_PARALLEL); + adc_mode_config(ADC_DAUL_INSERTED_PARALLEL); adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE); adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE); adc_special_function_config(ADC1, ADC_CONTINUOUS_MODE, ENABLE); @@ -333,13 +333,10 @@ void setup_iwdg() { } void setupFUSBIRQ() { - // Setup IRQ for USB-PD - gpio_init(FUSB302_IRQ_GPIO_Port, GPIO_MODE_IPU, GPIO_OSPEED_2MHZ, FUSB302_IRQ_Pin); - eclic_irq_enable(EXTI5_9_IRQn, 1, 1); - /* connect key EXTI line to key GPIO pin */ + eclic_global_interrupt_enable(); + eclic_irq_enable(EXTI5_9_IRQn, 15, 0); gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOB, GPIO_PIN_SOURCE_5); /* configure key EXTI line */ exti_init(EXTI_5, EXTI_INTERRUPT, EXTI_TRIG_FALLING); - exti_interrupt_flag_clear(EXTI_5); } diff --git a/source/Core/BSP/Pine64/Setup.h b/source/Core/BSP/Pine64/Setup.h index 5da34f5c..d95913e2 100644 --- a/source/Core/BSP/Pine64/Setup.h +++ b/source/Core/BSP/Pine64/Setup.h @@ -15,12 +15,12 @@ extern "C" { #endif
uint16_t getADC(uint8_t channel);
void hardware_init();
-void setupFUSBIRQ();
uint16_t getADCHandleTemp(uint8_t sample);
uint16_t getADCVin(uint8_t sample);
#ifdef __cplusplus
}
#endif
+void setupFUSBIRQ();
extern const uint8_t holdoffTicks;
extern const uint8_t tempMeasureTicks;
#endif /* PINE_SETUP_H_ */
diff --git a/source/Core/BSP/Pine64/Vendor/NMSIS/Core/Include/riscv_encoding.h b/source/Core/BSP/Pine64/Vendor/NMSIS/Core/Include/riscv_encoding.h index f6a57f6f..52c9ac1c 100644 --- a/source/Core/BSP/Pine64/Vendor/NMSIS/Core/Include/riscv_encoding.h +++ b/source/Core/BSP/Pine64/Vendor/NMSIS/Core/Include/riscv_encoding.h @@ -608,6 +608,118 @@ extern "C" { #define DCAUSE_FAULT_STORE_PMP 0x1 #define DCAUSE_FAULT_STORE_INST 0x2 +#define read_fpu(reg) \ + ({ \ + unsigned long __tmp; \ + asm volatile("fmv.x.w %0, " #reg : "=r"(__tmp)); \ + __tmp; \ + }) + +#define write_fpu(reg, val) \ + ({ \ + if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ + asm volatile("fmv.w.x " #reg ", %0" ::"i"(val)); \ + else \ + asm volatile("fmv.w.x " #reg ", %0" ::"r"(val)); \ + }) + +#define read_csr(reg) \ + ({ \ + unsigned long __tmp; \ + asm volatile("csrr %0, " #reg : "=r"(__tmp)); \ + __tmp; \ + }) + +#define write_csr(reg, val) \ + ({ \ + if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ + asm volatile("csrw " #reg ", %0" ::"i"(val)); \ + else \ + asm volatile("csrw " #reg ", %0" ::"r"(val)); \ + }) + +#define swap_csr(reg, val) \ + ({ \ + unsigned long __tmp; \ + if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ + asm volatile("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "i"(val)); \ + else \ + asm volatile("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \ + __tmp; \ + }) + +#define set_csr(reg, bit) \ + ({ \ + unsigned long __tmp; \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + asm volatile("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \ + else \ + asm volatile("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \ + __tmp; \ + }) + +#define clear_csr(reg, bit) \ + ({ \ + unsigned long __tmp; \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + asm volatile("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \ + else \ + asm volatile("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \ + __tmp; \ + }) + +#define rdtime() read_csr(time) +#define rdcycle() read_csr(cycle) +#define rdinstret() read_csr(instret) + +#define ECLICINTCTLBITS 4 + +/*ECLIC memory map */ +/* Offset */ +/* 0x0000 1B RW ecliccfg */ +#define ECLIC_CFG_OFFSET 0x0 +/* 0x0004 4B R eclicinfo */ +#define ECLIC_INFO_OFFSET 0x4 +/* 0x000B 1B RW mintthresh */ +#define ECLIC_MTH_OFFSET 0xB + +/* 0x1000+4*i 1B/input RW eclicintip[i] */ +#define ECLIC_INT_IP_OFFSET _AC(0x1000, UL) +/* 0x1001+4*i 1B/input RW eclicintie[i] */ +#define ECLIC_INT_IE_OFFSET _AC(0x1001, UL) +/* 0x1002+4*i 1B/input RW eclicintattr[i]*/ +#define ECLIC_INT_ATTR_OFFSET _AC(0x1002, UL) + +#define ECLIC_INT_ATTR_SHV 0x01 +#define ECLIC_INT_ATTR_TRIG_LEVEL 0x00 +#define ECLIC_INT_ATTR_TRIG_EDGE 0x02 +#define ECLIC_INT_ATTR_TRIG_POS 0x00 +#define ECLIC_INT_ATTR_TRIG_NEG 0x04 + +/* 0x1003+4*i 1B/input RW eclicintctl[i] */ +#define ECLIC_INT_CTRL_OFFSET _AC(0x1003, UL) + +#define ECLIC_ADDR_BASE 0xd2000000 + +#define ECLIC_CFG_NLBITS_MASK _AC(0x1E, UL) +#define ECLIC_CFG_NLBITS_LSB (1u) + +#define MSIP_HANDLER eclic_msip_handler +#define MTIME_HANDLER eclic_mtip_handler +#define BWEI_HANDLER eclic_bwei_handler +#define PMOVI_HANDLER eclic_pmovi_handler + +#define TIMER_MSIP 0xFFC +#define TIMER_MSIP_size 0x4 +#define TIMER_MTIMECMP 0x8 +#define TIMER_MTIMECMP_size 0x8 +#define TIMER_MTIME 0x0 +#define TIMER_MTIME_size 0x8 + +#define TIMER_CTRL_ADDR 0xd1000000 +#define TIMER_REG(offset) _REG32(TIMER_CTRL_ADDR, offset) +#define TIMER_FREQ ((uint32_t)SystemCoreClock / 4) + /** @} */ /** End of Doxygen Group NMSIS_Core_CSR_Encoding **/ #ifdef __cplusplus diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Board/pinecil/Include/gd32vf103v_eval.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Board/pinecil/Include/gd32vf103v_eval.h deleted file mode 100644 index 1e4cdcd2..00000000 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Board/pinecil/Include/gd32vf103v_eval.h +++ /dev/null @@ -1,48 +0,0 @@ -/*! - \file gd32vf103v_eval.h - \brief definitions for GD32VF103V_EVAL's leds, keys and COM ports hardware resources - - \version 2019-6-5, V1.0.0, demo for GD32VF103 -*/ - -/* - Copyright (c) 2019, GigaDevice Semiconductor Inc. - - Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - 3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - -#ifndef GD32VF103V_EVAL_H -#define GD32VF103V_EVAL_H - -#ifdef cplusplus -extern "C" { -#endif - -#include "nuclei_sdk_soc.h" - -#ifdef cplusplus -} -#endif - -#endif /* GD32VF103V_EVAL_H */ diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Board/pinecil/Include/nuclei_sdk_hal.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Board/pinecil/Include/nuclei_sdk_hal.h deleted file mode 100644 index caee2f0e..00000000 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Board/pinecil/Include/nuclei_sdk_hal.h +++ /dev/null @@ -1,18 +0,0 @@ -// See LICENSE for license details. -#ifndef _NUCLEI_SDK_HAL_H -#define _NUCLEI_SDK_HAL_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "gd32vf103v_eval.h" - -#ifndef NUCLEI_BANNER -#define NUCLEI_BANNER 0 -#endif - -#ifdef __cplusplus -} -#endif -#endif diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Board/pinecil/Source/gd32vf103v_eval.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Board/pinecil/Source/gd32vf103v_eval.c deleted file mode 100644 index ba11e192..00000000 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Board/pinecil/Source/gd32vf103v_eval.c +++ /dev/null @@ -1,38 +0,0 @@ -/*!
- \file gd32vf103v_eval.c
- \brief firmware functions to manage leds, keys, COM ports
-
- \version 2019-6-5, V1.0.0, demo for GD32VF103
-*/
-
-/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
-
- Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- 3. Neither the name of the copyright holder nor the names of its contributors
- may be used to endorse or promote products derived from this software without
- specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-#include "gd32vf103_exti.h"
-#include "gd32vf103_gpio.h"
-#include "gd32vf103_usart.h"
-#include "nuclei_sdk_hal.h"
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103.h index c8a2fcc8..5d242443 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103.h @@ -344,6 +344,35 @@ extern void delay_1ms(uint32_t count); /** @} */ /* End of group gd32vf103 */ +/* define startup timeout value of high speed crystal oscillator (HXTAL) */ +#if !defined(HXTAL_STARTUP_TIMEOUT) +#define HXTAL_STARTUP_TIMEOUT ((uint16_t)0xFFFF) +#endif /* high speed crystal oscillator startup timeout */ + +/* define value of internal 8MHz RC oscillator (IRC8M) in Hz */ +#if !defined(IRC8M_VALUE) +#define IRC8M_VALUE ((uint32_t)8000000) +#endif /* internal 8MHz RC oscillator value */ + +/* define startup timeout value of internal 8MHz RC oscillator (IRC8M) */ +#if !defined(IRC8M_STARTUP_TIMEOUT) +#define IRC8M_STARTUP_TIMEOUT ((uint16_t)0x0500) +#endif /* internal 8MHz RC oscillator startup timeout */ + +/* define value of internal 40KHz RC oscillator(IRC40K) in Hz */ +#if !defined(IRC40K_VALUE) +#define IRC40K_VALUE ((uint32_t)40000) +#endif /* internal 40KHz RC oscillator value */ + +/* define value of low speed crystal oscillator (LXTAL)in Hz */ +#if !defined(LXTAL_VALUE) +#define LXTAL_VALUE ((uint32_t)32768) +#endif /* low speed crystal oscillator value */ + +#if !defined(HXTAL_VALUE) +#define HXTAL_VALUE ((uint32_t)8000000) +#endif /* high speed crystal oscillator value */ + #ifdef __cplusplus } #endif diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_adc.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_adc.h index 65d102b0..20669609 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_adc.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_adc.h @@ -1,398 +1,397 @@ -/*! - \file gd32vf103_adc.h - \brief definitions for the ADC - - \version 2019-6-5, V1.0.0, firmware for GD32VF103 -*/ - -/* - Copyright (c) 2019, GigaDevice Semiconductor Inc. - - Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - 3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - -#ifndef GD32VF103_ADC_H -#define GD32VF103_ADC_H - -#include "gd32vf103.h" -#include "gd32vf103_dbg.h" -#include "gd32vf103_rcu.h" - -/* ADC definitions */ -#define ADC0 ADC_BASE -#define ADC1 (ADC_BASE + 0x400U) - -/* registers definitions */ -#define ADC_STAT(adcx) REG32((adcx) + 0x00U) /*!< ADC status register */ -#define ADC_CTL0(adcx) REG32((adcx) + 0x04U) /*!< ADC control register 0 */ -#define ADC_CTL1(adcx) REG32((adcx) + 0x08U) /*!< ADC control register 1 */ -#define ADC_SAMPT0(adcx) REG32((adcx) + 0x0CU) /*!< ADC sampling time register 0 */ -#define ADC_SAMPT1(adcx) REG32((adcx) + 0x10U) /*!< ADC sampling time register 1 */ -#define ADC_IOFF0(adcx) REG32((adcx) + 0x14U) /*!< ADC inserted channel data offset register 0 */ -#define ADC_IOFF1(adcx) REG32((adcx) + 0x18U) /*!< ADC inserted channel data offset register 1 */ -#define ADC_IOFF2(adcx) REG32((adcx) + 0x1CU) /*!< ADC inserted channel data offset register 2 */ -#define ADC_IOFF3(adcx) REG32((adcx) + 0x20U) /*!< ADC inserted channel data offset register 3 */ -#define ADC_WDHT(adcx) REG32((adcx) + 0x24U) /*!< ADC watchdog high threshold register */ -#define ADC_WDLT(adcx) REG32((adcx) + 0x28U) /*!< ADC watchdog low threshold register */ -#define ADC_RSQ0(adcx) REG32((adcx) + 0x2CU) /*!< ADC regular sequence register 0 */ -#define ADC_RSQ1(adcx) REG32((adcx) + 0x30U) /*!< ADC regular sequence register 1 */ -#define ADC_RSQ2(adcx) REG32((adcx) + 0x34U) /*!< ADC regular sequence register 2 */ -#define ADC_ISQ(adcx) REG32((adcx) + 0x38U) /*!< ADC inserted sequence register */ -#define ADC_IDATA0(adcx) REG32((adcx) + 0x3CU) /*!< ADC inserted data register 0 */ -#define ADC_IDATA1(adcx) REG32((adcx) + 0x40U) /*!< ADC inserted data register 1 */ -#define ADC_IDATA2(adcx) REG32((adcx) + 0x44U) /*!< ADC inserted data register 2 */ -#define ADC_IDATA3(adcx) REG32((adcx) + 0x48U) /*!< ADC inserted data register 3 */ -#define ADC_RDATA(adcx) REG32((adcx) + 0x4CU) /*!< ADC regular data register */ -#define ADC_OVSCR(adcx) REG32((adcx) + 0x80U) /*!< ADC oversample control register */ - -/* bits definitions */ -/* ADC_STAT */ -#define ADC_STAT_WDE BIT(0) /*!< analog watchdog event flag */ -#define ADC_STAT_EOC BIT(1) /*!< end of conversion */ -#define ADC_STAT_EOIC BIT(2) /*!< inserted channel end of conversion */ -#define ADC_STAT_STIC BIT(3) /*!< inserted channel start flag */ -#define ADC_STAT_STRC BIT(4) /*!< regular channel start flag */ - -/* ADC_CTL0 */ -#define ADC_CTL0_WDCHSEL BITS(0, 4) /*!< analog watchdog channel select bits */ -#define ADC_CTL0_EOCIE BIT(5) /*!< interrupt enable for EOC */ -#define ADC_CTL0_WDEIE BIT(6) /*!< analog watchdog interrupt enable */ -#define ADC_CTL0_EOICIE BIT(7) /*!< interrupt enable for inserted channels */ -#define ADC_CTL0_SM BIT(8) /*!< scan mode */ -#define ADC_CTL0_WDSC BIT(9) /*!< when in scan mode, analog watchdog is effective on a single channel */ -#define ADC_CTL0_ICA BIT(10) /*!< automatic inserted group conversion */ -#define ADC_CTL0_DISRC BIT(11) /*!< discontinuous mode on regular channels */ -#define ADC_CTL0_DISIC BIT(12) /*!< discontinuous mode on inserted channels */ -#define ADC_CTL0_DISNUM BITS(13, 15) /*!< discontinuous mode channel count */ -#define ADC_CTL0_SYNCM BITS(16, 19) /*!< sync mode selection */ -#define ADC_CTL0_IWDEN BIT(22) /*!< analog watchdog enable on inserted channels */ -#define ADC_CTL0_RWDEN BIT(23) /*!< analog watchdog enable on regular channels */ - -/* ADC_CTL1 */ -#define ADC_CTL1_ADCON BIT(0) /*!< ADC converter on */ -#define ADC_CTL1_CTN BIT(1) /*!< continuous conversion */ -#define ADC_CTL1_CLB BIT(2) /*!< ADC calibration */ -#define ADC_CTL1_RSTCLB BIT(3) /*!< reset calibration */ -#define ADC_CTL1_DMA BIT(8) /*!< direct memory access mode */ -#define ADC_CTL1_DAL BIT(11) /*!< data alignment */ -#define ADC_CTL1_ETSIC BITS(12, 14) /*!< external trigger select for inserted channel */ -#define ADC_CTL1_ETEIC BIT(15) /*!< external trigger enable for inserted channel */ -#define ADC_CTL1_ETSRC BITS(17, 19) /*!< external trigger select for regular channel */ -#define ADC_CTL1_ETERC BIT(20) /*!< external trigger conversion mode for inserted channels */ -#define ADC_CTL1_SWICST BIT(21) /*!< start on inserted channel */ -#define ADC_CTL1_SWRCST BIT(22) /*!< start on regular channel */ -#define ADC_CTL1_TSVREN BIT(23) /*!< channel 16 and 17 enable of ADC0 */ - -/* ADC_SAMPTx x=0..1 */ -#define ADC_SAMPTX_SPTN BITS(0, 2) /*!< channel n sample time selection */ - -/* ADC_IOFFx x=0..3 */ -#define ADC_IOFFX_IOFF BITS(0, 11) /*!< data offset for inserted channel x */ - -/* ADC_WDHT */ -#define ADC_WDHT_WDHT BITS(0, 11) /*!< analog watchdog high threshold */ - -/* ADC_WDLT */ -#define ADC_WDLT_WDLT BITS(0, 11) /*!< analog watchdog low threshold */ - -/* ADC_RSQx x=0..2 */ -#define ADC_RSQX_RSQN BITS(0, 4) /*!< nth conversion in regular sequence */ -#define ADC_RSQ0_RL BITS(20, 23) /*!< regular channel sequence length */ - -/* ADC_ISQ */ -#define ADC_ISQ_ISQN BITS(0, 4) /*!< nth conversion in inserted sequence */ -#define ADC_ISQ_IL BITS(20, 21) /*!< inserted sequence length */ - -/* ADC_IDATAx x=0..3*/ -#define ADC_IDATAX_IDATAN BITS(0, 15) /*!< inserted data n */ - -/* ADC_RDATA */ -#define ADC_RDATA_RDATA BITS(0, 15) /*!< regular data */ -#define ADC_RDATA_ADC1RDTR BITS(16, 31) /*!< ADC1 regular channel data */ - -/* ADC_OVSCR */ -#define ADC_OVSCR_OVSEN BIT(0) /*!< oversampling enable */ -#define ADC_OVSCR_OVSR BITS(2, 4) /*!< oversampling ratio */ -#define ADC_OVSCR_OVSS BITS(5, 8) /*!< oversampling shift */ -#define ADC_OVSCR_TOVS BIT(9) /*!< triggered oversampling */ -#define ADC_OVSCR_DRES BITS(12, 13) /*!< ADC data resolution */ - -/* constants definitions */ -/* adc_stat register value */ -#define ADC_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog event flag */ -#define ADC_FLAG_EOC ADC_STAT_EOC /*!< end of conversion */ -#define ADC_FLAG_EOIC ADC_STAT_EOIC /*!< inserted channel end of conversion */ -#define ADC_FLAG_STIC ADC_STAT_STIC /*!< inserted channel start flag */ -#define ADC_FLAG_STRC ADC_STAT_STRC /*!< regular channel start flag */ - -/* adc_ctl0 register value */ -#define CTL0_DISNUM(regval) (BITS(13, 15) & ((uint32_t)(regval) << 13)) /*!< write value to ADC_CTL0_DISNUM bit field */ - -/* scan mode */ -#define ADC_SCAN_MODE ADC_CTL0_SM /*!< scan mode */ - -/* inserted channel group convert automatically */ -#define ADC_INSERTED_CHANNEL_AUTO ADC_CTL0_ICA /*!< inserted channel group convert automatically */ - -/* ADC sync mode */ -#define CTL0_SYNCM(regval) (BITS(16, 19) & ((uint32_t)(regval) << 16)) /*!< write value to ADC_CTL0_SYNCM bit field */ -#define ADC_MODE_FREE CTL0_SYNCM(0) /*!< all the ADCs work independently */ -#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL CTL0_SYNCM(1) /*!< ADC0 and ADC1 work in combined regular parallel + inserted parallel mode */ -#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION CTL0_SYNCM(2) /*!< ADC0 and ADC1 work in combined regular parallel + trigger rotation mode */ -#define ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_FAST CTL0_SYNCM(3) /*!< ADC0 and ADC1 work in combined inserted parallel + follow-up fast mode */ -#define ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_SLOW CTL0_SYNCM(4) /*!< ADC0 and ADC1 work in combined inserted parallel + follow-up slow mode */ -#define ADC_DAUL_INSERTED_PARALLEL CTL0_SYNCM(5) /*!< ADC0 and ADC1 work in inserted parallel mode only */ -#define ADC_DAUL_REGULAL_PARALLEL CTL0_SYNCM(6) /*!< ADC0 and ADC1 work in regular parallel mode only */ -#define ADC_DAUL_REGULAL_FOLLOWUP_FAST CTL0_SYNCM(7) /*!< ADC0 and ADC1 work in follow-up fast mode only */ -#define ADC_DAUL_REGULAL_FOLLOWUP_SLOW CTL0_SYNCM(8) /*!< ADC0 and ADC1 work in follow-up slow mode only */ -#define ADC_DAUL_INSERTED_TRIGGER_ROTATION CTL0_SYNCM(9) /*!< ADC0 and ADC1 work in trigger rotation mode only */ - -/* adc_ctl1 register value */ -#define ADC_DATAALIGN_RIGHT ((uint32_t)0x00000000U) /*!< LSB alignment */ -#define ADC_DATAALIGN_LEFT ADC_CTL1_DAL /*!< MSB alignment */ - -/* continuous mode */ -#define ADC_CONTINUOUS_MODE ADC_CTL1_CTN /*!< continuous mode */ - -/* external trigger select for regular channel */ -#define CTL1_ETSRC(regval) (BITS(17, 19) & ((uint32_t)(regval) << 17)) /*!< write value to ADC_CTL1_ETSRC bit field */ -/* for ADC0 and ADC1 regular channel */ -#define ADC0_1_EXTTRIG_REGULAR_T0_CH0 CTL1_ETSRC(0) /*!< TIMER0 CH0 event select */ -#define ADC0_1_EXTTRIG_REGULAR_T0_CH1 CTL1_ETSRC(1) /*!< TIMER0 CH1 event select */ -#define ADC0_1_EXTTRIG_REGULAR_T0_CH2 CTL1_ETSRC(2) /*!< TIMER0 CH2 event select */ -#define ADC0_1_EXTTRIG_REGULAR_T1_CH1 CTL1_ETSRC(3) /*!< TIMER1 CH1 event select */ -#define ADC0_1_EXTTRIG_REGULAR_T2_TRGO CTL1_ETSRC(4) /*!< TIMER2 TRGO event select */ -#define ADC0_1_EXTTRIG_REGULAR_T3_CH3 CTL1_ETSRC(5) /*!< TIMER3 CH3 event select */ -#define ADC0_1_EXTTRIG_REGULAR_EXTI_11 CTL1_ETSRC(6) /*!< external interrupt line 11 */ -#define ADC0_1_EXTTRIG_REGULAR_NONE CTL1_ETSRC(7) /*!< software trigger */ - -/* external trigger mode for inserted channel */ -#define CTL1_ETSIC(regval) (BITS(12, 14) & ((uint32_t)(regval) << 12)) /*!< write value to ADC_CTL1_ETSIC bit field */ -/* for ADC0 and ADC1 inserted channel */ -#define ADC0_1_EXTTRIG_INSERTED_T0_TRGO CTL1_ETSIC(0) /*!< TIMER0 TRGO event select */ -#define ADC0_1_EXTTRIG_INSERTED_T0_CH3 CTL1_ETSIC(1) /*!< TIMER0 CH3 event select */ -#define ADC0_1_EXTTRIG_INSERTED_T1_TRGO CTL1_ETSIC(2) /*!< TIMER1 TRGO event select */ -#define ADC0_1_EXTTRIG_INSERTED_T1_CH0 CTL1_ETSIC(3) /*!< TIMER1 CH0 event select */ -#define ADC0_1_EXTTRIG_INSERTED_T2_CH3 CTL1_ETSIC(4) /*!< TIMER2 CH3 event select */ -#define ADC0_1_EXTTRIG_INSERTED_T3_TRGO CTL1_ETSIC(5) /*!< TIMER3 TRGO event select */ -#define ADC0_1_EXTTRIG_INSERTED_EXTI_15 CTL1_ETSIC(6) /*!< external interrupt line 15 */ -#define ADC0_1_EXTTRIG_INSERTED_NONE CTL1_ETSIC(7) /*!< software trigger */ - -/* adc_samptx register value */ -#define SAMPTX_SPT(regval) (BITS(0, 2) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_SAMPTX_SPT bit field */ -#define ADC_SAMPLETIME_1POINT5 SAMPTX_SPT(0) /*!< 1.5 sampling cycles */ -#define ADC_SAMPLETIME_7POINT5 SAMPTX_SPT(1) /*!< 7.5 sampling cycles */ -#define ADC_SAMPLETIME_13POINT5 SAMPTX_SPT(2) /*!< 13.5 sampling cycles */ -#define ADC_SAMPLETIME_28POINT5 SAMPTX_SPT(3) /*!< 28.5 sampling cycles */ -#define ADC_SAMPLETIME_41POINT5 SAMPTX_SPT(4) /*!< 41.5 sampling cycles */ -#define ADC_SAMPLETIME_55POINT5 SAMPTX_SPT(5) /*!< 55.5 sampling cycles */ -#define ADC_SAMPLETIME_71POINT5 SAMPTX_SPT(6) /*!< 71.5 sampling cycles */ -#define ADC_SAMPLETIME_239POINT5 SAMPTX_SPT(7) /*!< 239.5 sampling cycles */ - -/* adc_ioffx register value */ -#define IOFFX_IOFF(regval) (BITS(0, 11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_IOFFX_IOFF bit field */ - -/* adc_wdht register value */ -#define WDHT_WDHT(regval) (BITS(0, 11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_WDHT_WDHT bit field */ - -/* adc_wdlt register value */ -#define WDLT_WDLT(regval) (BITS(0, 11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_WDLT_WDLT bit field */ - -/* adc_rsqx register value */ -#define RSQ0_RL(regval) (BITS(20, 23) & ((uint32_t)(regval) << 20)) /*!< write value to ADC_RSQ0_RL bit field */ - -/* adc_isq register value */ -#define ISQ_IL(regval) (BITS(20, 21) & ((uint32_t)(regval) << 20)) /*!< write value to ADC_ISQ_IL bit field */ - -/* ADC channel group definitions */ -#define ADC_REGULAR_CHANNEL ((uint8_t)0x01U) /*!< adc regular channel group */ -#define ADC_INSERTED_CHANNEL ((uint8_t)0x02U) /*!< adc inserted channel group */ -#define ADC_REGULAR_INSERTED_CHANNEL ((uint8_t)0x03U) /*!< both regular and inserted channel group */ - -#define ADC_CHANNEL_DISCON_DISABLE ((uint8_t)0x04U) /*!< disable discontinuous mode of regular & inserted channel */ - -/* ADC inserted channel definitions */ -#define ADC_INSERTED_CHANNEL_0 ((uint8_t)0x00U) /*!< adc inserted channel 0 */ -#define ADC_INSERTED_CHANNEL_1 ((uint8_t)0x01U) /*!< adc inserted channel 1 */ -#define ADC_INSERTED_CHANNEL_2 ((uint8_t)0x02U) /*!< adc inserted channel 2 */ -#define ADC_INSERTED_CHANNEL_3 ((uint8_t)0x03U) /*!< adc inserted channel 3 */ - -/* ADC channel definitions */ -#define ADC_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC channel 0 */ -#define ADC_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC channel 1 */ -#define ADC_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC channel 2 */ -#define ADC_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC channel 3 */ -#define ADC_CHANNEL_4 ((uint8_t)0x04U) /*!< ADC channel 4 */ -#define ADC_CHANNEL_5 ((uint8_t)0x05U) /*!< ADC channel 5 */ -#define ADC_CHANNEL_6 ((uint8_t)0x06U) /*!< ADC channel 6 */ -#define ADC_CHANNEL_7 ((uint8_t)0x07U) /*!< ADC channel 7 */ -#define ADC_CHANNEL_8 ((uint8_t)0x08U) /*!< ADC channel 8 */ -#define ADC_CHANNEL_9 ((uint8_t)0x09U) /*!< ADC channel 9 */ -#define ADC_CHANNEL_10 ((uint8_t)0x0AU) /*!< ADC channel 10 */ -#define ADC_CHANNEL_11 ((uint8_t)0x0BU) /*!< ADC channel 11 */ -#define ADC_CHANNEL_12 ((uint8_t)0x0CU) /*!< ADC channel 12 */ -#define ADC_CHANNEL_13 ((uint8_t)0x0DU) /*!< ADC channel 13 */ -#define ADC_CHANNEL_14 ((uint8_t)0x0EU) /*!< ADC channel 14 */ -#define ADC_CHANNEL_15 ((uint8_t)0x0FU) /*!< ADC channel 15 */ -#define ADC_CHANNEL_16 ((uint8_t)0x10U) /*!< ADC channel 16 */ -#define ADC_CHANNEL_17 ((uint8_t)0x11U) /*!< ADC channel 17 */ - -/* ADC interrupt */ -#define ADC_INT_WDE ADC_STAT_WDE /*!< analog watchdog event interrupt */ -#define ADC_INT_EOC ADC_STAT_EOC /*!< end of group conversion interrupt */ -#define ADC_INT_EOIC ADC_STAT_EOIC /*!< end of inserted group conversion interrupt */ - -/* ADC interrupt flag */ -#define ADC_INT_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog event interrupt flag */ -#define ADC_INT_FLAG_EOC ADC_STAT_EOC /*!< end of group conversion interrupt flag */ -#define ADC_INT_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted group conversion interrupt flag */ - -/* ADC resolution definitions */ -#define OVSCR_DRES(regval) (BITS(12, 13) & ((uint32_t)(regval) << 12)) -#define ADC_RESOLUTION_12B OVSCR_DRES(0) /*!< 12-bit ADC resolution */ -#define ADC_RESOLUTION_10B OVSCR_DRES(1) /*!< 10-bit ADC resolution */ -#define ADC_RESOLUTION_8B OVSCR_DRES(2) /*!< 8-bit ADC resolution */ -#define ADC_RESOLUTION_6B OVSCR_DRES(3) /*!< 6-bit ADC resolution */ - -/* ADC oversampling mode */ -#define ADC_OVERSAMPLING_ALL_CONVERT 0 /*!< all oversampled conversions for a channel are done consecutively after a trigger */ -#define ADC_OVERSAMPLING_ONE_CONVERT 1 /*!< each oversampled conversion for a channel needs a trigger */ - -/* ADC oversampling shift */ -#define OVSCR_OVSS(regval) (BITS(5, 8) & ((uint32_t)(regval) << 5)) -#define ADC_OVERSAMPLING_SHIFT_NONE OVSCR_OVSS(0) /*!< no oversampling shift */ -#define ADC_OVERSAMPLING_SHIFT_1B OVSCR_OVSS(1) /*!< 1-bit oversampling shift */ -#define ADC_OVERSAMPLING_SHIFT_2B OVSCR_OVSS(2) /*!< 2-bit oversampling shift */ -#define ADC_OVERSAMPLING_SHIFT_3B OVSCR_OVSS(3) /*!< 3-bit oversampling shift */ -#define ADC_OVERSAMPLING_SHIFT_4B OVSCR_OVSS(4) /*!< 4-bit oversampling shift */ -#define ADC_OVERSAMPLING_SHIFT_5B OVSCR_OVSS(5) /*!< 5-bit oversampling shift */ -#define ADC_OVERSAMPLING_SHIFT_6B OVSCR_OVSS(6) /*!< 6-bit oversampling shift */ -#define ADC_OVERSAMPLING_SHIFT_7B OVSCR_OVSS(7) /*!< 7-bit oversampling shift */ -#define ADC_OVERSAMPLING_SHIFT_8B OVSCR_OVSS(8) /*!< 8-bit oversampling shift */ - -/* ADC oversampling ratio */ -#define OVSCR_OVSR(regval) (BITS(2, 4) & ((uint32_t)(regval) << 2)) -#define ADC_OVERSAMPLING_RATIO_MUL2 OVSCR_OVSR(0) /*!< oversampling ratio X2 */ -#define ADC_OVERSAMPLING_RATIO_MUL4 OVSCR_OVSR(1) /*!< oversampling ratio X4 */ -#define ADC_OVERSAMPLING_RATIO_MUL8 OVSCR_OVSR(2) /*!< oversampling ratio X8 */ -#define ADC_OVERSAMPLING_RATIO_MUL16 OVSCR_OVSR(3) /*!< oversampling ratio X16 */ -#define ADC_OVERSAMPLING_RATIO_MUL32 OVSCR_OVSR(4) /*!< oversampling ratio X32 */ -#define ADC_OVERSAMPLING_RATIO_MUL64 OVSCR_OVSR(5) /*!< oversampling ratio X64 */ -#define ADC_OVERSAMPLING_RATIO_MUL128 OVSCR_OVSR(6) /*!< oversampling ratio X128 */ -#define ADC_OVERSAMPLING_RATIO_MUL256 OVSCR_OVSR(7) /*!< oversampling ratio X256 */ - -/* function declarations */ -/* initialization config */ -/* reset ADC */ -void adc_deinit(uint32_t adc_periph); -/* configure the ADC sync mode */ -void adc_mode_config(uint32_t adc_periph, uint32_t mode); -/* enable or disable ADC special function */ -void adc_special_function_config(uint32_t adc_periph, uint32_t function, ControlStatus newvalue); -/* configure ADC data alignment */ -void adc_data_alignment_config(uint32_t adc_periph, uint32_t data_alignment); -/* enable ADC interface */ -void adc_enable(uint32_t adc_periph); -/* disable ADC interface */ -void adc_disable(uint32_t adc_periph); -/* ADC calibration and reset calibration */ -void adc_calibration_enable(uint32_t adc_periph); -/* enable the temperature sensor and Vrefint channel */ -void adc_tempsensor_vrefint_enable(void); -/* disable the temperature sensor and Vrefint channel */ -void adc_tempsensor_vrefint_disable(void); - -/* DMA config */ -/* enable DMA request */ -void adc_dma_mode_enable(uint32_t adc_periph); -/* disable DMA request */ -void adc_dma_mode_disable(uint32_t adc_periph); - -/* regular group and inserted group config */ -/* configure ADC discontinuous mode */ -void adc_discontinuous_mode_config(uint32_t adc_periph, uint8_t adc_channel_group, uint8_t length); - -/* configure the length of regular channel group or inserted channel group */ -void adc_channel_length_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t length); -/* configure ADC regular channel */ -void adc_regular_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time); -/* configure ADC inserted channel */ -void adc_inserted_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time); -/* configure ADC inserted channel offset */ -void adc_inserted_channel_offset_config(uint32_t adc_periph, uint8_t inserted_channel, uint16_t offset); - -/* configure ADC external trigger source */ -void adc_external_trigger_source_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t external_trigger_source); -/* configure ADC external trigger */ -void adc_external_trigger_config(uint32_t adc_periph, uint8_t adc_channel_group, ControlStatus newvalue); -/* enable ADC software trigger */ -void adc_software_trigger_enable(uint32_t adc_periph, uint8_t adc_channel_group); - -/* get channel data */ -/* read ADC regular group data register */ -uint16_t adc_regular_data_read(uint32_t adc_periph); -/* read ADC inserted group data register */ -uint16_t adc_inserted_data_read(uint32_t adc_periph, uint8_t inserted_channel); -/* read the last ADC0 and ADC1 conversion result data in sync mode */ -uint32_t adc_sync_mode_convert_value_read(void); - -/* watchdog config */ -/* configure ADC analog watchdog single channel */ -void adc_watchdog_single_channel_enable(uint32_t adc_periph, uint8_t adc_channel); -/* configure ADC analog watchdog group channel */ -void adc_watchdog_group_channel_enable(uint32_t adc_periph, uint8_t adc_channel_group); -/* disable ADC analog watchdog */ -void adc_watchdog_disable(uint32_t adc_periph); -/* configure ADC analog watchdog threshold */ -void adc_watchdog_threshold_config(uint32_t adc_periph, uint16_t low_threshold, uint16_t high_threshold); - -/* interrupt & flag functions */ -/* get the ADC flag bits */ -FlagStatus adc_flag_get(uint32_t adc_periph, uint32_t adc_flag); -/* clear the ADC flag bits */ -void adc_flag_clear(uint32_t adc_periph, uint32_t adc_flag); -/* get the bit state of ADCx software start conversion */ -FlagStatus adc_regular_software_startconv_flag_get(uint32_t adc_periph); -/* get the bit state of ADCx software inserted channel start conversion */ -FlagStatus adc_inserted_software_startconv_flag_get(uint32_t adc_periph); -/* get the ADC interrupt bits */ -FlagStatus adc_interrupt_flag_get(uint32_t adc_periph, uint32_t adc_interrupt); -/* clear the ADC flag */ -void adc_interrupt_flag_clear(uint32_t adc_periph, uint32_t adc_interrupt); -/* enable ADC interrupt */ -void adc_interrupt_enable(uint32_t adc_periph, uint32_t adc_interrupt); -/* disable ADC interrupt */ -void adc_interrupt_disable(uint32_t adc_periph, uint32_t adc_interrupt); - -/* ADC resolution & oversample */ -/* ADC resolution config */ -void adc_resolution_config(uint32_t adc_periph, uint32_t resolution); -/* ADC oversample mode config */ -void adc_oversample_mode_config(uint32_t adc_periph, uint8_t mode, uint16_t shift, uint8_t ratio); -/* enable ADC oversample mode */ -void adc_oversample_mode_enable(uint32_t adc_periph); -/* disable ADC oversample mode */ -void adc_oversample_mode_disable(uint32_t adc_periph); - -#endif /* GD32VF103_ADC_H */ +/*!
+ \file gd32vf103_adc.h
+ \brief definitions for the ADC
+
+ \version 2020-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
+*/
+
+/*
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ 3. Neither the name of the copyright holder nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32VF103_ADC_H
+#define GD32VF103_ADC_H
+
+#include "gd32vf103.h"
+
+/* ADC definitions */
+#define ADC0 ADC_BASE
+#define ADC1 (ADC_BASE + 0x400U)
+
+/* registers definitions */
+#define ADC_STAT(adcx) REG32((adcx) + 0x00U) /*!< ADC status register */
+#define ADC_CTL0(adcx) REG32((adcx) + 0x04U) /*!< ADC control register 0 */
+#define ADC_CTL1(adcx) REG32((adcx) + 0x08U) /*!< ADC control register 1 */
+#define ADC_SAMPT0(adcx) REG32((adcx) + 0x0CU) /*!< ADC sampling time register 0 */
+#define ADC_SAMPT1(adcx) REG32((adcx) + 0x10U) /*!< ADC sampling time register 1 */
+#define ADC_IOFF0(adcx) REG32((adcx) + 0x14U) /*!< ADC inserted channel data offset register 0 */
+#define ADC_IOFF1(adcx) REG32((adcx) + 0x18U) /*!< ADC inserted channel data offset register 1 */
+#define ADC_IOFF2(adcx) REG32((adcx) + 0x1CU) /*!< ADC inserted channel data offset register 2 */
+#define ADC_IOFF3(adcx) REG32((adcx) + 0x20U) /*!< ADC inserted channel data offset register 3 */
+#define ADC_WDHT(adcx) REG32((adcx) + 0x24U) /*!< ADC watchdog high threshold register */
+#define ADC_WDLT(adcx) REG32((adcx) + 0x28U) /*!< ADC watchdog low threshold register */
+#define ADC_RSQ0(adcx) REG32((adcx) + 0x2CU) /*!< ADC regular sequence register 0 */
+#define ADC_RSQ1(adcx) REG32((adcx) + 0x30U) /*!< ADC regular sequence register 1 */
+#define ADC_RSQ2(adcx) REG32((adcx) + 0x34U) /*!< ADC regular sequence register 2 */
+#define ADC_ISQ(adcx) REG32((adcx) + 0x38U) /*!< ADC inserted sequence register */
+#define ADC_IDATA0(adcx) REG32((adcx) + 0x3CU) /*!< ADC inserted data register 0 */
+#define ADC_IDATA1(adcx) REG32((adcx) + 0x40U) /*!< ADC inserted data register 1 */
+#define ADC_IDATA2(adcx) REG32((adcx) + 0x44U) /*!< ADC inserted data register 2 */
+#define ADC_IDATA3(adcx) REG32((adcx) + 0x48U) /*!< ADC inserted data register 3 */
+#define ADC_RDATA(adcx) REG32((adcx) + 0x4CU) /*!< ADC regular data register */
+#define ADC_OVSCR(adcx) REG32((adcx) + 0x80U) /*!< ADC oversample control register */
+
+/* bits definitions */
+/* ADC_STAT */
+#define ADC_STAT_WDE BIT(0) /*!< analog watchdog event flag */
+#define ADC_STAT_EOC BIT(1) /*!< end of conversion */
+#define ADC_STAT_EOIC BIT(2) /*!< inserted channel end of conversion */
+#define ADC_STAT_STIC BIT(3) /*!< inserted channel start flag */
+#define ADC_STAT_STRC BIT(4) /*!< regular channel start flag */
+
+/* ADC_CTL0 */
+#define ADC_CTL0_WDCHSEL BITS(0, 4) /*!< analog watchdog channel select bits */
+#define ADC_CTL0_EOCIE BIT(5) /*!< interrupt enable for EOC */
+#define ADC_CTL0_WDEIE BIT(6) /*!< analog watchdog interrupt enable */
+#define ADC_CTL0_EOICIE BIT(7) /*!< interrupt enable for inserted channels */
+#define ADC_CTL0_SM BIT(8) /*!< scan mode */
+#define ADC_CTL0_WDSC BIT(9) /*!< when in scan mode, analog watchdog is effective on a single channel */
+#define ADC_CTL0_ICA BIT(10) /*!< automatic inserted group conversion */
+#define ADC_CTL0_DISRC BIT(11) /*!< discontinuous mode on regular channels */
+#define ADC_CTL0_DISIC BIT(12) /*!< discontinuous mode on inserted channels */
+#define ADC_CTL0_DISNUM BITS(13, 15) /*!< discontinuous mode channel count */
+#define ADC_CTL0_SYNCM BITS(16, 19) /*!< sync mode selection */
+#define ADC_CTL0_IWDEN BIT(22) /*!< analog watchdog enable on inserted channels */
+#define ADC_CTL0_RWDEN BIT(23) /*!< analog watchdog enable on regular channels */
+
+/* ADC_CTL1 */
+#define ADC_CTL1_ADCON BIT(0) /*!< ADC converter on */
+#define ADC_CTL1_CTN BIT(1) /*!< continuous conversion */
+#define ADC_CTL1_CLB BIT(2) /*!< ADC calibration */
+#define ADC_CTL1_RSTCLB BIT(3) /*!< reset calibration */
+#define ADC_CTL1_DMA BIT(8) /*!< direct memory access mode */
+#define ADC_CTL1_DAL BIT(11) /*!< data alignment */
+#define ADC_CTL1_ETSIC BITS(12, 14) /*!< external trigger select for inserted channel */
+#define ADC_CTL1_ETEIC BIT(15) /*!< external trigger enable for inserted channel */
+#define ADC_CTL1_ETSRC BITS(17, 19) /*!< external trigger select for regular channel */
+#define ADC_CTL1_ETERC BIT(20) /*!< external trigger conversion mode for inserted channels */
+#define ADC_CTL1_SWICST BIT(21) /*!< start on inserted channel */
+#define ADC_CTL1_SWRCST BIT(22) /*!< start on regular channel */
+#define ADC_CTL1_TSVREN BIT(23) /*!< channel 16 and 17 enable of ADC0 */
+
+/* ADC_SAMPTx x=0..1 */
+#define ADC_SAMPTX_SPTN BITS(0, 2) /*!< channel n sample time selection */
+
+/* ADC_IOFFx x=0..3 */
+#define ADC_IOFFX_IOFF BITS(0, 11) /*!< data offset for inserted channel x */
+
+/* ADC_WDHT */
+#define ADC_WDHT_WDHT BITS(0, 11) /*!< analog watchdog high threshold */
+
+/* ADC_WDLT */
+#define ADC_WDLT_WDLT BITS(0, 11) /*!< analog watchdog low threshold */
+
+/* ADC_RSQx x=0..2 */
+#define ADC_RSQX_RSQN BITS(0, 4) /*!< nth conversion in regular sequence */
+#define ADC_RSQ0_RL BITS(20, 23) /*!< regular channel sequence length */
+
+/* ADC_ISQ */
+#define ADC_ISQ_ISQN BITS(0, 4) /*!< nth conversion in inserted sequence */
+#define ADC_ISQ_IL BITS(20, 21) /*!< inserted sequence length */
+
+/* ADC_IDATAx x=0..3*/
+#define ADC_IDATAX_IDATAN BITS(0, 15) /*!< inserted data n */
+
+/* ADC_RDATA */
+#define ADC_RDATA_RDATA BITS(0, 15) /*!< regular data */
+#define ADC_RDATA_ADC1RDTR BITS(16, 31) /*!< ADC1 regular channel data */
+
+/* ADC_OVSCR */
+#define ADC_OVSCR_OVSEN BIT(0) /*!< oversampling enable */
+#define ADC_OVSCR_OVSR BITS(2, 4) /*!< oversampling ratio */
+#define ADC_OVSCR_OVSS BITS(5, 8) /*!< oversampling shift */
+#define ADC_OVSCR_TOVS BIT(9) /*!< triggered oversampling */
+#define ADC_OVSCR_DRES BITS(12, 13) /*!< ADC data resolution */
+
+/* constants definitions */
+/* adc_stat register value */
+#define ADC_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog event flag */
+#define ADC_FLAG_EOC ADC_STAT_EOC /*!< end of conversion */
+#define ADC_FLAG_EOIC ADC_STAT_EOIC /*!< inserted channel end of conversion */
+#define ADC_FLAG_STIC ADC_STAT_STIC /*!< inserted channel start flag */
+#define ADC_FLAG_STRC ADC_STAT_STRC /*!< regular channel start flag */
+
+/* adc_ctl0 register value */
+#define CTL0_DISNUM(regval) (BITS(13, 15) & ((uint32_t)(regval) << 13)) /*!< write value to ADC_CTL0_DISNUM bit field */
+
+/* scan mode */
+#define ADC_SCAN_MODE ADC_CTL0_SM /*!< scan mode */
+
+/* inserted channel group convert automatically */
+#define ADC_INSERTED_CHANNEL_AUTO ADC_CTL0_ICA /*!< inserted channel group convert automatically */
+
+/* ADC sync mode */
+#define CTL0_SYNCM(regval) (BITS(16, 19) & ((uint32_t)(regval) << 16)) /*!< write value to ADC_CTL0_SYNCM bit field */
+#define ADC_MODE_FREE CTL0_SYNCM(0) /*!< all the ADCs work independently */
+#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL CTL0_SYNCM(1) /*!< ADC0 and ADC1 work in combined regular parallel + inserted parallel mode */
+#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION CTL0_SYNCM(2) /*!< ADC0 and ADC1 work in combined regular parallel + trigger rotation mode */
+#define ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_FAST CTL0_SYNCM(3) /*!< ADC0 and ADC1 work in combined inserted parallel + follow-up fast mode */
+#define ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_SLOW CTL0_SYNCM(4) /*!< ADC0 and ADC1 work in combined inserted parallel + follow-up slow mode */
+#define ADC_DAUL_INSERTED_PARALLEL CTL0_SYNCM(5) /*!< ADC0 and ADC1 work in inserted parallel mode only */
+#define ADC_DAUL_REGULAL_PARALLEL CTL0_SYNCM(6) /*!< ADC0 and ADC1 work in regular parallel mode only */
+#define ADC_DAUL_REGULAL_FOLLOWUP_FAST CTL0_SYNCM(7) /*!< ADC0 and ADC1 work in follow-up fast mode only */
+#define ADC_DAUL_REGULAL_FOLLOWUP_SLOW CTL0_SYNCM(8) /*!< ADC0 and ADC1 work in follow-up slow mode only */
+#define ADC_DAUL_INSERTED_TRIGGER_ROTATION CTL0_SYNCM(9) /*!< ADC0 and ADC1 work in trigger rotation mode only */
+
+/* adc_ctl1 register value */
+#define ADC_DATAALIGN_RIGHT ((uint32_t)0x00000000U) /*!< LSB alignment */
+#define ADC_DATAALIGN_LEFT ADC_CTL1_DAL /*!< MSB alignment */
+
+/* continuous mode */
+#define ADC_CONTINUOUS_MODE ADC_CTL1_CTN /*!< continuous mode */
+
+/* external trigger select for regular channel */
+#define CTL1_ETSRC(regval) (BITS(17, 19) & ((uint32_t)(regval) << 17)) /*!< write value to ADC_CTL1_ETSRC bit field */
+/* for ADC0 and ADC1 regular channel */
+#define ADC0_1_EXTTRIG_REGULAR_T0_CH0 CTL1_ETSRC(0) /*!< TIMER0 CH0 event select */
+#define ADC0_1_EXTTRIG_REGULAR_T0_CH1 CTL1_ETSRC(1) /*!< TIMER0 CH1 event select */
+#define ADC0_1_EXTTRIG_REGULAR_T0_CH2 CTL1_ETSRC(2) /*!< TIMER0 CH2 event select */
+#define ADC0_1_EXTTRIG_REGULAR_T1_CH1 CTL1_ETSRC(3) /*!< TIMER1 CH1 event select */
+#define ADC0_1_EXTTRIG_REGULAR_T2_TRGO CTL1_ETSRC(4) /*!< TIMER2 TRGO event select */
+#define ADC0_1_EXTTRIG_REGULAR_T3_CH3 CTL1_ETSRC(5) /*!< TIMER3 CH3 event select */
+#define ADC0_1_EXTTRIG_REGULAR_EXTI_11 CTL1_ETSRC(6) /*!< external interrupt line 11 */
+#define ADC0_1_EXTTRIG_REGULAR_NONE CTL1_ETSRC(7) /*!< software trigger */
+
+/* external trigger mode for inserted channel */
+#define CTL1_ETSIC(regval) (BITS(12, 14) & ((uint32_t)(regval) << 12)) /*!< write value to ADC_CTL1_ETSIC bit field */
+/* for ADC0 and ADC1 inserted channel */
+#define ADC0_1_EXTTRIG_INSERTED_T0_TRGO CTL1_ETSIC(0) /*!< TIMER0 TRGO event select */
+#define ADC0_1_EXTTRIG_INSERTED_T0_CH3 CTL1_ETSIC(1) /*!< TIMER0 CH3 event select */
+#define ADC0_1_EXTTRIG_INSERTED_T1_TRGO CTL1_ETSIC(2) /*!< TIMER1 TRGO event select */
+#define ADC0_1_EXTTRIG_INSERTED_T1_CH0 CTL1_ETSIC(3) /*!< TIMER1 CH0 event select */
+#define ADC0_1_EXTTRIG_INSERTED_T2_CH3 CTL1_ETSIC(4) /*!< TIMER2 CH3 event select */
+#define ADC0_1_EXTTRIG_INSERTED_T3_TRGO CTL1_ETSIC(5) /*!< TIMER3 TRGO event select */
+#define ADC0_1_EXTTRIG_INSERTED_EXTI_15 CTL1_ETSIC(6) /*!< external interrupt line 15 */
+#define ADC0_1_EXTTRIG_INSERTED_NONE CTL1_ETSIC(7) /*!< software trigger */
+
+/* adc_samptx register value */
+#define SAMPTX_SPT(regval) (BITS(0, 2) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_SAMPTX_SPT bit field */
+#define ADC_SAMPLETIME_1POINT5 SAMPTX_SPT(0) /*!< 1.5 sampling cycles */
+#define ADC_SAMPLETIME_7POINT5 SAMPTX_SPT(1) /*!< 7.5 sampling cycles */
+#define ADC_SAMPLETIME_13POINT5 SAMPTX_SPT(2) /*!< 13.5 sampling cycles */
+#define ADC_SAMPLETIME_28POINT5 SAMPTX_SPT(3) /*!< 28.5 sampling cycles */
+#define ADC_SAMPLETIME_41POINT5 SAMPTX_SPT(4) /*!< 41.5 sampling cycles */
+#define ADC_SAMPLETIME_55POINT5 SAMPTX_SPT(5) /*!< 55.5 sampling cycles */
+#define ADC_SAMPLETIME_71POINT5 SAMPTX_SPT(6) /*!< 71.5 sampling cycles */
+#define ADC_SAMPLETIME_239POINT5 SAMPTX_SPT(7) /*!< 239.5 sampling cycles */
+
+/* adc_ioffx register value */
+#define IOFFX_IOFF(regval) (BITS(0, 11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_IOFFX_IOFF bit field */
+
+/* adc_wdht register value */
+#define WDHT_WDHT(regval) (BITS(0, 11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_WDHT_WDHT bit field */
+
+/* adc_wdlt register value */
+#define WDLT_WDLT(regval) (BITS(0, 11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_WDLT_WDLT bit field */
+
+/* adc_rsqx register value */
+#define RSQ0_RL(regval) (BITS(20, 23) & ((uint32_t)(regval) << 20)) /*!< write value to ADC_RSQ0_RL bit field */
+
+/* adc_isq register value */
+#define ISQ_IL(regval) (BITS(20, 21) & ((uint32_t)(regval) << 20)) /*!< write value to ADC_ISQ_IL bit field */
+
+/* ADC channel group definitions */
+#define ADC_REGULAR_CHANNEL ((uint8_t)0x01U) /*!< adc regular channel group */
+#define ADC_INSERTED_CHANNEL ((uint8_t)0x02U) /*!< adc inserted channel group */
+#define ADC_REGULAR_INSERTED_CHANNEL ((uint8_t)0x03U) /*!< both regular and inserted channel group */
+
+#define ADC_CHANNEL_DISCON_DISABLE ((uint8_t)0x04U) /*!< disable discontinuous mode of regular & inserted channel */
+
+/* ADC inserted channel definitions */
+#define ADC_INSERTED_CHANNEL_0 ((uint8_t)0x00U) /*!< adc inserted channel 0 */
+#define ADC_INSERTED_CHANNEL_1 ((uint8_t)0x01U) /*!< adc inserted channel 1 */
+#define ADC_INSERTED_CHANNEL_2 ((uint8_t)0x02U) /*!< adc inserted channel 2 */
+#define ADC_INSERTED_CHANNEL_3 ((uint8_t)0x03U) /*!< adc inserted channel 3 */
+
+/* ADC channel definitions */
+#define ADC_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC channel 0 */
+#define ADC_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC channel 1 */
+#define ADC_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC channel 2 */
+#define ADC_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC channel 3 */
+#define ADC_CHANNEL_4 ((uint8_t)0x04U) /*!< ADC channel 4 */
+#define ADC_CHANNEL_5 ((uint8_t)0x05U) /*!< ADC channel 5 */
+#define ADC_CHANNEL_6 ((uint8_t)0x06U) /*!< ADC channel 6 */
+#define ADC_CHANNEL_7 ((uint8_t)0x07U) /*!< ADC channel 7 */
+#define ADC_CHANNEL_8 ((uint8_t)0x08U) /*!< ADC channel 8 */
+#define ADC_CHANNEL_9 ((uint8_t)0x09U) /*!< ADC channel 9 */
+#define ADC_CHANNEL_10 ((uint8_t)0x0AU) /*!< ADC channel 10 */
+#define ADC_CHANNEL_11 ((uint8_t)0x0BU) /*!< ADC channel 11 */
+#define ADC_CHANNEL_12 ((uint8_t)0x0CU) /*!< ADC channel 12 */
+#define ADC_CHANNEL_13 ((uint8_t)0x0DU) /*!< ADC channel 13 */
+#define ADC_CHANNEL_14 ((uint8_t)0x0EU) /*!< ADC channel 14 */
+#define ADC_CHANNEL_15 ((uint8_t)0x0FU) /*!< ADC channel 15 */
+#define ADC_CHANNEL_16 ((uint8_t)0x10U) /*!< ADC channel 16 */
+#define ADC_CHANNEL_17 ((uint8_t)0x11U) /*!< ADC channel 17 */
+
+/* ADC interrupt */
+#define ADC_INT_WDE ADC_STAT_WDE /*!< analog watchdog event interrupt */
+#define ADC_INT_EOC ADC_STAT_EOC /*!< end of group conversion interrupt */
+#define ADC_INT_EOIC ADC_STAT_EOIC /*!< end of inserted group conversion interrupt */
+
+/* ADC interrupt flag */
+#define ADC_INT_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog event interrupt flag */
+#define ADC_INT_FLAG_EOC ADC_STAT_EOC /*!< end of group conversion interrupt flag */
+#define ADC_INT_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted group conversion interrupt flag */
+
+/* ADC resolution definitions */
+#define OVSCR_DRES(regval) (BITS(12, 13) & ((uint32_t)(regval) << 12))
+#define ADC_RESOLUTION_12B OVSCR_DRES(0) /*!< 12-bit ADC resolution */
+#define ADC_RESOLUTION_10B OVSCR_DRES(1) /*!< 10-bit ADC resolution */
+#define ADC_RESOLUTION_8B OVSCR_DRES(2) /*!< 8-bit ADC resolution */
+#define ADC_RESOLUTION_6B OVSCR_DRES(3) /*!< 6-bit ADC resolution */
+
+/* ADC oversampling mode */
+#define ADC_OVERSAMPLING_ALL_CONVERT 0 /*!< all oversampled conversions for a channel are done consecutively after a trigger */
+#define ADC_OVERSAMPLING_ONE_CONVERT 1 /*!< each oversampled conversion for a channel needs a trigger */
+
+/* ADC oversampling shift */
+#define OVSCR_OVSS(regval) (BITS(5, 8) & ((uint32_t)(regval) << 5))
+#define ADC_OVERSAMPLING_SHIFT_NONE OVSCR_OVSS(0) /*!< no oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_1B OVSCR_OVSS(1) /*!< 1-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_2B OVSCR_OVSS(2) /*!< 2-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_3B OVSCR_OVSS(3) /*!< 3-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_4B OVSCR_OVSS(4) /*!< 4-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_5B OVSCR_OVSS(5) /*!< 5-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_6B OVSCR_OVSS(6) /*!< 6-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_7B OVSCR_OVSS(7) /*!< 7-bit oversampling shift */
+#define ADC_OVERSAMPLING_SHIFT_8B OVSCR_OVSS(8) /*!< 8-bit oversampling shift */
+
+/* ADC oversampling ratio */
+#define OVSCR_OVSR(regval) (BITS(2, 4) & ((uint32_t)(regval) << 2))
+#define ADC_OVERSAMPLING_RATIO_MUL2 OVSCR_OVSR(0) /*!< oversampling ratio X2 */
+#define ADC_OVERSAMPLING_RATIO_MUL4 OVSCR_OVSR(1) /*!< oversampling ratio X4 */
+#define ADC_OVERSAMPLING_RATIO_MUL8 OVSCR_OVSR(2) /*!< oversampling ratio X8 */
+#define ADC_OVERSAMPLING_RATIO_MUL16 OVSCR_OVSR(3) /*!< oversampling ratio X16 */
+#define ADC_OVERSAMPLING_RATIO_MUL32 OVSCR_OVSR(4) /*!< oversampling ratio X32 */
+#define ADC_OVERSAMPLING_RATIO_MUL64 OVSCR_OVSR(5) /*!< oversampling ratio X64 */
+#define ADC_OVERSAMPLING_RATIO_MUL128 OVSCR_OVSR(6) /*!< oversampling ratio X128 */
+#define ADC_OVERSAMPLING_RATIO_MUL256 OVSCR_OVSR(7) /*!< oversampling ratio X256 */
+
+/* function declarations */
+/* initialization config */
+/* reset ADC */
+void adc_deinit(uint32_t adc_periph);
+/* configure the ADC sync mode */
+void adc_mode_config(uint32_t mode);
+/* enable or disable ADC special function */
+void adc_special_function_config(uint32_t adc_periph, uint32_t function, ControlStatus newvalue);
+/* configure ADC data alignment */
+void adc_data_alignment_config(uint32_t adc_periph, uint32_t data_alignment);
+/* enable ADC interface */
+void adc_enable(uint32_t adc_periph);
+/* disable ADC interface */
+void adc_disable(uint32_t adc_periph);
+/* ADC calibration and reset calibration */
+void adc_calibration_enable(uint32_t adc_periph);
+/* enable the temperature sensor and Vrefint channel */
+void adc_tempsensor_vrefint_enable(void);
+/* disable the temperature sensor and Vrefint channel */
+void adc_tempsensor_vrefint_disable(void);
+
+/* DMA config */
+/* enable DMA request */
+void adc_dma_mode_enable(uint32_t adc_periph);
+/* disable DMA request */
+void adc_dma_mode_disable(uint32_t adc_periph);
+
+/* regular group and inserted group config */
+/* configure ADC discontinuous mode */
+void adc_discontinuous_mode_config(uint32_t adc_periph, uint8_t adc_channel_group, uint8_t length);
+
+/* configure the length of regular channel group or inserted channel group */
+void adc_channel_length_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t length);
+/* configure ADC regular channel */
+void adc_regular_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time);
+/* configure ADC inserted channel */
+void adc_inserted_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time);
+/* configure ADC inserted channel offset */
+void adc_inserted_channel_offset_config(uint32_t adc_periph, uint8_t inserted_channel, uint16_t offset);
+
+/* configure ADC external trigger source */
+void adc_external_trigger_source_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t external_trigger_source);
+/* configure ADC external trigger */
+void adc_external_trigger_config(uint32_t adc_periph, uint8_t adc_channel_group, ControlStatus newvalue);
+/* enable ADC software trigger */
+void adc_software_trigger_enable(uint32_t adc_periph, uint8_t adc_channel_group);
+
+/* get channel data */
+/* read ADC regular group data register */
+uint16_t adc_regular_data_read(uint32_t adc_periph);
+/* read ADC inserted group data register */
+uint16_t adc_inserted_data_read(uint32_t adc_periph, uint8_t inserted_channel);
+/* read the last ADC0 and ADC1 conversion result data in sync mode */
+uint32_t adc_sync_mode_convert_value_read(void);
+
+/* watchdog config */
+/* configure ADC analog watchdog single channel */
+void adc_watchdog_single_channel_enable(uint32_t adc_periph, uint8_t adc_channel);
+/* configure ADC analog watchdog group channel */
+void adc_watchdog_group_channel_enable(uint32_t adc_periph, uint8_t adc_channel_group);
+/* disable ADC analog watchdog */
+void adc_watchdog_disable(uint32_t adc_periph);
+/* configure ADC analog watchdog threshold */
+void adc_watchdog_threshold_config(uint32_t adc_periph, uint16_t low_threshold, uint16_t high_threshold);
+
+/* interrupt & flag functions */
+/* get the ADC flag bits */
+FlagStatus adc_flag_get(uint32_t adc_periph, uint32_t adc_flag);
+/* clear the ADC flag bits */
+void adc_flag_clear(uint32_t adc_periph, uint32_t adc_flag);
+/* get the bit state of ADCx software start conversion */
+FlagStatus adc_regular_software_startconv_flag_get(uint32_t adc_periph);
+/* get the bit state of ADCx software inserted channel start conversion */
+FlagStatus adc_inserted_software_startconv_flag_get(uint32_t adc_periph);
+/* get the ADC interrupt bits */
+FlagStatus adc_interrupt_flag_get(uint32_t adc_periph, uint32_t adc_interrupt);
+/* clear the ADC flag */
+void adc_interrupt_flag_clear(uint32_t adc_periph, uint32_t adc_interrupt);
+/* enable ADC interrupt */
+void adc_interrupt_enable(uint32_t adc_periph, uint32_t adc_interrupt);
+/* disable ADC interrupt */
+void adc_interrupt_disable(uint32_t adc_periph, uint32_t adc_interrupt);
+
+/* ADC resolution & oversample */
+/* ADC resolution config */
+void adc_resolution_config(uint32_t adc_periph, uint32_t resolution);
+/* ADC oversample mode config */
+void adc_oversample_mode_config(uint32_t adc_periph, uint8_t mode, uint16_t shift, uint8_t ratio);
+/* enable ADC oversample mode */
+void adc_oversample_mode_enable(uint32_t adc_periph);
+/* disable ADC oversample mode */
+void adc_oversample_mode_disable(uint32_t adc_periph);
+
+#endif /* GD32VF103_ADC_H */
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_bkp.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_bkp.h index ea270229..8c5540b3 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_bkp.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_bkp.h @@ -2,11 +2,12 @@ \file gd32vf103_bkp.h
\brief definitions for the BKP
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -36,8 +37,6 @@ OF SUCH DAMAGE. #define GD32VF103_BKP_H
#include "gd32vf103.h"
-#include "gd32vf103_dbg.h"
-#include "gd32vf103_rcu.h"
/* BKP definitions */
#define BKP BKP_BASE /*!< BKP base address */
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_can.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_can.h deleted file mode 100644 index e24aa4ea..00000000 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_can.h +++ /dev/null @@ -1,714 +0,0 @@ -/*!
- \file gd32vf103_can.h
- \brief definitions for the CAN
-
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
-*/
-
-/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
-
- Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- 3. Neither the name of the copyright holder nor the names of its contributors
- may be used to endorse or promote products derived from this software without
- specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-#ifndef GD32VF103_CAN_H
-#define GD32VF103_CAN_H
-
-#include "gd32vf103.h"
-#include "gd32vf103_dbg.h"
-#include "gd32vf103_rcu.h"
-
-/* CAN definitions */
-#define CAN0 CAN_BASE /*!< CAN0 base address */
-#define CAN1 (CAN0 + 0x00000400U) /*!< CAN1 base address */
-
-/* registers definitions */
-#define CAN_CTL(canx) REG32((canx) + 0x00U) /*!< CAN control register */
-#define CAN_STAT(canx) REG32((canx) + 0x04U) /*!< CAN status register */
-#define CAN_TSTAT(canx) REG32((canx) + 0x08U) /*!< CAN transmit status register*/
-#define CAN_RFIFO0(canx) REG32((canx) + 0x0CU) /*!< CAN receive FIFO0 register */
-#define CAN_RFIFO1(canx) REG32((canx) + 0x10U) /*!< CAN receive FIFO1 register */
-#define CAN_INTEN(canx) REG32((canx) + 0x14U) /*!< CAN interrupt enable register */
-#define CAN_ERR(canx) REG32((canx) + 0x18U) /*!< CAN error register */
-#define CAN_BT(canx) REG32((canx) + 0x1CU) /*!< CAN bit timing register */
-#define CAN_TMI0(canx) REG32((canx) + 0x180U) /*!< CAN transmit mailbox0 identifier register */
-#define CAN_TMP0(canx) REG32((canx) + 0x184U) /*!< CAN transmit mailbox0 property register */
-#define CAN_TMDATA00(canx) REG32((canx) + 0x188U) /*!< CAN transmit mailbox0 data0 register */
-#define CAN_TMDATA10(canx) REG32((canx) + 0x18CU) /*!< CAN transmit mailbox0 data1 register */
-#define CAN_TMI1(canx) REG32((canx) + 0x190U) /*!< CAN transmit mailbox1 identifier register */
-#define CAN_TMP1(canx) REG32((canx) + 0x194U) /*!< CAN transmit mailbox1 property register */
-#define CAN_TMDATA01(canx) REG32((canx) + 0x198U) /*!< CAN transmit mailbox1 data0 register */
-#define CAN_TMDATA11(canx) REG32((canx) + 0x19CU) /*!< CAN transmit mailbox1 data1 register */
-#define CAN_TMI2(canx) REG32((canx) + 0x1A0U) /*!< CAN transmit mailbox2 identifier register */
-#define CAN_TMP2(canx) REG32((canx) + 0x1A4U) /*!< CAN transmit mailbox2 property register */
-#define CAN_TMDATA02(canx) REG32((canx) + 0x1A8U) /*!< CAN transmit mailbox2 data0 register */
-#define CAN_TMDATA12(canx) REG32((canx) + 0x1ACU) /*!< CAN transmit mailbox2 data1 register */
-#define CAN_RFIFOMI0(canx) REG32((canx) + 0x1B0U) /*!< CAN receive FIFO0 mailbox identifier register */
-#define CAN_RFIFOMP0(canx) REG32((canx) + 0x1B4U) /*!< CAN receive FIFO0 mailbox property register */
-#define CAN_RFIFOMDATA00(canx) REG32((canx) + 0x1B8U) /*!< CAN receive FIFO0 mailbox data0 register */
-#define CAN_RFIFOMDATA10(canx) REG32((canx) + 0x1BCU) /*!< CAN receive FIFO0 mailbox data1 register */
-#define CAN_RFIFOMI1(canx) REG32((canx) + 0x1C0U) /*!< CAN receive FIFO1 mailbox identifier register */
-#define CAN_RFIFOMP1(canx) REG32((canx) + 0x1C4U) /*!< CAN receive FIFO1 mailbox property register */
-#define CAN_RFIFOMDATA01(canx) REG32((canx) + 0x1C8U) /*!< CAN receive FIFO1 mailbox data0 register */
-#define CAN_RFIFOMDATA11(canx) REG32((canx) + 0x1CCU) /*!< CAN receive FIFO1 mailbox data1 register */
-#define CAN_FCTL(canx) REG32((canx) + 0x200U) /*!< CAN filter control register */
-#define CAN_FMCFG(canx) REG32((canx) + 0x204U) /*!< CAN filter mode register */
-#define CAN_FSCFG(canx) REG32((canx) + 0x20CU) /*!< CAN filter scale register */
-#define CAN_FAFIFO(canx) REG32((canx) + 0x214U) /*!< CAN filter associated FIFO register */
-#define CAN_FW(canx) REG32((canx) + 0x21CU) /*!< CAN filter working register */
-#define CAN_F0DATA0(canx) REG32((canx) + 0x240U) /*!< CAN filter 0 data 0 register */
-#define CAN_F1DATA0(canx) REG32((canx) + 0x248U) /*!< CAN filter 1 data 0 register */
-#define CAN_F2DATA0(canx) REG32((canx) + 0x250U) /*!< CAN filter 2 data 0 register */
-#define CAN_F3DATA0(canx) REG32((canx) + 0x258U) /*!< CAN filter 3 data 0 register */
-#define CAN_F4DATA0(canx) REG32((canx) + 0x260U) /*!< CAN filter 4 data 0 register */
-#define CAN_F5DATA0(canx) REG32((canx) + 0x268U) /*!< CAN filter 5 data 0 register */
-#define CAN_F6DATA0(canx) REG32((canx) + 0x270U) /*!< CAN filter 6 data 0 register */
-#define CAN_F7DATA0(canx) REG32((canx) + 0x278U) /*!< CAN filter 7 data 0 register */
-#define CAN_F8DATA0(canx) REG32((canx) + 0x280U) /*!< CAN filter 8 data 0 register */
-#define CAN_F9DATA0(canx) REG32((canx) + 0x288U) /*!< CAN filter 9 data 0 register */
-#define CAN_F10DATA0(canx) REG32((canx) + 0x290U) /*!< CAN filter 10 data 0 register */
-#define CAN_F11DATA0(canx) REG32((canx) + 0x298U) /*!< CAN filter 11 data 0 register */
-#define CAN_F12DATA0(canx) REG32((canx) + 0x2A0U) /*!< CAN filter 12 data 0 register */
-#define CAN_F13DATA0(canx) REG32((canx) + 0x2A8U) /*!< CAN filter 13 data 0 register */
-#define CAN_F14DATA0(canx) REG32((canx) + 0x2B0U) /*!< CAN filter 14 data 0 register */
-#define CAN_F15DATA0(canx) REG32((canx) + 0x2B8U) /*!< CAN filter 15 data 0 register */
-#define CAN_F16DATA0(canx) REG32((canx) + 0x2C0U) /*!< CAN filter 16 data 0 register */
-#define CAN_F17DATA0(canx) REG32((canx) + 0x2C8U) /*!< CAN filter 17 data 0 register */
-#define CAN_F18DATA0(canx) REG32((canx) + 0x2D0U) /*!< CAN filter 18 data 0 register */
-#define CAN_F19DATA0(canx) REG32((canx) + 0x2D8U) /*!< CAN filter 19 data 0 register */
-#define CAN_F20DATA0(canx) REG32((canx) + 0x2E0U) /*!< CAN filter 20 data 0 register */
-#define CAN_F21DATA0(canx) REG32((canx) + 0x2E8U) /*!< CAN filter 21 data 0 register */
-#define CAN_F22DATA0(canx) REG32((canx) + 0x2F0U) /*!< CAN filter 22 data 0 register */
-#define CAN_F23DATA0(canx) REG32((canx) + 0x3F8U) /*!< CAN filter 23 data 0 register */
-#define CAN_F24DATA0(canx) REG32((canx) + 0x300U) /*!< CAN filter 24 data 0 register */
-#define CAN_F25DATA0(canx) REG32((canx) + 0x308U) /*!< CAN filter 25 data 0 register */
-#define CAN_F26DATA0(canx) REG32((canx) + 0x310U) /*!< CAN filter 26 data 0 register */
-#define CAN_F27DATA0(canx) REG32((canx) + 0x318U) /*!< CAN filter 27 data 0 register */
-#define CAN_F0DATA1(canx) REG32((canx) + 0x244U) /*!< CAN filter 0 data 1 register */
-#define CAN_F1DATA1(canx) REG32((canx) + 0x24CU) /*!< CAN filter 1 data 1 register */
-#define CAN_F2DATA1(canx) REG32((canx) + 0x254U) /*!< CAN filter 2 data 1 register */
-#define CAN_F3DATA1(canx) REG32((canx) + 0x25CU) /*!< CAN filter 3 data 1 register */
-#define CAN_F4DATA1(canx) REG32((canx) + 0x264U) /*!< CAN filter 4 data 1 register */
-#define CAN_F5DATA1(canx) REG32((canx) + 0x26CU) /*!< CAN filter 5 data 1 register */
-#define CAN_F6DATA1(canx) REG32((canx) + 0x274U) /*!< CAN filter 6 data 1 register */
-#define CAN_F7DATA1(canx) REG32((canx) + 0x27CU) /*!< CAN filter 7 data 1 register */
-#define CAN_F8DATA1(canx) REG32((canx) + 0x284U) /*!< CAN filter 8 data 1 register */
-#define CAN_F9DATA1(canx) REG32((canx) + 0x28CU) /*!< CAN filter 9 data 1 register */
-#define CAN_F10DATA1(canx) REG32((canx) + 0x294U) /*!< CAN filter 10 data 1 register */
-#define CAN_F11DATA1(canx) REG32((canx) + 0x29CU) /*!< CAN filter 11 data 1 register */
-#define CAN_F12DATA1(canx) REG32((canx) + 0x2A4U) /*!< CAN filter 12 data 1 register */
-#define CAN_F13DATA1(canx) REG32((canx) + 0x2ACU) /*!< CAN filter 13 data 1 register */
-#define CAN_F14DATA1(canx) REG32((canx) + 0x2B4U) /*!< CAN filter 14 data 1 register */
-#define CAN_F15DATA1(canx) REG32((canx) + 0x2BCU) /*!< CAN filter 15 data 1 register */
-#define CAN_F16DATA1(canx) REG32((canx) + 0x2C4U) /*!< CAN filter 16 data 1 register */
-#define CAN_F17DATA1(canx) REG32((canx) + 0x24CU) /*!< CAN filter 17 data 1 register */
-#define CAN_F18DATA1(canx) REG32((canx) + 0x2D4U) /*!< CAN filter 18 data 1 register */
-#define CAN_F19DATA1(canx) REG32((canx) + 0x2DCU) /*!< CAN filter 19 data 1 register */
-#define CAN_F20DATA1(canx) REG32((canx) + 0x2E4U) /*!< CAN filter 20 data 1 register */
-#define CAN_F21DATA1(canx) REG32((canx) + 0x2ECU) /*!< CAN filter 21 data 1 register */
-#define CAN_F22DATA1(canx) REG32((canx) + 0x2F4U) /*!< CAN filter 22 data 1 register */
-#define CAN_F23DATA1(canx) REG32((canx) + 0x2FCU) /*!< CAN filter 23 data 1 register */
-#define CAN_F24DATA1(canx) REG32((canx) + 0x304U) /*!< CAN filter 24 data 1 register */
-#define CAN_F25DATA1(canx) REG32((canx) + 0x30CU) /*!< CAN filter 25 data 1 register */
-#define CAN_F26DATA1(canx) REG32((canx) + 0x314U) /*!< CAN filter 26 data 1 register */
-#define CAN_F27DATA1(canx) REG32((canx) + 0x31CU) /*!< CAN filter 27 data 1 register */
-
-/* CAN transmit mailbox bank */
-#define CAN_TMI(canx, bank) REG32((canx) + 0x180U + ((bank)*0x10U)) /*!< CAN transmit mailbox identifier register */
-#define CAN_TMP(canx, bank) REG32((canx) + 0x184U + ((bank)*0x10U)) /*!< CAN transmit mailbox property register */
-#define CAN_TMDATA0(canx, bank) REG32((canx) + 0x188U + ((bank)*0x10U)) /*!< CAN transmit mailbox data0 register */
-#define CAN_TMDATA1(canx, bank) REG32((canx) + 0x18CU + ((bank)*0x10U)) /*!< CAN transmit mailbox data1 register */
-
-/* CAN filter bank */
-#define CAN_FDATA0(canx, bank) REG32((canx) + 0x240U + ((bank)*0x8U) + 0x0U) /*!< CAN filter data 0 register */
-#define CAN_FDATA1(canx, bank) REG32((canx) + 0x240U + ((bank)*0x8U) + 0x4U) /*!< CAN filter data 1 register */
-
-/* CAN receive fifo mailbox bank */
-#define CAN_RFIFOMI(canx, bank) REG32((canx) + 0x1B0U + ((bank)*0x10U)) /*!< CAN receive FIFO mailbox identifier register */
-#define CAN_RFIFOMP(canx, bank) REG32((canx) + 0x1B4U + ((bank)*0x10U)) /*!< CAN receive FIFO mailbox property register */
-#define CAN_RFIFOMDATA0(canx, bank) REG32((canx) + 0x1B8U + ((bank)*0x10U)) /*!< CAN receive FIFO mailbox data0 register */
-#define CAN_RFIFOMDATA1(canx, bank) REG32((canx) + 0x1BCU + ((bank)*0x10U)) /*!< CAN receive FIFO mailbox data1 register */
-
-/* bits definitions */
-/* CAN_CTL */
-#define CAN_CTL_IWMOD BIT(0) /*!< initial working mode */
-#define CAN_CTL_SLPWMOD BIT(1) /*!< sleep working mode */
-#define CAN_CTL_TFO BIT(2) /*!< transmit FIFO order */
-#define CAN_CTL_RFOD BIT(3) /*!< receive FIFO overwrite disable */
-#define CAN_CTL_ARD BIT(4) /*!< automatic retransmission disable */
-#define CAN_CTL_AWU BIT(5) /*!< automatic wakeup */
-#define CAN_CTL_ABOR BIT(6) /*!< automatic bus-off recovery */
-#define CAN_CTL_TTC BIT(7) /*!< time triggered communication */
-#define CAN_CTL_SWRST BIT(15) /*!< CAN software reset */
-#define CAN_CTL_DFZ BIT(16) /*!< CAN debug freeze */
-
-/* CAN_STAT */
-#define CAN_STAT_IWS BIT(0) /*!< initial working state */
-#define CAN_STAT_SLPWS BIT(1) /*!< sleep working state */
-#define CAN_STAT_ERRIF BIT(2) /*!< error interrupt flag*/
-#define CAN_STAT_WUIF BIT(3) /*!< status change interrupt flag of wakeup from sleep working mode */
-#define CAN_STAT_SLPIF BIT(4) /*!< status change interrupt flag of sleep working mode entering */
-#define CAN_STAT_TS BIT(8) /*!< transmitting state */
-#define CAN_STAT_RS BIT(9) /*!< receiving state */
-#define CAN_STAT_LASTRX BIT(10) /*!< last sample value of rx pin */
-#define CAN_STAT_RXL BIT(11) /*!< CAN rx signal */
-
-/* CAN_TSTAT */
-#define CAN_TSTAT_MTF0 BIT(0) /*!< mailbox0 transmit finished */
-#define CAN_TSTAT_MTFNERR0 BIT(1) /*!< mailbox0 transmit finished and no error */
-#define CAN_TSTAT_MAL0 BIT(2) /*!< mailbox0 arbitration lost */
-#define CAN_TSTAT_MTE0 BIT(3) /*!< mailbox0 transmit error */
-#define CAN_TSTAT_MST0 BIT(7) /*!< mailbox0 stop transmitting */
-#define CAN_TSTAT_MTF1 BIT(8) /*!< mailbox1 transmit finished */
-#define CAN_TSTAT_MTFNERR1 BIT(9) /*!< mailbox1 transmit finished and no error */
-#define CAN_TSTAT_MAL1 BIT(10) /*!< mailbox1 arbitration lost */
-#define CAN_TSTAT_MTE1 BIT(11) /*!< mailbox1 transmit error */
-#define CAN_TSTAT_MST1 BIT(15) /*!< mailbox1 stop transmitting */
-#define CAN_TSTAT_MTF2 BIT(16) /*!< mailbox2 transmit finished */
-#define CAN_TSTAT_MTFNERR2 BIT(17) /*!< mailbox2 transmit finished and no error */
-#define CAN_TSTAT_MAL2 BIT(18) /*!< mailbox2 arbitration lost */
-#define CAN_TSTAT_MTE2 BIT(19) /*!< mailbox2 transmit error */
-#define CAN_TSTAT_MST2 BIT(23) /*!< mailbox2 stop transmitting */
-#define CAN_TSTAT_NUM BITS(24, 25) /*!< mailbox number */
-#define CAN_TSTAT_TME0 BIT(26) /*!< transmit mailbox0 empty */
-#define CAN_TSTAT_TME1 BIT(27) /*!< transmit mailbox1 empty */
-#define CAN_TSTAT_TME2 BIT(28) /*!< transmit mailbox2 empty */
-#define CAN_TSTAT_TMLS0 BIT(29) /*!< last sending priority flag for mailbox0 */
-#define CAN_TSTAT_TMLS1 BIT(30) /*!< last sending priority flag for mailbox1 */
-#define CAN_TSTAT_TMLS2 BIT(31) /*!< last sending priority flag for mailbox2 */
-
-/* CAN_RFIFO0 */
-#define CAN_RFIFO0_RFL0 BITS(0, 1) /*!< receive FIFO0 length */
-#define CAN_RFIFO0_RFF0 BIT(3) /*!< receive FIFO0 full */
-#define CAN_RFIFO0_RFO0 BIT(4) /*!< receive FIFO0 overfull */
-#define CAN_RFIFO0_RFD0 BIT(5) /*!< receive FIFO0 dequeue */
-
-/* CAN_RFIFO1 */
-#define CAN_RFIFO1_RFL1 BITS(0, 1) /*!< receive FIFO1 length */
-#define CAN_RFIFO1_RFF1 BIT(3) /*!< receive FIFO1 full */
-#define CAN_RFIFO1_RFO1 BIT(4) /*!< receive FIFO1 overfull */
-#define CAN_RFIFO1_RFD1 BIT(5) /*!< receive FIFO1 dequeue */
-
-/* CAN_INTEN */
-#define CAN_INTEN_TMEIE BIT(0) /*!< transmit mailbox empty interrupt enable */
-#define CAN_INTEN_RFNEIE0 BIT(1) /*!< receive FIFO0 not empty interrupt enable */
-#define CAN_INTEN_RFFIE0 BIT(2) /*!< receive FIFO0 full interrupt enable */
-#define CAN_INTEN_RFOIE0 BIT(3) /*!< receive FIFO0 overfull interrupt enable */
-#define CAN_INTEN_RFNEIE1 BIT(4) /*!< receive FIFO1 not empty interrupt enable */
-#define CAN_INTEN_RFFIE1 BIT(5) /*!< receive FIFO1 full interrupt enable */
-#define CAN_INTEN_RFOIE1 BIT(6) /*!< receive FIFO1 overfull interrupt enable */
-#define CAN_INTEN_WERRIE BIT(8) /*!< warning error interrupt enable */
-#define CAN_INTEN_PERRIE BIT(9) /*!< passive error interrupt enable */
-#define CAN_INTEN_BOIE BIT(10) /*!< bus-off interrupt enable */
-#define CAN_INTEN_ERRNIE BIT(11) /*!< error number interrupt enable */
-#define CAN_INTEN_ERRIE BIT(15) /*!< error interrupt enable */
-#define CAN_INTEN_WIE BIT(16) /*!< wakeup interrupt enable */
-#define CAN_INTEN_SLPWIE BIT(17) /*!< sleep working interrupt enable */
-
-/* CAN_ERR */
-#define CAN_ERR_WERR BIT(0) /*!< warning error */
-#define CAN_ERR_PERR BIT(1) /*!< passive error */
-#define CAN_ERR_BOERR BIT(2) /*!< bus-off error */
-#define CAN_ERR_ERRN BITS(4, 6) /*!< error number */
-#define CAN_ERR_TECNT BITS(16, 23) /*!< transmit error count */
-#define CAN_ERR_RECNT BITS(24, 31) /*!< receive error count */
-
-/* CAN_BT */
-#define CAN_BT_BAUDPSC BITS(0, 9) /*!< baudrate prescaler */
-#define CAN_BT_BS1 BITS(16, 19) /*!< bit segment 1 */
-#define CAN_BT_BS2 BITS(20, 22) /*!< bit segment 2 */
-#define CAN_BT_SJW BITS(24, 25) /*!< resynchronization jump width */
-#define CAN_BT_LCMOD BIT(30) /*!< loopback communication mode */
-#define CAN_BT_SCMOD BIT(31) /*!< silent communication mode */
-
-/* CAN_TMIx */
-#define CAN_TMI_TEN BIT(0) /*!< transmit enable */
-#define CAN_TMI_FT BIT(1) /*!< frame type */
-#define CAN_TMI_FF BIT(2) /*!< frame format */
-#define CAN_TMI_EFID BITS(3, 31) /*!< the frame identifier */
-#define CAN_TMI_SFID BITS(21, 31) /*!< the frame identifier */
-
-/* CAN_TMPx */
-#define CAN_TMP_DLENC BITS(0, 3) /*!< data length code */
-#define CAN_TMP_TSEN BIT(8) /*!< time stamp enable */
-#define CAN_TMP_TS BITS(16, 31) /*!< time stamp */
-
-/* CAN_TMDATA0x */
-#define CAN_TMDATA0_DB0 BITS(0, 7) /*!< transmit data byte 0 */
-#define CAN_TMDATA0_DB1 BITS(8, 15) /*!< transmit data byte 1 */
-#define CAN_TMDATA0_DB2 BITS(16, 23) /*!< transmit data byte 2 */
-#define CAN_TMDATA0_DB3 BITS(24, 31) /*!< transmit data byte 3 */
-
-/* CAN_TMDATA1x */
-#define CAN_TMDATA1_DB4 BITS(0, 7) /*!< transmit data byte 4 */
-#define CAN_TMDATA1_DB5 BITS(8, 15) /*!< transmit data byte 5 */
-#define CAN_TMDATA1_DB6 BITS(16, 23) /*!< transmit data byte 6 */
-#define CAN_TMDATA1_DB7 BITS(24, 31) /*!< transmit data byte 7 */
-
-/* CAN_RFIFOMIx */
-#define CAN_RFIFOMI_FT BIT(1) /*!< frame type */
-#define CAN_RFIFOMI_FF BIT(2) /*!< frame format */
-#define CAN_RFIFOMI_EFID BITS(3, 31) /*!< the frame identifier */
-#define CAN_RFIFOMI_SFID BITS(21, 31) /*!< the frame identifier */
-
-/* CAN_RFIFOMPx */
-#define CAN_RFIFOMP_DLENC BITS(0, 3) /*!< receive data length code */
-#define CAN_RFIFOMP_FI BITS(8, 15) /*!< filter index */
-#define CAN_RFIFOMP_TS BITS(16, 31) /*!< time stamp */
-
-/* CAN_RFIFOMDATA0x */
-#define CAN_RFIFOMDATA0_DB0 BITS(0, 7) /*!< receive data byte 0 */
-#define CAN_RFIFOMDATA0_DB1 BITS(8, 15) /*!< receive data byte 1 */
-#define CAN_RFIFOMDATA0_DB2 BITS(16, 23) /*!< receive data byte 2 */
-#define CAN_RFIFOMDATA0_DB3 BITS(24, 31) /*!< receive data byte 3 */
-
-/* CAN_RFIFOMDATA1x */
-#define CAN_RFIFOMDATA1_DB4 BITS(0, 7) /*!< receive data byte 4 */
-#define CAN_RFIFOMDATA1_DB5 BITS(8, 15) /*!< receive data byte 5 */
-#define CAN_RFIFOMDATA1_DB6 BITS(16, 23) /*!< receive data byte 6 */
-#define CAN_RFIFOMDATA1_DB7 BITS(24, 31) /*!< receive data byte 7 */
-
-/* CAN_FCTL */
-#define CAN_FCTL_FLD BIT(0) /*!< filter lock disable */
-#define CAN_FCTL_HBC1F BITS(8, 13) /*!< header bank of CAN1 filter */
-
-/* CAN_FMCFG */
-#define CAN_FMCFG_FMOD(regval) BIT(regval) /*!< filter mode, list or mask*/
-
-/* CAN_FSCFG */
-#define CAN_FSCFG_FS(regval) BIT(regval) /*!< filter scale, 32 bits or 16 bits*/
-
-/* CAN_FAFIFO */
-#define CAN_FAFIFOR_FAF(regval) BIT(regval) /*!< filter associated with FIFO */
-
-/* CAN_FW */
-#define CAN_FW_FW(regval) BIT(regval) /*!< filter working */
-
-/* CAN_FxDATAy */
-#define CAN_FDATA_FD(regval) BIT(regval) /*!< filter data */
-
-/* consts definitions */
-/* define the CAN bit position and its register index offset */
-#define CAN_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))
-#define CAN_REG_VAL(canx, offset) (REG32((canx) + ((uint32_t)(offset) >> 6)))
-#define CAN_BIT_POS(val) ((uint32_t)(val)&0x1FU)
-
-#define CAN_REGIDX_BITS(regidx, bitpos0, bitpos1) (((uint32_t)(regidx) << 12) | ((uint32_t)(bitpos0) << 6) | (uint32_t)(bitpos1))
-#define CAN_REG_VALS(canx, offset) (REG32((canx) + ((uint32_t)(offset) >> 12)))
-#define CAN_BIT_POS0(val) (((uint32_t)(val) >> 6) & 0x1FU)
-#define CAN_BIT_POS1(val) ((uint32_t)(val)&0x1FU)
-
-/* register offset */
-#define STAT_REG_OFFSET ((uint8_t)0x04U) /*!< STAT register offset */
-#define TSTAT_REG_OFFSET ((uint8_t)0x08U) /*!< TSTAT register offset */
-#define RFIFO0_REG_OFFSET ((uint8_t)0x0CU) /*!< RFIFO0 register offset */
-#define RFIFO1_REG_OFFSET ((uint8_t)0x10U) /*!< RFIFO1 register offset */
-#define ERR_REG_OFFSET ((uint8_t)0x18U) /*!< ERR register offset */
-
-/* CAN flags */
-typedef enum {
- /* flags in TSTAT register */
- CAN_FLAG_MTE2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 19U), /*!< mailbox 2 transmit error */
- CAN_FLAG_MTE1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 11U), /*!< mailbox 1 transmit error */
- CAN_FLAG_MTE0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 3U), /*!< mailbox 0 transmit error */
- CAN_FLAG_MTF2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 16U), /*!< mailbox 2 transmit finished */
- CAN_FLAG_MTF1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 8U), /*!< mailbox 1 transmit finished */
- CAN_FLAG_MTF0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 0U), /*!< mailbox 0 transmit finished */
- /* flags in RFIFO0 register */
- CAN_FLAG_RFO0 = CAN_REGIDX_BIT(RFIFO0_REG_OFFSET, 4U), /*!< receive FIFO0 overfull */
- CAN_FLAG_RFF0 = CAN_REGIDX_BIT(RFIFO0_REG_OFFSET, 3U), /*!< receive FIFO0 full */
- /* flags in RFIFO1 register */
- CAN_FLAG_RFO1 = CAN_REGIDX_BIT(RFIFO1_REG_OFFSET, 4U), /*!< receive FIFO1 overfull */
- CAN_FLAG_RFF1 = CAN_REGIDX_BIT(RFIFO1_REG_OFFSET, 3U), /*!< receive FIFO1 full */
- /* flags in ERR register */
- CAN_FLAG_BOERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 2U), /*!< bus-off error */
- CAN_FLAG_PERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 1U), /*!< passive error */
- CAN_FLAG_WERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 0U), /*!< warning error */
-} can_flag_enum;
-
-/* CAN interrupt flags */
-typedef enum {
- /* interrupt flags in STAT register */
- CAN_INT_FLAG_SLPIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 4U, 17U), /*!< status change interrupt flag of sleep working mode entering */
- CAN_INT_FLAG_WUIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 3U, 16), /*!< status change interrupt flag of wakeup from sleep working mode */
- CAN_INT_FLAG_ERRIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 2U, 15), /*!< error interrupt flag */
- /* interrupt flags in TSTAT register */
- CAN_INT_FLAG_MTF2 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 16U, 0U), /*!< mailbox 2 transmit finished interrupt flag */
- CAN_INT_FLAG_MTF1 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 8U, 0U), /*!< mailbox 1 transmit finished interrupt flag */
- CAN_INT_FLAG_MTF0 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 0U, 0U), /*!< mailbox 0 transmit finished interrupt flag */
- /* interrupt flags in RFIFO0 register */
- CAN_INT_FLAG_RFO0 = CAN_REGIDX_BITS(RFIFO0_REG_OFFSET, 4U, 3U), /*!< receive FIFO0 overfull interrupt flag */
- CAN_INT_FLAG_RFF0 = CAN_REGIDX_BITS(RFIFO0_REG_OFFSET, 3U, 2U), /*!< receive FIFO0 full interrupt flag */
- /* interrupt flags in RFIFO0 register */
- CAN_INT_FLAG_RFO1 = CAN_REGIDX_BITS(RFIFO1_REG_OFFSET, 4U, 6U), /*!< receive FIFO1 overfull interrupt flag */
- CAN_INT_FLAG_RFF1 = CAN_REGIDX_BITS(RFIFO1_REG_OFFSET, 3U, 5U), /*!< receive FIFO1 full interrupt flag */
-} can_interrupt_flag_enum;
-
-/* CAN initiliaze parameters struct */
-typedef struct {
- uint8_t working_mode; /*!< CAN working mode */
- uint8_t resync_jump_width; /*!< CAN resynchronization jump width */
- uint8_t time_segment_1; /*!< time segment 1 */
- uint8_t time_segment_2; /*!< time segment 2 */
- ControlStatus time_triggered; /*!< time triggered communication mode */
- ControlStatus auto_bus_off_recovery; /*!< automatic bus-off recovery */
- ControlStatus auto_wake_up; /*!< automatic wake-up mode */
- ControlStatus no_auto_retrans; /*!< automatic retransmission mode disable */
- ControlStatus rec_fifo_overwrite; /*!< receive FIFO overwrite mode */
- ControlStatus trans_fifo_order; /*!< transmit FIFO order */
- uint16_t prescaler; /*!< baudrate prescaler */
-} can_parameter_struct;
-
-/* CAN transmit message struct */
-typedef struct {
- uint32_t tx_sfid; /*!< standard format frame identifier */
- uint32_t tx_efid; /*!< extended format frame identifier */
- uint8_t tx_ff; /*!< format of frame, standard or extended format */
- uint8_t tx_ft; /*!< type of frame, data or remote */
- uint8_t tx_dlen; /*!< data length */
- uint8_t tx_data[8]; /*!< transmit data */
-} can_trasnmit_message_struct;
-
-/* CAN receive message struct */
-typedef struct {
- uint32_t rx_sfid; /*!< standard format frame identifier */
- uint32_t rx_efid; /*!< extended format frame identifier */
- uint8_t rx_ff; /*!< format of frame, standard or extended format */
- uint8_t rx_ft; /*!< type of frame, data or remote */
- uint8_t rx_dlen; /*!< data length */
- uint8_t rx_data[8]; /*!< receive data */
- uint8_t rx_fi; /*!< filtering index */
-} can_receive_message_struct;
-
-/* CAN filter parameters struct */
-typedef struct {
- uint16_t filter_list_high; /*!< filter list number high bits*/
- uint16_t filter_list_low; /*!< filter list number low bits */
- uint16_t filter_mask_high; /*!< filter mask number high bits */
- uint16_t filter_mask_low; /*!< filter mask number low bits */
- uint16_t filter_fifo_number; /*!< receive FIFO associated with the filter */
- uint16_t filter_number; /*!< filter number */
- uint16_t filter_mode; /*!< filter mode, list or mask */
- uint16_t filter_bits; /*!< filter scale */
- ControlStatus filter_enable; /*!< filter work or not */
-} can_filter_parameter_struct;
-
-/* CAN errors */
-typedef enum {
- CAN_ERROR_NONE = 0, /*!< no error */
- CAN_ERROR_FILL, /*!< fill error */
- CAN_ERROR_FORMATE, /*!< format error */
- CAN_ERROR_ACK, /*!< ACK error */
- CAN_ERROR_BITRECESSIVE, /*!< bit recessive error */
- CAN_ERROR_BITDOMINANTER, /*!< bit dominant error */
- CAN_ERROR_CRC, /*!< CRC error */
- CAN_ERROR_SOFTWARECFG, /*!< software configure */
-} can_error_enum;
-
-/* transmit states */
-typedef enum {
- CAN_TRANSMIT_FAILED = 0, /*!< CAN transmitted failure */
- CAN_TRANSMIT_OK = 1, /*!< CAN transmitted success */
- CAN_TRANSMIT_PENDING = 2, /*!< CAN transmitted pending */
- CAN_TRANSMIT_NOMAILBOX = 4, /*!< no empty mailbox to be used for CAN */
-} can_transmit_state_enum;
-
-typedef enum {
- CAN_INIT_STRUCT = 0, /* CAN initiliaze parameters struct */
- CAN_FILTER_STRUCT, /* CAN filter parameters struct */
- CAN_TX_MESSAGE_STRUCT, /* CAN transmit message struct */
- CAN_RX_MESSAGE_STRUCT, /* CAN receive message struct */
-} can_struct_type_enum;
-
-/* CAN baudrate prescaler*/
-#define BT_BAUDPSC(regval) (BITS(0, 9) & ((uint32_t)(regval) << 0))
-
-/* CAN bit segment 1*/
-#define BT_BS1(regval) (BITS(16, 19) & ((uint32_t)(regval) << 16))
-
-/* CAN bit segment 2*/
-#define BT_BS2(regval) (BITS(20, 22) & ((uint32_t)(regval) << 20))
-
-/* CAN resynchronization jump width*/
-#define BT_SJW(regval) (BITS(24, 25) & ((uint32_t)(regval) << 24))
-
-/* CAN communication mode*/
-#define BT_MODE(regval) (BITS(30, 31) & ((uint32_t)(regval) << 30))
-
-/* CAN FDATA high 16 bits */
-#define FDATA_MASK_HIGH(regval) (BITS(16, 31) & ((uint32_t)(regval) << 16))
-
-/* CAN FDATA low 16 bits */
-#define FDATA_MASK_LOW(regval) (BITS(0, 15) & ((uint32_t)(regval) << 0))
-
-/* CAN1 filter start bank_number*/
-#define FCTL_HBC1F(regval) (BITS(8, 13) & ((uint32_t)(regval) << 8))
-
-/* CAN transmit mailbox extended identifier*/
-#define TMI_EFID(regval) (BITS(3, 31) & ((uint32_t)(regval) << 3))
-
-/* CAN transmit mailbox standard identifier*/
-#define TMI_SFID(regval) (BITS(21, 31) & ((uint32_t)(regval) << 21))
-
-/* transmit data byte 0 */
-#define TMDATA0_DB0(regval) (BITS(0, 7) & ((uint32_t)(regval) << 0))
-
-/* transmit data byte 1 */
-#define TMDATA0_DB1(regval) (BITS(8, 15) & ((uint32_t)(regval) << 8))
-
-/* transmit data byte 2 */
-#define TMDATA0_DB2(regval) (BITS(16, 23) & ((uint32_t)(regval) << 16))
-
-/* transmit data byte 3 */
-#define TMDATA0_DB3(regval) (BITS(24, 31) & ((uint32_t)(regval) << 24))
-
-/* transmit data byte 4 */
-#define TMDATA1_DB4(regval) (BITS(0, 7) & ((uint32_t)(regval) << 0))
-
-/* transmit data byte 5 */
-#define TMDATA1_DB5(regval) (BITS(8, 15) & ((uint32_t)(regval) << 8))
-
-/* transmit data byte 6 */
-#define TMDATA1_DB6(regval) (BITS(16, 23) & ((uint32_t)(regval) << 16))
-
-/* transmit data byte 7 */
-#define TMDATA1_DB7(regval) (BITS(24, 31) & ((uint32_t)(regval) << 24))
-
-/* receive mailbox extended identifier*/
-#define GET_RFIFOMI_EFID(regval) GET_BITS((uint32_t)(regval), 3, 31)
-
-/* receive mailbox standrad identifier*/
-#define GET_RFIFOMI_SFID(regval) GET_BITS((uint32_t)(regval), 21, 31)
-
-/* receive data length */
-#define GET_RFIFOMP_DLENC(regval) GET_BITS((uint32_t)(regval), 0, 3)
-
-/* the index of the filter by which the frame is passed */
-#define GET_RFIFOMP_FI(regval) GET_BITS((uint32_t)(regval), 8, 15)
-
-/* receive data byte 0 */
-#define GET_RFIFOMDATA0_DB0(regval) GET_BITS((uint32_t)(regval), 0, 7)
-
-/* receive data byte 1 */
-#define GET_RFIFOMDATA0_DB1(regval) GET_BITS((uint32_t)(regval), 8, 15)
-
-/* receive data byte 2 */
-#define GET_RFIFOMDATA0_DB2(regval) GET_BITS((uint32_t)(regval), 16, 23)
-
-/* receive data byte 3 */
-#define GET_RFIFOMDATA0_DB3(regval) GET_BITS((uint32_t)(regval), 24, 31)
-
-/* receive data byte 4 */
-#define GET_RFIFOMDATA1_DB4(regval) GET_BITS((uint32_t)(regval), 0, 7)
-
-/* receive data byte 5 */
-#define GET_RFIFOMDATA1_DB5(regval) GET_BITS((uint32_t)(regval), 8, 15)
-
-/* receive data byte 6 */
-#define GET_RFIFOMDATA1_DB6(regval) GET_BITS((uint32_t)(regval), 16, 23)
-
-/* receive data byte 7 */
-#define GET_RFIFOMDATA1_DB7(regval) GET_BITS((uint32_t)(regval), 24, 31)
-
-/* error number */
-#define GET_ERR_ERRN(regval) GET_BITS((uint32_t)(regval), 4, 6)
-
-/* transmit error count */
-#define GET_ERR_TECNT(regval) GET_BITS((uint32_t)(regval), 16, 23)
-
-/* receive error count */
-#define GET_ERR_RECNT(regval) GET_BITS((uint32_t)(regval), 24, 31)
-
-/* CAN errors */
-#define ERR_ERRN(regval) (BITS(4, 6) & ((uint32_t)(regval) << 4))
-#define CAN_ERRN_0 ERR_ERRN(0) /* no error */
-#define CAN_ERRN_1 ERR_ERRN(1) /*!< fill error */
-#define CAN_ERRN_2 ERR_ERRN(2) /*!< format error */
-#define CAN_ERRN_3 ERR_ERRN(3) /*!< ACK error */
-#define CAN_ERRN_4 ERR_ERRN(4) /*!< bit recessive error */
-#define CAN_ERRN_5 ERR_ERRN(5) /*!< bit dominant error */
-#define CAN_ERRN_6 ERR_ERRN(6) /*!< CRC error */
-#define CAN_ERRN_7 ERR_ERRN(7) /*!< software error */
-
-#define CAN_STATE_PENDING ((uint32_t)0x00000000U) /*!< CAN pending */
-
-/* CAN communication mode */
-#define CAN_NORMAL_MODE ((uint8_t)0x00U) /*!< normal communication mode */
-#define CAN_LOOPBACK_MODE ((uint8_t)0x01U) /*!< loopback communication mode */
-#define CAN_SILENT_MODE ((uint8_t)0x02U) /*!< silent communication mode */
-#define CAN_SILENT_LOOPBACK_MODE ((uint8_t)0x03U) /*!< loopback and silent communication mode */
-
-/* CAN resynchronisation jump width */
-#define CAN_BT_SJW_1TQ ((uint8_t)0x00U) /*!< 1 time quanta */
-#define CAN_BT_SJW_2TQ ((uint8_t)0x01U) /*!< 2 time quanta */
-#define CAN_BT_SJW_3TQ ((uint8_t)0x02U) /*!< 3 time quanta */
-#define CAN_BT_SJW_4TQ ((uint8_t)0x03U) /*!< 4 time quanta */
-
-/* CAN time segment 1 */
-#define CAN_BT_BS1_1TQ ((uint8_t)0x00U) /*!< 1 time quanta */
-#define CAN_BT_BS1_2TQ ((uint8_t)0x01U) /*!< 2 time quanta */
-#define CAN_BT_BS1_3TQ ((uint8_t)0x02U) /*!< 3 time quanta */
-#define CAN_BT_BS1_4TQ ((uint8_t)0x03U) /*!< 4 time quanta */
-#define CAN_BT_BS1_5TQ ((uint8_t)0x04U) /*!< 5 time quanta */
-#define CAN_BT_BS1_6TQ ((uint8_t)0x05U) /*!< 6 time quanta */
-#define CAN_BT_BS1_7TQ ((uint8_t)0x06U) /*!< 7 time quanta */
-#define CAN_BT_BS1_8TQ ((uint8_t)0x07U) /*!< 8 time quanta */
-#define CAN_BT_BS1_9TQ ((uint8_t)0x08U) /*!< 9 time quanta */
-#define CAN_BT_BS1_10TQ ((uint8_t)0x09U) /*!< 10 time quanta */
-#define CAN_BT_BS1_11TQ ((uint8_t)0x0AU) /*!< 11 time quanta */
-#define CAN_BT_BS1_12TQ ((uint8_t)0x0BU) /*!< 12 time quanta */
-#define CAN_BT_BS1_13TQ ((uint8_t)0x0CU) /*!< 13 time quanta */
-#define CAN_BT_BS1_14TQ ((uint8_t)0x0DU) /*!< 14 time quanta */
-#define CAN_BT_BS1_15TQ ((uint8_t)0x0EU) /*!< 15 time quanta */
-#define CAN_BT_BS1_16TQ ((uint8_t)0x0FU) /*!< 16 time quanta */
-
-/* CAN time segment 2 */
-#define CAN_BT_BS2_1TQ ((uint8_t)0x00U) /*!< 1 time quanta */
-#define CAN_BT_BS2_2TQ ((uint8_t)0x01U) /*!< 2 time quanta */
-#define CAN_BT_BS2_3TQ ((uint8_t)0x02U) /*!< 3 time quanta */
-#define CAN_BT_BS2_4TQ ((uint8_t)0x03U) /*!< 4 time quanta */
-#define CAN_BT_BS2_5TQ ((uint8_t)0x04U) /*!< 5 time quanta */
-#define CAN_BT_BS2_6TQ ((uint8_t)0x05U) /*!< 6 time quanta */
-#define CAN_BT_BS2_7TQ ((uint8_t)0x06U) /*!< 7 time quanta */
-#define CAN_BT_BS2_8TQ ((uint8_t)0x07U) /*!< 8 time quanta */
-
-/* CAN mailbox number */
-#define CAN_MAILBOX0 ((uint8_t)0x00U) /*!< mailbox0 */
-#define CAN_MAILBOX1 ((uint8_t)0x01U) /*!< mailbox1 */
-#define CAN_MAILBOX2 ((uint8_t)0x02U) /*!< mailbox2 */
-#define CAN_NOMAILBOX ((uint8_t)0x03U) /*!< no mailbox empty */
-
-/* CAN frame format */
-#define CAN_FF_STANDARD ((uint32_t)0x00000000U) /*!< standard frame */
-#define CAN_FF_EXTENDED ((uint32_t)0x00000004U) /*!< extended frame */
-
-/* CAN receive fifo */
-#define CAN_FIFO0 ((uint8_t)0x00U) /*!< receive FIFO0 */
-#define CAN_FIFO1 ((uint8_t)0x01U) /*!< receive FIFO1 */
-
-/* frame number of receive fifo */
-#define CAN_RFIF_RFL_MASK ((uint32_t)0x00000003U) /*!< mask for frame number in receive FIFOx */
-
-#define CAN_SFID_MASK ((uint32_t)0x000007FFU) /*!< mask of standard identifier */
-#define CAN_EFID_MASK ((uint32_t)0x1FFFFFFFU) /*!< mask of extended identifier */
-
-/* CAN working mode */
-#define CAN_MODE_INITIALIZE ((uint8_t)0x01U) /*!< CAN initialize mode */
-#define CAN_MODE_NORMAL ((uint8_t)0x02U) /*!< CAN normal mode */
-#define CAN_MODE_SLEEP ((uint8_t)0x04U) /*!< CAN sleep mode */
-
-/* filter bits */
-#define CAN_FILTERBITS_16BIT ((uint8_t)0x00U) /*!< CAN filter 16 bits */
-#define CAN_FILTERBITS_32BIT ((uint8_t)0x01U) /*!< CAN filter 32 bits */
-
-/* filter mode */
-#define CAN_FILTERMODE_MASK ((uint8_t)0x00U) /*!< mask mode */
-#define CAN_FILTERMODE_LIST ((uint8_t)0x01U) /*!< list mode */
-
-/* filter 16 bits mask */
-#define CAN_FILTER_MASK_16BITS ((uint32_t)0x0000FFFFU) /*!< can filter 16 bits mask */
-
-/* frame type */
-#define CAN_FT_DATA ((uint32_t)0x00000000U) /*!< data frame */
-#define CAN_FT_REMOTE ((uint32_t)0x00000002U) /*!< remote frame */
-
-/* CAN timeout */
-#define CAN_TIMEOUT ((uint32_t)0x0000FFFFU) /*!< timeout value */
-
-/* interrupt enable bits */
-#define CAN_INT_TME CAN_INTEN_TMEIE /*!< transmit mailbox empty interrupt enable */
-#define CAN_INT_RFNE0 CAN_INTEN_RFNEIE0 /*!< receive FIFO0 not empty interrupt enable */
-#define CAN_INT_RFF0 CAN_INTEN_RFFIE0 /*!< receive FIFO0 full interrupt enable */
-#define CAN_INT_RFO0 CAN_INTEN_RFOIE0 /*!< receive FIFO0 overfull interrupt enable */
-#define CAN_INT_RFNE1 CAN_INTEN_RFNEIE1 /*!< receive FIFO1 not empty interrupt enable */
-#define CAN_INT_RFF1 CAN_INTEN_RFFIE1 /*!< receive FIFO1 full interrupt enable */
-#define CAN_INT_RFO1 CAN_INTEN_RFOIE1 /*!< receive FIFO1 overfull interrupt enable */
-#define CAN_INT_WERR CAN_INTEN_WERRIE /*!< warning error interrupt enable */
-#define CAN_INT_PERR CAN_INTEN_PERRIE /*!< passive error interrupt enable */
-#define CAN_INT_BO CAN_INTEN_BOIE /*!< bus-off interrupt enable */
-#define CAN_INT_ERRN CAN_INTEN_ERRNIE /*!< error number interrupt enable */
-#define CAN_INT_ERR CAN_INTEN_ERRIE /*!< error interrupt enable */
-#define CAN_INT_WAKEUP CAN_INTEN_WIE /*!< wakeup interrupt enable */
-#define CAN_INT_SLPW CAN_INTEN_SLPWIE /*!< sleep working interrupt enable */
-
-/* function declarations */
-/* deinitialize CAN */
-void can_deinit(uint32_t can_periph);
-/* initialize CAN struct */
-void can_struct_para_init(can_struct_type_enum type, void *p_struct);
-/* initialize CAN */
-ErrStatus can_init(uint32_t can_periph, can_parameter_struct *can_parameter_init);
-/* CAN filter init */
-void can_filter_init(can_filter_parameter_struct *can_filter_parameter_init);
-/* set can1 fliter start bank number */
-void can1_filter_start_bank(uint8_t start_bank);
-/* enable functions */
-/* CAN debug freeze enable */
-void can_debug_freeze_enable(uint32_t can_periph);
-/* CAN debug freeze disable */
-void can_debug_freeze_disable(uint32_t can_periph);
-/* CAN time trigger mode enable */
-void can_time_trigger_mode_enable(uint32_t can_periph);
-/* CAN time trigger mode disable */
-void can_time_trigger_mode_disable(uint32_t can_periph);
-
-/* transmit functions */
-/* transmit CAN message */
-uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct *transmit_message);
-/* get CAN transmit state */
-can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox_number);
-/* stop CAN transmission */
-void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number);
-/* CAN receive message */
-void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct *receive_message);
-/* CAN release fifo */
-void can_fifo_release(uint32_t can_periph, uint8_t fifo_number);
-/* CAN receive message length */
-uint8_t can_receive_message_length_get(uint32_t can_periph, uint8_t fifo_number);
-/* CAN working mode */
-ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode);
-/* CAN wakeup from sleep mode */
-ErrStatus can_wakeup(uint32_t can_periph);
-
-/* CAN get error */
-can_error_enum can_error_get(uint32_t can_periph);
-/* get CAN receive error number */
-uint8_t can_receive_error_number_get(uint32_t can_periph);
-/* get CAN transmit error number */
-uint8_t can_transmit_error_number_get(uint32_t can_periph);
-
-/* CAN interrupt enable */
-void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt);
-/* CAN interrupt disable */
-void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt);
-/* CAN get flag state */
-FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag);
-/* CAN clear flag state */
-void can_flag_clear(uint32_t can_periph, can_flag_enum flag);
-/* CAN get interrupt flag state */
-FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag);
-/* CAN clear interrupt flag state */
-void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum flag);
-
-#endif /* GD32VF103_CAN_H */
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_crc.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_crc.h index e5863643..bf4e7adf 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_crc.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_crc.h @@ -1,13 +1,13 @@ /*!
- \file gd32vf103_crc.h
- \brief definitions for the CRC
+ \file gd32vf103_crc.h
+ \brief definitions for the CRC
-
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -37,8 +37,6 @@ OF SUCH DAMAGE. #define GD32VF103_CRC_H
#include "gd32vf103.h"
-#include "gd32vf103_dbg.h"
-#include "gd32vf103_rcu.h"
/* CRC definitions */
#define CRC CRC_BASE
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_dac.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_dac.h index 4627b4ec..82b9b83d 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_dac.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_dac.h @@ -2,11 +2,12 @@ \file gd32vf103_dac.h
\brief definitions for the DAC
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -36,8 +37,6 @@ OF SUCH DAMAGE. #define GD32VF103_DAC_H
#include "gd32vf103.h"
-#include "gd32vf103_dbg.h"
-#include "gd32vf103_rcu.h"
/* DACx(x=0,1) definitions */
#define DAC DAC_BASE
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_dbg.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_dbg.h index 889ff6d1..d780638e 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_dbg.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_dbg.h @@ -1,12 +1,13 @@ /*!
- \file gd32vf103_dbg.h
- \brief definitions for the DBG
+ \file gd32vf103_dbg.h
+ \brief definitions for the DBG
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -36,7 +37,6 @@ OF SUCH DAMAGE. #define GD32VF103_DBG_H
#include "gd32vf103.h"
-#include "gd32vf103_rcu.h"
/* DBG definitions */
#define DBG DBG_BASE
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_dma.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_dma.h index 5c070a1d..47e863d0 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_dma.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_dma.h @@ -2,11 +2,13 @@ \file gd32vf103_dma.h
\brief definitions for the DMA
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2019-10-30, V1.0.1, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -36,11 +38,7 @@ OF SUCH DAMAGE. #define GD32VF103_DMA_H
#include "gd32vf103.h"
-#include "gd32vf103_dbg.h"
-#include "gd32vf103_rcu.h"
-#ifdef _cplusplus
-extern "C" {
-#endif
+
/* DMA definitions */
#define DMA0 (DMA_BASE) /*!< DMA0 base address */
#define DMA1 (DMA_BASE + 0x0400U) /*!< DMA1 base address */
@@ -181,16 +179,16 @@ typedef struct { #define DMA_INT_ERR DMA_CHXCTL_ERRIE /*!< enable bit for channel error interrupt */
/* transfer direction */
-#define DMA_PERIPHERAL_TO_MEMORY ((uint8_t)0x0000U) /*!< read from peripheral and write to memory */
-#define DMA_MEMORY_TO_PERIPHERAL ((uint8_t)0x0001U) /*!< read from memory and write to peripheral */
+#define DMA_PERIPHERAL_TO_MEMORY ((uint8_t)0x00U) /*!< read from peripheral and write to memory */
+#define DMA_MEMORY_TO_PERIPHERAL ((uint8_t)0x01U) /*!< read from memory and write to peripheral */
/* peripheral increasing mode */
-#define DMA_PERIPH_INCREASE_DISABLE ((uint8_t)0x0000U) /*!< next address of peripheral is fixed address mode */
-#define DMA_PERIPH_INCREASE_ENABLE ((uint8_t)0x0001U) /*!< next address of peripheral is increasing address mode */
+#define DMA_PERIPH_INCREASE_DISABLE ((uint8_t)0x00U) /*!< next address of peripheral is fixed address mode */
+#define DMA_PERIPH_INCREASE_ENABLE ((uint8_t)0x01U) /*!< next address of peripheral is increasing address mode */
/* memory increasing mode */
-#define DMA_MEMORY_INCREASE_DISABLE ((uint8_t)0x0000U) /*!< next address of memory is fixed address mode */
-#define DMA_MEMORY_INCREASE_ENABLE ((uint8_t)0x0001U) /*!< next address of memory is increasing address mode */
+#define DMA_MEMORY_INCREASE_DISABLE ((uint8_t)0x00U) /*!< next address of memory is fixed address mode */
+#define DMA_MEMORY_INCREASE_ENABLE ((uint8_t)0x01U) /*!< next address of memory is increasing address mode */
/* transfer data size of peripheral */
#define CHCTL_PWIDTH(regval) (BITS(8, 9) & ((uint32_t)(regval) << 8)) /*!< transfer data size of peripheral */
@@ -264,7 +262,7 @@ void dma_periph_increase_enable(uint32_t dma_periph, dma_channel_enum channelx); /* disable next address increasement algorithm of peripheral */
void dma_periph_increase_disable(uint32_t dma_periph, dma_channel_enum channelx);
/* configure the direction of data transfer on the channel */
-void dma_transfer_direction_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t direction);
+void dma_transfer_direction_config(uint32_t dma_periph, dma_channel_enum channelx, uint8_t direction);
/* flag and interrupt functions */
/* check DMA flag is set or not */
@@ -279,8 +277,5 @@ void dma_interrupt_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, ui void dma_interrupt_enable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source);
/* disable DMA interrupt */
void dma_interrupt_disable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source);
-#ifdef _cplusplus
-}
-#endif
#endif /* GD32VF103_DMA_H */
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_eclic.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_eclic.h index 6e555085..12d559bf 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_eclic.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_eclic.h @@ -1,12 +1,13 @@ /*!
- \file gd32vf103_eclic.h
- \brief definitions for the ECLIC(Enhancement Core-Local Interrupt Controller)
+ \file gd32vf103_eclic.h
+ \brief definitions for the ECLIC(Enhancement Core-Local Interrupt Controller)
\version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -31,9 +32,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
+
#ifndef GD32VF103_ECLIC_H
#define GD32VF103_ECLIC_H
@@ -49,8 +48,12 @@ extern "C" { #define __SEV eclic_send_event
/* function declarations */
+/* enable the global interrupt */
+void eclic_global_interrupt_enable(void);
+/* disable the global interrupt */
+void eclic_global_interrupt_disable(void);
/* set the priority group */
-void eclic_priority_group_set(uint32_t prigroup);
+void eclic_priority_group_set(uint8_t prigroup);
/* enable the interrupt request */
void eclic_irq_enable(uint32_t source, uint8_t level, uint8_t priority);
/* disable the interrupt request */
@@ -62,6 +65,3 @@ void eclic_system_reset(void); void eclic_send_event(void);
#endif /* GD32VF103_ECLIC_H */
-#ifdef __cplusplus
-}
-#endif
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_exmc.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_exmc.h index ba7088b8..ea56006d 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_exmc.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_exmc.h @@ -1,12 +1,13 @@ /*!
- \file gd32vf103_exmc.h
- \brief definitions for the EXMC
+ \file gd32vf103_exmc.h
+ \brief definitions for the EXMC
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -36,8 +37,6 @@ OF SUCH DAMAGE. #define GD32VF103_EXMC_H
#include "gd32vf103.h"
-#include "gd32vf103_dbg.h"
-#include "gd32vf103_rcu.h"
/* EXMC definitions */
#define EXMC (EXMC_BASE) /*!< EXMC register base address */
@@ -79,13 +78,13 @@ typedef struct { /* EXMC NOR/SRAM initialize struct */
typedef struct {
uint32_t norsram_region; /*!< select the region of EXMC NOR/SRAM bank */
- uint32_t asyn_wait; /*!< enable or disable the asynchronous wait function */
- uint32_t nwait_signal; /*!< enable or disable the NWAIT signal */
- uint32_t memory_write; /*!< enable or disable the write operation */
+ ControlStatus asyn_wait; /*!< enable or disable the asynchronous wait function */
+ ControlStatus nwait_signal; /*!< enable or disable the NWAIT signal */
+ ControlStatus memory_write; /*!< enable or disable the write operation */
uint32_t nwait_polarity; /*!< specifies the polarity of NWAIT signal from memory */
uint32_t databus_width; /*!< specifies the databus width of external memory */
uint32_t memory_type; /*!< specifies the type of external memory */
- uint32_t address_data_mux; /*!< specifies whether the data bus and address bus are multiplexed */
+ ControlStatus address_data_mux; /*!< specifies whether the data bus and address bus are multiplexed */
exmc_norsram_timing_parameter_struct *read_write_timing; /*!< timing parameters for read and write */
} exmc_norsram_parameter_struct;
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_exti.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_exti.h index 9a4f8b7a..de7e724f 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_exti.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_exti.h @@ -2,11 +2,12 @@ \file gd32vf103_exti.h
\brief definitions for the EXTI
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -36,8 +37,6 @@ OF SUCH DAMAGE. #define GD32VF103_EXTI_H
#include "gd32vf103.h"
-#include "gd32vf103_dbg.h"
-#include "gd32vf103_rcu.h"
/* EXTI definitions */
#define EXTI EXTI_BASE
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_fmc.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_fmc.h index 0150ece3..d3fc8ffc 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_fmc.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_fmc.h @@ -1,12 +1,15 @@ /*!
- \file gd32vf103_fmc.h
- \brief definitions for the FMC
+ \file gd32vf103_fmc.h
+ \brief definitions for the FMC
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2019-09-18, V1.0.1, firmware for GD32VF103
+ \version 2020-02-20, V1.0.2, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -36,8 +39,6 @@ OF SUCH DAMAGE. #define GD32VF103_FMC_H
#include "gd32vf103.h"
-#include "gd32vf103_dbg.h"
-#include "gd32vf103_rcu.h"
/* FMC and option byte definition */
#define FMC FMC_BASE /*!< FMC register base address */
@@ -45,11 +46,11 @@ OF SUCH DAMAGE. /* registers definitions */
#define FMC_WS REG32((FMC) + 0x00U) /*!< FMC wait state register */
-#define FMC_KEY0 REG32((FMC) + 0x04U) /*!< FMC unlock key register 0 */
+#define FMC_KEY REG32((FMC) + 0x04U) /*!< FMC unlock key register */
#define FMC_OBKEY REG32((FMC) + 0x08U) /*!< FMC option bytes unlock key register */
-#define FMC_STAT0 REG32((FMC) + 0x0CU) /*!< FMC status register 0 */
-#define FMC_CTL0 REG32((FMC) + 0x10U) /*!< FMC control register 0 */
-#define FMC_ADDR0 REG32((FMC) + 0x14U) /*!< FMC address register 0 */
+#define FMC_STAT REG32((FMC) + 0x0CU) /*!< FMC status register */
+#define FMC_CTL REG32((FMC) + 0x10U) /*!< FMC control register */
+#define FMC_ADDR REG32((FMC) + 0x14U) /*!< FMC address register */
#define FMC_OBSTAT REG32((FMC) + 0x1CU) /*!< FMC option bytes status register */
#define FMC_WP REG32((FMC) + 0x20U) /*!< FMC erase/program protection register */
#define FMC_PID REG32((FMC) + 0x100U) /*!< FMC product ID register */
@@ -65,31 +66,31 @@ OF SUCH DAMAGE. /* FMC_WS */
#define FMC_WS_WSCNT BITS(0, 2) /*!< wait state counter */
-/* FMC_KEY0 */
-#define FMC_KEY0_KEY BITS(0, 31) /*!< FMC_CTL0 unlock key bits */
+/* FMC_KEY */
+#define FMC_KEY_KEY BITS(0, 31) /*!< FMC_CTL unlock key bits */
/* FMC_OBKEY */
#define FMC_OBKEY_OBKEY BITS(0, 31) /*!< option bytes unlock key bits */
-/* FMC_STAT0 */
-#define FMC_STAT0_BUSY BIT(0) /*!< flash busy flag bit */
-#define FMC_STAT0_PGERR BIT(2) /*!< flash program error flag bit */
-#define FMC_STAT0_WPERR BIT(4) /*!< erase/program protection error flag bit */
-#define FMC_STAT0_ENDF BIT(5) /*!< end of operation flag bit */
-
-/* FMC_CTL0 */
-#define FMC_CTL0_PG BIT(0) /*!< main flash program for bank0 command bit */
-#define FMC_CTL0_PER BIT(1) /*!< main flash page erase for bank0 command bit */
-#define FMC_CTL0_MER BIT(2) /*!< main flash mass erase for bank0 command bit */
-#define FMC_CTL0_OBPG BIT(4) /*!< option bytes program command bit */
-#define FMC_CTL0_OBER BIT(5) /*!< option bytes erase command bit */
-#define FMC_CTL0_START BIT(6) /*!< send erase command to FMC bit */
-#define FMC_CTL0_LK BIT(7) /*!< FMC_CTL0 lock bit */
-#define FMC_CTL0_OBWEN BIT(9) /*!< option bytes erase/program enable bit */
-#define FMC_CTL0_ERRIE BIT(10) /*!< error interrupt enable bit */
-#define FMC_CTL0_ENDIE BIT(12) /*!< end of operation interrupt enable bit */
-
-/* FMC_ADDR0 */
+/* FMC_STAT */
+#define FMC_STAT_BUSY BIT(0) /*!< flash busy flag bit */
+#define FMC_STAT_PGERR BIT(2) /*!< flash program error flag bit */
+#define FMC_STAT_WPERR BIT(4) /*!< erase/program protection error flag bit */
+#define FMC_STAT_ENDF BIT(5) /*!< end of operation flag bit */
+
+/* FMC_CTL */
+#define FMC_CTL_PG BIT(0) /*!< main flash program command bit */
+#define FMC_CTL_PER BIT(1) /*!< main flash page erase command bit */
+#define FMC_CTL_MER BIT(2) /*!< main flash mass erase command bit */
+#define FMC_CTL_OBPG BIT(4) /*!< option bytes program command bit */
+#define FMC_CTL_OBER BIT(5) /*!< option bytes erase command bit */
+#define FMC_CTL_START BIT(6) /*!< send erase command to FMC bit */
+#define FMC_CTL_LK BIT(7) /*!< FMC_CTL lock bit */
+#define FMC_CTL_OBWEN BIT(9) /*!< option bytes erase/program enable bit */
+#define FMC_CTL_ERRIE BIT(10) /*!< error interrupt enable bit */
+#define FMC_CTL_ENDIE BIT(12) /*!< end of operation interrupt enable bit */
+
+/* FMC_ADDR */
#define FMC_ADDR0_ADDR BITS(0, 31) /*!< Flash erase/program command address bits */
/* FMC_OBSTAT */
@@ -119,8 +120,8 @@ OF SUCH DAMAGE. #define FMC_REG_OFFSET_GET(flag) ((uint32_t)(flag) >> 12)
/* configuration register */
-#define FMC_STAT0_REG_OFFSET 0x0CU /*!< status register 0 offset */
-#define FMC_CTL0_REG_OFFSET 0x10U /*!< control register 0 offset */
+#define FMC_STAT_REG_OFFSET 0x0CU /*!< status register offset */
+#define FMC_CTL_REG_OFFSET 0x10U /*!< control register offset */
#define FMC_OBSTAT_REG_OFFSET 0x1CU /*!< option byte status register offset */
/* fmc state */
@@ -134,24 +135,23 @@ typedef enum { /* FMC interrupt enable */
typedef enum {
- FMC_INT_END = FMC_REGIDX_BIT(FMC_CTL0_REG_OFFSET, 12U), /*!< enable FMC end of program interrupt */
- FMC_INT_ERR = FMC_REGIDX_BIT(FMC_CTL0_REG_OFFSET, 10U), /*!< enable FMC error interrupt */
+ FMC_INT_END = FMC_CTL_ENDIE, /*!< enable FMC end of program interrupt */
+ FMC_INT_ERR = FMC_CTL_ERRIE, /*!< enable FMC error interrupt */
} fmc_int_enum;
/* FMC flags */
typedef enum {
- FMC_FLAG_BUSY = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 0U), /*!< FMC busy flag */
- FMC_FLAG_PGERR = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 2U), /*!< FMC operation error flag bit */
- FMC_FLAG_WPERR = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 4U), /*!< FMC erase/program protection error flag bit */
- FMC_FLAG_END = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 5U), /*!< FMC end of operation flag bit */
- FMC_FLAG_OBERR = FMC_REGIDX_BIT(FMC_OBSTAT_REG_OFFSET, 0U), /*!< FMC option bytes read error flag */
+ FMC_FLAG_BUSY = FMC_STAT_BUSY, /*!< FMC busy flag */
+ FMC_FLAG_PGERR = FMC_STAT_PGERR, /*!< FMC operation error flag */
+ FMC_FLAG_WPERR = FMC_STAT_WPERR, /*!< FMC erase/program protection error flag */
+ FMC_FLAG_END = FMC_STAT_ENDF, /*!< FMC end of operation flag */
} fmc_flag_enum;
/* FMC interrupt flags */
typedef enum {
- FMC_INT_FLAG_PGERR = FMC_REGIDX_BITS(FMC_STAT0_REG_OFFSET, 2U, 10U), /*!< FMC operation error interrupt flag bit */
- FMC_INT_FLAG_WPERR = FMC_REGIDX_BITS(FMC_STAT0_REG_OFFSET, 4U, 10U), /*!< FMC erase/program protection error interrupt flag bit */
- FMC_INT_FLAG_END = FMC_REGIDX_BITS(FMC_STAT0_REG_OFFSET, 5U, 12U), /*!< FMC end of operation interrupt flag bit */
+ FMC_INT_FLAG_PGERR = FMC_STAT_PGERR, /*!< FMC operation error interrupt flag */
+ FMC_INT_FLAG_WPERR = FMC_STAT_WPERR, /*!< FMC erase/program protection error interrupt flag */
+ FMC_INT_FLAG_END = FMC_STAT_ENDF, /*!< FMC end of operation interrupt flag */
} fmc_interrupt_flag_enum;
/* unlock key */
@@ -271,32 +271,32 @@ void ob_unlock(void); void ob_lock(void);
/* erase the FMC option byte */
fmc_state_enum ob_erase(void);
-/* enable write protect */
+/* enable write protection */
fmc_state_enum ob_write_protection_enable(uint32_t ob_wp);
-/* configure the option byte security protection */
+/* configure security protection */
fmc_state_enum ob_security_protection_config(uint8_t ob_spc);
-/* write the FMC option byte */
+/* program the FMC user option byte */
fmc_state_enum ob_user_write(uint8_t ob_fwdgt, uint8_t ob_deepsleep, uint8_t ob_stdby, uint8_t ob_boot);
-/* program option bytes data */
+/* program the FMC data option byte */
fmc_state_enum ob_data_program(uint32_t address, uint8_t data);
-/* get the FMC option byte user */
+/* get OB_USER in register FMC_OBSTAT */
uint8_t ob_user_get(void);
/* get OB_DATA in register FMC_OBSTAT */
uint16_t ob_data_get(void);
/* get the FMC option byte write protection */
uint32_t ob_write_protection_get(void);
-/* get FMC option byte security protection code value */
+/* get FMC option byte security protection state */
FlagStatus ob_spc_get(void);
/* FMC interrupts and flags management functions */
/* enable FMC interrupt */
-void fmc_interrupt_enable(uint32_t interrupt);
+void fmc_interrupt_enable(fmc_int_enum interrupt);
/* disable FMC interrupt */
-void fmc_interrupt_disable(uint32_t interrupt);
+void fmc_interrupt_disable(fmc_int_enum interrupt);
/* check flag is set or not */
-FlagStatus fmc_flag_get(uint32_t flag);
+FlagStatus fmc_flag_get(fmc_flag_enum flag);
/* clear the FMC flag */
-void fmc_flag_clear(uint32_t flag);
+void fmc_flag_clear(fmc_flag_enum flag);
/* get FMC interrupt flag state */
FlagStatus fmc_interrupt_flag_get(fmc_interrupt_flag_enum flag);
/* clear FMC interrupt flag state */
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_fwdgt.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_fwdgt.h index f68c603e..e294c020 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_fwdgt.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_fwdgt.h @@ -1,12 +1,13 @@ /*!
- \file gd32vf103_fwdgt.h
- \brief definitions for the FWDGT
+ \file gd32vf103_fwdgt.h
+ \brief definitions for the FWDGT
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -36,8 +37,6 @@ OF SUCH DAMAGE. #define GD32VF103_FWDGT_H
#include "gd32vf103.h"
-#include "gd32vf103_dbg.h"
-#include "gd32vf103_rcu.h"
/* FWDGT definitions */
#define FWDGT FWDGT_BASE /*!< FWDGT base address */
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_gpio.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_gpio.h index fd454756..fd78da5f 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_gpio.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_gpio.h @@ -1,12 +1,13 @@ /*!
- \file gd32vf103_gpio.h
- \brief definitions for the GPIO
+ \file gd32vf103_gpio.h
+ \brief definitions for the GPIO
- \version 2019-06-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -36,11 +37,6 @@ OF SUCH DAMAGE. #define GD32VF103_GPIO_H
#include "gd32vf103.h"
-#include "gd32vf103_dbg.h"
-#include "gd32vf103_rcu.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
/* GPIOx(x=A,B,C,D,E) definitions */
#define GPIOA (GPIO_BASE + 0x00000000U)
@@ -422,8 +418,5 @@ void gpio_event_output_disable(void); /* lock GPIO pin bit */
void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin);
-#ifdef __cplusplus
-}
-#endif
#endif /* GD32VF103_GPIO_H */
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_i2c.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_i2c.h index 5ea317dd..9a3f4a02 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_i2c.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_i2c.h @@ -1,12 +1,13 @@ /*!
- \file gd32vf103_i2c.h
- \brief definitions for the I2C
+ \file gd32vf103_i2c.h
+ \brief definitions for the I2C
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -36,8 +37,6 @@ OF SUCH DAMAGE. #define GD32VF103_I2C_H
#include "gd32vf103.h"
-#include "gd32vf103_dbg.h"
-#include "gd32vf103_rcu.h"
/* I2Cx(x=0,1) definitions */
#define I2C0 I2C_BASE /*!< I2C0 base address */
@@ -53,7 +52,7 @@ OF SUCH DAMAGE. #define I2C_STAT1(i2cx) REG32((i2cx) + 0x18U) /*!< I2C transfer status register */
#define I2C_CKCFG(i2cx) REG32((i2cx) + 0x1CU) /*!< I2C clock configure register */
#define I2C_RT(i2cx) REG32((i2cx) + 0x20U) /*!< I2C rise time register */
-
+#define I2C_FMPCFG(i2cx) REG32((i2cx) + 0x90U) /*!< I2C fast-mode-plus configure register */
/* bits definitions */
/* I2Cx_CTL0 */
#define I2C_CTL0_I2CEN BIT(0) /*!< peripheral enable */
@@ -126,6 +125,9 @@ OF SUCH DAMAGE. /* I2Cx_RT */
#define I2C_RT_RISETIME BITS(0, 5) /*!< maximum rise time in fast/standard mode (Master mode) */
+/* I2Cx_FMPCFG */
+#define I2C_FMPCFG_FMPEN BIT(0) /*!< fast mode plus enable bit */
+
/* constants definitions */
/* define the I2C bit position and its register index offset */
#define I2C_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))
@@ -286,8 +288,6 @@ void i2c_ack_config(uint32_t i2c_periph, uint32_t ack); void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos);
/* master sends slave address */
void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection);
-/* configure I2C saddress1 */
-void i2c_saddr1_config(uint32_t i2c_periph, uint32_t addr);
/* enable dual-address mode */
void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t dualaddr);
/* disable dual-address mode */
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_libopt.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_libopt.h index 4517fdca..29c8424a 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_libopt.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_libopt.h @@ -40,7 +40,6 @@ extern "C" { #include "gd32vf103.h"
#include "gd32vf103_adc.h"
#include "gd32vf103_bkp.h"
-#include "gd32vf103_can.h"
#include "gd32vf103_crc.h"
#include "gd32vf103_dac.h"
#include "gd32vf103_dbg.h"
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_pmu.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_pmu.h index 8b40fd70..e2854e8d 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_pmu.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_pmu.h @@ -2,11 +2,12 @@ \file gd32vf103_pmu.h
\brief definitions for the PMU
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -36,8 +37,6 @@ OF SUCH DAMAGE. #define GD32VF103_PMU_H
#include "gd32vf103.h"
-#include "gd32vf103_dbg.h"
-#include "gd32vf103_rcu.h"
/* PMU definitions */
#define PMU PMU_BASE /*!< PMU base address */
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_rcu.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_rcu.h index 4a8ffe39..e540d385 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_rcu.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_rcu.h @@ -2,11 +2,12 @@ \file gd32vf103_rcu.h
\brief definitions for the RCU
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -36,7 +37,10 @@ OF SUCH DAMAGE. #define GD32VF103_RCU_H
#include "gd32vf103.h"
-
+/* define clock source */
+#define SEL_IRC8M ((uint16_t)0U)
+#define SEL_HXTAL ((uint16_t)1U)
+#define SEL_PLL ((uint16_t)2U)
/* RCU definitions */
#define RCU RCU_BASE
@@ -227,46 +231,6 @@ OF SUCH DAMAGE. #define RCU_DSV_DSLPVS BITS(0, 1) /*!< deep-sleep mode voltage select */
/* constants definitions */
-/* define value of high speed crystal oscillator (HXTAL) in Hz */
-#if !defined HXTAL_VALUE
-#define HXTAL_VALUE ((uint32_t)8000000) /*!< value of the external oscillator in Hz */
-#define HXTAL_VALUE_25M HXTAL_VALUE
-#endif /* high speed crystal oscillator value */
-
-/* define startup timeout value of high speed crystal oscillator (HXTAL) */
-#if !defined(HXTAL_STARTUP_TIMEOUT)
-#define HXTAL_STARTUP_TIMEOUT ((uint16_t)0xFFFF)
-#endif /* high speed crystal oscillator startup timeout */
-
-/* define value of internal 8MHz RC oscillator (IRC8M) in Hz */
-#if !defined(IRC8M_VALUE)
-#define IRC8M_VALUE ((uint32_t)8000000)
-#endif /* internal 8MHz RC oscillator value */
-
-/* define startup timeout value of internal 8MHz RC oscillator (IRC8M) */
-#if !defined(IRC8M_STARTUP_TIMEOUT)
-#define IRC8M_STARTUP_TIMEOUT ((uint16_t)0x0500)
-#endif /* internal 8MHz RC oscillator startup timeout */
-
-/* define value of internal 40KHz RC oscillator(IRC40K) in Hz */
-#if !defined(IRC40K_VALUE)
-#define IRC40K_VALUE ((uint32_t)40000)
-#endif /* internal 40KHz RC oscillator value */
-
-/* define value of low speed crystal oscillator (LXTAL)in Hz */
-#if !defined(LXTAL_VALUE)
-#define LXTAL_VALUE ((uint32_t)32768)
-#endif /* low speed crystal oscillator value */
-
-/* define clock source */
-#define SEL_IRC8M ((uint16_t)0U)
-#define SEL_HXTAL ((uint16_t)1U)
-#define SEL_PLL ((uint16_t)2U)
-
-/* define startup timeout count */
-#define OSC_STARTUP_TIMEOUT ((uint32_t)0xFFFFFU)
-#define LXTAL_STARTUP_TIMEOUT ((uint32_t)0x3FFFFFFU)
-
/* define the peripheral clock enable bit position and its register index offset */
#define RCU_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))
#define RCU_REG_VAL(periph) (REG32(RCU + ((uint32_t)(periph) >> 6)))
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_rtc.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_rtc.h index d191489b..c6870d8c 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_rtc.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_rtc.h @@ -1,12 +1,13 @@ /*!
- \file gd32vf103_rtc.h
- \brief definitions for the RTC
+ \file gd32vf103_rtc.h
+ \brief definitions for the RTC
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -36,8 +37,6 @@ OF SUCH DAMAGE. #define GD32VF103_RTC_H
#include "gd32vf103.h"
-#include "gd32vf103_dbg.h"
-#include "gd32vf103_rcu.h"
/* RTC definitions */
#define RTC RTC_BASE
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_spi.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_spi.h index ebaaa5ba..341bbfc8 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_spi.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_spi.h @@ -1,12 +1,13 @@ /*!
- \file gd32vf103_spi.h
- \brief definitions for the SPI
+ \file gd32vf103_spi.h
+ \brief definitions for the SPI
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -36,8 +37,6 @@ OF SUCH DAMAGE. #define GD32VF103_SPI_H
#include "gd32vf103.h"
-#include "gd32vf103_dbg.h"
-#include "gd32vf103_rcu.h"
/* SPIx(x=0,1,2) definitions */
#define SPI0 (SPI_BASE + 0x0000F800U)
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_timer.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_timer.h index 8bc0180a..66a2ce34 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_timer.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_timer.h @@ -2,11 +2,12 @@ \file gd32vf103_timer.h
\brief definitions for the TIMER
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.1, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -36,8 +37,6 @@ OF SUCH DAMAGE. #define GD32VF103_TIMER_H
#include "gd32vf103.h"
-#include "gd32vf103_dbg.h"
-#include "gd32vf103_rcu.h"
/* TIMERx(x=0..13) definitions */
#define TIMER0 (TIMER_BASE + 0x00012C00U)
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_usart.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_usart.h index 56edca63..4a1d7f78 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_usart.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_usart.h @@ -2,11 +2,13 @@ \file gd32vf103_usart.h
\brief definitions for the USART
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2019-09-18, V1.0.1, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2018, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -36,11 +38,6 @@ OF SUCH DAMAGE. #define GD32VF103_USART_H
#include "gd32vf103.h"
-#include "gd32vf103_dbg.h"
-#include "gd32vf103_rcu.h"
-#ifdef _cplusplus
-extern "C" {
-#endif
/* USARTx(x=0,1,2)/UARTx(x=3,4) definitions */
#define USART1 USART_BASE /*!< USART1 base address */
@@ -140,12 +137,12 @@ extern "C" { /* USART flags */
typedef enum {
/* flags in STAT register */
- USART_FLAG_CTSF = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 9U), /*!< CTS change flag */
- USART_FLAG_LBDF = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 8U), /*!< LIN break detected flag */
+ USART_FLAG_CTS = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 9U), /*!< CTS change flag */
+ USART_FLAG_LBD = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 8U), /*!< LIN break detected flag */
USART_FLAG_TBE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 7U), /*!< transmit data buffer empty */
USART_FLAG_TC = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 6U), /*!< transmission complete */
USART_FLAG_RBNE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 5U), /*!< read data buffer not empty */
- USART_FLAG_IDLEF = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 4U), /*!< IDLE frame detected flag */
+ USART_FLAG_IDLE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 4U), /*!< IDLE frame detected flag */
USART_FLAG_ORERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 3U), /*!< overrun error */
USART_FLAG_NERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 2U), /*!< noise error flag */
USART_FLAG_FERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 1U), /*!< frame error flag */
@@ -365,17 +362,11 @@ void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag); /* interrupt functions */
/* enable USART interrupt */
-void usart_interrupt_enable(uint32_t usart_periph, uint32_t int_flag);
+void usart_interrupt_enable(uint32_t usart_periph, uint32_t interrupt);
/* disable USART interrupt */
-void usart_interrupt_disable(uint32_t usart_periph, uint32_t int_flag);
+void usart_interrupt_disable(uint32_t usart_periph, uint32_t interrupt);
/* get USART interrupt and flag status */
FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, uint32_t int_flag);
/* clear interrupt flag in STAT register */
-void usart_interrupt_flag_clear(uint32_t usart_periph, uint32_t flag);
-int usart_write(uint32_t usart_periph, int ch);
-uint8_t usart_read(uint32_t usart_periph);
-#ifdef _cplusplus
-}
-#endif
-
+void usart_interrupt_flag_clear(uint32_t usart_periph, uint32_t int_flag);
#endif /* GD32VF103_USART_H */
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_wwdgt.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_wwdgt.h index b071f37c..3f0f6768 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_wwdgt.h +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/gd32vf103_wwdgt.h @@ -1,12 +1,13 @@ /*!
- \file gd32vf103_wwdgt.h
- \brief definitions for the WWDGT
+ \file gd32vf103_wwdgt.h
+ \brief definitions for the WWDGT
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -36,8 +37,6 @@ OF SUCH DAMAGE. #define GD32VF103_WWDGT_H
#include "gd32vf103.h"
-#include "gd32vf103_dbg.h"
-#include "gd32vf103_rcu.h"
/* WWDGT definitions */
#define WWDGT WWDGT_BASE /*!< WWDGT base address */
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/n200_func.h b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/n200_func.h new file mode 100644 index 00000000..7cd70829 --- /dev/null +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/n200_func.h @@ -0,0 +1,77 @@ +/* See LICENSE file for licence details */
+
+#ifndef N200_FUNC_H
+#define N200_FUNC_H
+
+#include <stddef.h>
+
+#define ECLIC_GROUP_LEVEL0_PRIO4 0
+#define ECLIC_GROUP_LEVEL1_PRIO3 1
+#define ECLIC_GROUP_LEVEL2_PRIO2 2
+#define ECLIC_GROUP_LEVEL3_PRIO1 3
+#define ECLIC_GROUP_LEVEL4_PRIO0 4
+
+void pmp_open_all_space(void);
+
+void switch_m2u_mode(void);
+
+uint32_t get_mtime_freq(void);
+
+uint32_t mtime_lo(void);
+
+uint32_t mtime_hi(void);
+
+uint64_t get_mtime_value(void);
+
+uint64_t get_instret_value(void);
+
+uint64_t get_cycle_value(void);
+
+uint32_t __attribute__((noinline)) measure_cpu_freq(size_t n);
+
+/* ECLIC relevant functions */
+void eclic_init(uint32_t num_irq);
+uint64_t get_timer_value(void);
+void eclic_enable_interrupt(uint32_t source);
+void eclic_disable_interrupt(uint32_t source);
+
+void eclic_set_pending(uint32_t source);
+void eclic_clear_pending(uint32_t source);
+
+void eclic_set_intctrl(uint32_t source, uint8_t intctrl);
+uint8_t eclic_get_intctrl(uint32_t source);
+
+void eclic_set_intattr(uint32_t source, uint8_t intattr);
+uint8_t eclic_get_intattr(uint32_t source);
+
+void eclic_set_cliccfg(uint8_t cliccfg);
+uint8_t eclic_get_cliccfg(void);
+
+void eclic_set_mth(uint8_t mth);
+uint8_t eclic_get_mth(void);
+
+/* sets nlbits */
+void eclic_set_nlbits(uint8_t nlbits);
+
+/* get nlbits */
+uint8_t eclic_get_nlbits(void);
+
+void eclic_set_irq_lvl(uint32_t source, uint8_t lvl);
+uint8_t eclic_get_irq_lvl(uint32_t source);
+
+void eclic_set_irq_lvl_abs(uint32_t source, uint8_t lvl_abs);
+uint8_t eclic_get_irq_lvl_abs(uint32_t source);
+
+uint8_t eclic_set_irq_priority(uint32_t source, uint8_t priority);
+uint8_t eclic_get_irq_priority(uint32_t source);
+
+void eclic_mode_enable(void);
+
+void eclic_set_vmode(uint32_t source);
+void eclic_set_nonvmode(uint32_t source);
+
+void eclic_set_level_trig(uint32_t source);
+void eclic_set_posedge_trig(uint32_t source);
+void eclic_set_negedge_trig(uint32_t source);
+
+#endif
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_adc.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_adc.c index 92d7c1f6..9c04ec58 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_adc.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_adc.c @@ -1,941 +1,941 @@ -/*! - \file gd32vf103_adc.c - \brief ADC driver - - \version 2019-6-5, V1.0.0, firmware for GD32VF103 -*/ - -/* - Copyright (c) 2019, GigaDevice Semiconductor Inc. - - Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - 3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. -*/ - -#include "gd32vf103_adc.h" -#include "gd32vf103_rcu.h" - -/* discontinuous mode macro*/ -#define ADC_CHANNEL_LENGTH_SUBTRACT_ONE ((uint8_t)1U) - -/* ADC regular channel macro */ -#define ADC_REGULAR_CHANNEL_RANK_SIX ((uint8_t)6U) -#define ADC_REGULAR_CHANNEL_RANK_TWELVE ((uint8_t)12U) -#define ADC_REGULAR_CHANNEL_RANK_SIXTEEN ((uint8_t)16U) -#define ADC_REGULAR_CHANNEL_RANK_LENGTH ((uint8_t)5U) - -/* ADC sampling time macro */ -#define ADC_CHANNEL_SAMPLE_TEN ((uint8_t)10U) -#define ADC_CHANNEL_SAMPLE_EIGHTEEN ((uint8_t)18U) -#define ADC_CHANNEL_SAMPLE_LENGTH ((uint8_t)3U) - -/* ADC inserted channel macro */ -#define ADC_INSERTED_CHANNEL_RANK_LENGTH ((uint8_t)5U) -#define ADC_INSERTED_CHANNEL_SHIFT_LENGTH ((uint8_t)15U) - -/* ADC inserted channel offset macro */ -#define ADC_OFFSET_LENGTH ((uint8_t)3U) -#define ADC_OFFSET_SHIFT_LENGTH ((uint8_t)4U) - -/*! - \brief reset ADC - \param[in] adc_periph: ADCx, x=0,1 - \param[out] none - \retval none -*/ -void adc_deinit(uint32_t adc_periph) { - switch (adc_periph) { - case ADC0: - /* reset ADC0 */ - rcu_periph_reset_enable(RCU_ADC0RST); - rcu_periph_reset_disable(RCU_ADC0RST); - break; - case ADC1: - /* reset ADC1 */ - rcu_periph_reset_enable(RCU_ADC1RST); - rcu_periph_reset_disable(RCU_ADC1RST); - break; - default: - break; - } -} - -/*! - \brief configure the ADC sync mode - \param[in] adc_periph: ADCx, x=0,1 - \param[in] mode: ADC mode - only one parameter can be selected which is shown as below: - \arg ADC_MODE_FREE: all the ADCs work independently - \arg ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL: ADC0 and ADC1 work in combined regular parallel + inserted parallel mode - \arg ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION: ADC0 and ADC1 work in combined regular parallel + trigger rotation mode - \arg ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_FAST: ADC0 and ADC1 work in combined inserted parallel + follow-up fast mode - \arg ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_SLOW: ADC0 and ADC1 work in combined inserted parallel + follow-up slow mode - \arg ADC_DAUL_INSERTED_PARALLEL: ADC0 and ADC1 work in inserted parallel mode only - \arg ADC_DAUL_REGULAL_PARALLEL: ADC0 and ADC1 work in regular parallel mode only - \arg ADC_DAUL_REGULAL_FOLLOWUP_FAST: ADC0 and ADC1 work in follow-up fast mode only - \arg ADC_DAUL_REGULAL_FOLLOWUP_SLOW: ADC0 and ADC1 work in follow-up slow mode only - \arg ADC_DAUL_INSERTED_TRIGGER_ROTATION: ADC0 and ADC1 work in trigger rotation mode only - \param[out] none - \retval none -*/ -void adc_mode_config(uint32_t adc_periph, uint32_t mode) { - ADC_CTL0(adc_periph) &= ~(ADC_CTL0_SYNCM); - ADC_CTL0(adc_periph) |= mode; -} - -/*! - \brief enable or disable ADC special function - \param[in] adc_periph: ADCx, x=0,1 - \param[in] function: the function to config - only one parameter can be selected which is shown as below: - \arg ADC_SCAN_MODE: scan mode select - \arg ADC_INSERTED_CHANNEL_AUTO: inserted channel group convert automatically - \arg ADC_CONTINUOUS_MODE: continuous mode select - \param[in] newvalue: ENABLE or DISABLE - \param[out] none - \retval none -*/ -void adc_special_function_config(uint32_t adc_periph, uint32_t function, ControlStatus newvalue) { - if (newvalue) { - if (0U != (function & ADC_SCAN_MODE)) { - /* enable scan mode */ - ADC_CTL0(adc_periph) |= ADC_SCAN_MODE; - } - if (0U != (function & ADC_INSERTED_CHANNEL_AUTO)) { - /* enable inserted channel group convert automatically */ - ADC_CTL0(adc_periph) |= ADC_INSERTED_CHANNEL_AUTO; - } - if (0U != (function & ADC_CONTINUOUS_MODE)) { - /* enable continuous mode */ - ADC_CTL1(adc_periph) |= ADC_CONTINUOUS_MODE; - } - } else { - if (0U != (function & ADC_SCAN_MODE)) { - /* disable scan mode */ - ADC_CTL0(adc_periph) &= ~ADC_SCAN_MODE; - } - if (0U != (function & ADC_INSERTED_CHANNEL_AUTO)) { - /* disable inserted channel group convert automatically */ - ADC_CTL0(adc_periph) &= ~ADC_INSERTED_CHANNEL_AUTO; - } - if (0U != (function & ADC_CONTINUOUS_MODE)) { - /* disable continuous mode */ - ADC_CTL1(adc_periph) &= ~ADC_CONTINUOUS_MODE; - } - } -} - -/*! - \brief configure ADC data alignment - \param[in] adc_periph: ADCx, x=0,1 - \param[in] data_alignment: data alignment select - only one parameter can be selected which is shown as below: - \arg ADC_DATAALIGN_RIGHT: LSB alignment - \arg ADC_DATAALIGN_LEFT: MSB alignment - \param[out] none - \retval none -*/ -void adc_data_alignment_config(uint32_t adc_periph, uint32_t data_alignment) { - if (ADC_DATAALIGN_RIGHT != data_alignment) { - /* MSB alignment */ - ADC_CTL1(adc_periph) |= ADC_CTL1_DAL; - } else { - /* LSB alignment */ - ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DAL); - } -} - -/*! - \brief enable ADC interface - \param[in] adc_periph: ADCx, x=0,1 - \param[out] none - \retval none -*/ -void adc_enable(uint32_t adc_periph) { - if (RESET == (ADC_CTL1(adc_periph) & ADC_CTL1_ADCON)) { - /* enable ADC */ - ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_ADCON; - } -} - -/*! - \brief disable ADC interface - \param[in] adc_periph: ADCx, x=0,1 - \param[out] none - \retval none -*/ -void adc_disable(uint32_t adc_periph) { - /* disable ADC */ - ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ADCON); -} - -/*! - \brief ADC calibration and reset calibration - \param[in] adc_periph: ADCx, x=0,1 - \param[out] none - \retval none -*/ -void adc_calibration_enable(uint32_t adc_periph) { - /* reset the selected ADC1 calibration registers */ - ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_RSTCLB; - /* check the RSTCLB bit state */ - while (RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_RSTCLB)) {} - /* enable ADC calibration process */ - ADC_CTL1(adc_periph) |= ADC_CTL1_CLB; - /* check the CLB bit state */ - while (RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_CLB)) {} -} - -/*! - \brief enable the temperature sensor and Vrefint channel - \param[in] none - \param[out] none - \retval none -*/ -void adc_tempsensor_vrefint_enable(void) { - /* enable the temperature sensor and Vrefint channel */ - ADC_CTL1(ADC0) |= ADC_CTL1_TSVREN; -} - -/*! - \brief disable the temperature sensor and Vrefint channel - \param[in] none - \param[out] none - \retval none -*/ -void adc_tempsensor_vrefint_disable(void) { - /* disable the temperature sensor and Vrefint channel */ - ADC_CTL1(ADC0) &= ~ADC_CTL1_TSVREN; -} - -/*! - \brief enable DMA request - \param[in] adc_periph: ADCx, x=0,1 - \param[out] none - \retval none -*/ -void adc_dma_mode_enable(uint32_t adc_periph) { - /* enable DMA request */ - ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_DMA); -} - -/*! - \brief disable DMA request - \param[in] adc_periph: ADCx, x=0,1 - \param[out] none - \retval none -*/ -void adc_dma_mode_disable(uint32_t adc_periph) { - /* disable DMA request */ - ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DMA); -} - -/*! - \brief configure ADC discontinuous mode - \param[in] adc_periph: ADCx, x=0,1 - \param[in] adc_channel_group: select the channel group - only one parameter can be selected which is shown as below: - \arg ADC_REGULAR_CHANNEL: regular channel group - \arg ADC_INSERTED_CHANNEL: inserted channel group - \arg ADC_CHANNEL_DISCON_DISABLE: disable discontinuous mode of regular & inserted channel - \param[in] length: number of conversions in discontinuous mode,the number can be 1..8 - for regular channel, the number has no effect for inserted channel - \param[out] none - \retval none -*/ -void adc_discontinuous_mode_config(uint32_t adc_periph, uint8_t adc_channel_group, uint8_t length) { - /* disable discontinuous mode of regular & inserted channel */ - ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_DISRC | ADC_CTL0_DISIC)); - switch (adc_channel_group) { - case ADC_REGULAR_CHANNEL: - /* config the number of conversions in discontinuous mode */ - ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_DISNUM); - ADC_CTL0(adc_periph) |= CTL0_DISNUM(((uint32_t)length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); - /* enable regular channel group discontinuous mode */ - ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISRC; - break; - case ADC_INSERTED_CHANNEL: - /* enable inserted channel group discontinuous mode */ - ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISIC; - break; - case ADC_CHANNEL_DISCON_DISABLE: - /* disable discontinuous mode of regular & inserted channel */ - default: - break; - } -} - -/*! - \brief configure the length of regular channel group or inserted channel group - \param[in] adc_periph: ADCx, x=0,1 - \param[in] adc_channel_group: select the channel group - only one parameter can be selected which is shown as below: - \arg ADC_REGULAR_CHANNEL: regular channel group - \arg ADC_INSERTED_CHANNEL: inserted channel group - \param[in] length: the length of the channel - regular channel 1-16 - inserted channel 1-4 - \param[out] none - \retval none -*/ -void adc_channel_length_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t length) { - switch (adc_channel_group) { - case ADC_REGULAR_CHANNEL: - /* configure the length of regular channel group */ - ADC_RSQ0(adc_periph) &= ~((uint32_t)ADC_RSQ0_RL); - ADC_RSQ0(adc_periph) |= RSQ0_RL((uint32_t)(length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); - break; - case ADC_INSERTED_CHANNEL: - /* configure the length of inserted channel group */ - ADC_ISQ(adc_periph) &= ~((uint32_t)ADC_ISQ_IL); - ADC_ISQ(adc_periph) |= ISQ_IL((uint32_t)(length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); - break; - default: - break; - } -} - -/*! - \brief configure ADC regular channel - \param[in] adc_periph: ADCx, x=0,1 - \param[in] rank: the regular group sequence rank,this parameter must be between 0 to 15 - \param[in] adc_channel: the selected ADC channel - only one parameter can be selected which is shown as below: - \arg ADC_CHANNEL_x(x=0..17)(x=16 and x=17 are only for ADC0): ADC Channelx - \param[in] sample_time: the sample time value - only one parameter can be selected which is shown as below: - \arg ADC_SAMPLETIME_1POINT5: 1.5 cycles - \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles - \arg ADC_SAMPLETIME_13POINT5: 13.5 cycles - \arg ADC_SAMPLETIME_28POINT5: 28.5 cycles - \arg ADC_SAMPLETIME_41POINT5: 41.5 cycles - \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles - \arg ADC_SAMPLETIME_71POINT5: 71.5 cycles - \arg ADC_SAMPLETIME_239POINT5: 239.5 cycles - \param[out] none - \retval none -*/ -void adc_regular_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time) { - uint32_t rsq, sampt; - - /* ADC regular sequence config */ - if (rank < ADC_REGULAR_CHANNEL_RANK_SIX) { - /* the regular group sequence rank is smaller than six */ - rsq = ADC_RSQ2(adc_periph); - rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH * rank))); - /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */ - rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH * rank)); - ADC_RSQ2(adc_periph) = rsq; - } else if (rank < ADC_REGULAR_CHANNEL_RANK_TWELVE) { - /* the regular group sequence rank is smaller than twelve */ - rsq = ADC_RSQ1(adc_periph); - rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH * (rank - ADC_REGULAR_CHANNEL_RANK_SIX)))); - /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */ - rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH * (rank - ADC_REGULAR_CHANNEL_RANK_SIX))); - ADC_RSQ1(adc_periph) = rsq; - } else if (rank < ADC_REGULAR_CHANNEL_RANK_SIXTEEN) { - /* the regular group sequence rank is smaller than sixteen */ - rsq = ADC_RSQ0(adc_periph); - rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH * (rank - ADC_REGULAR_CHANNEL_RANK_TWELVE)))); - /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */ - rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH * (rank - ADC_REGULAR_CHANNEL_RANK_TWELVE))); - ADC_RSQ0(adc_periph) = rsq; - } else { - } - - /* ADC sampling time config */ - if (adc_channel < ADC_CHANNEL_SAMPLE_TEN) { - /* the regular group sequence rank is smaller than ten */ - sampt = ADC_SAMPT1(adc_periph); - sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel))); - /* channel sample time set*/ - sampt |= (uint32_t)(sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel)); - ADC_SAMPT1(adc_periph) = sampt; - } else if (adc_channel < ADC_CHANNEL_SAMPLE_EIGHTEEN) { - /* the regular group sequence rank is smaller than eighteen */ - sampt = ADC_SAMPT0(adc_periph); - sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN)))); - /* channel sample time set*/ - sampt |= (uint32_t)(sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN))); - ADC_SAMPT0(adc_periph) = sampt; - } else { - } -} - -/*! - \brief configure ADC inserted channel - \param[in] adc_periph: ADCx, x=0,1 - \param[in] rank: the inserted group sequencer rank,this parameter must be between 0 to 3 - \param[in] adc_channel: the selected ADC channel - only one parameter can be selected which is shown as below: - \arg ADC_CHANNEL_x(x=0..17)(x=16 and x=17 are only for ADC0): ADC Channelx - \param[in] sample_time: The sample time value - only one parameter can be selected which is shown as below: - \arg ADC_SAMPLETIME_1POINT5: 1.5 cycles - \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles - \arg ADC_SAMPLETIME_13POINT5: 13.5 cycles - \arg ADC_SAMPLETIME_28POINT5: 28.5 cycles - \arg ADC_SAMPLETIME_41POINT5: 41.5 cycles - \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles - \arg ADC_SAMPLETIME_71POINT5: 71.5 cycles - \arg ADC_SAMPLETIME_239POINT5: 239.5 cycles - \param[out] none - \retval none -*/ -void adc_inserted_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time) { - uint8_t inserted_length; - uint32_t isq, sampt; - /* get inserted channel group length */ - inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph), 20U, 21U); - /* the channel number is written to these bits to select a channel as the nth conversion in the inserted channel group */ - isq = ADC_ISQ(adc_periph); - isq &= ~((uint32_t)(ADC_ISQ_ISQN << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH - (inserted_length - rank) * ADC_INSERTED_CHANNEL_RANK_LENGTH))); - isq |= ((uint32_t)adc_channel << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH - (inserted_length - rank) * ADC_INSERTED_CHANNEL_RANK_LENGTH)); - ADC_ISQ(adc_periph) = isq; - - /* ADC sampling time config */ - if (adc_channel < ADC_CHANNEL_SAMPLE_TEN) { - /* the inserted group sequence rank is smaller than ten */ - sampt = ADC_SAMPT1(adc_periph); - sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel))); - /* channel sample time set*/ - sampt |= (uint32_t)sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel); - ADC_SAMPT1(adc_periph) = sampt; - } else if (adc_channel < ADC_CHANNEL_SAMPLE_EIGHTEEN) { - /* the inserted group sequence rank is smaller than eighteen */ - sampt = ADC_SAMPT0(adc_periph); - sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN)))); - /* channel sample time set*/ - sampt |= ((uint32_t)sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN))); - ADC_SAMPT0(adc_periph) = sampt; - } else { - } -} - -/*! - \brief configure ADC inserted channel offset - \param[in] adc_periph: ADCx, x=0,1 - \param[in] inserted_channel: insert channel select - only one parameter can be selected - \arg ADC_INSERTED_CHANNEL_0: inserted channel0 - \arg ADC_INSERTED_CHANNEL_1: inserted channel1 - \arg ADC_INSERTED_CHANNEL_2: inserted channel2 - \arg ADC_INSERTED_CHANNEL_3: inserted channel3 - \param[in] offset: the offset data - \param[out] none - \retval none -*/ -void adc_inserted_channel_offset_config(uint32_t adc_periph, uint8_t inserted_channel, uint16_t offset) { - uint8_t inserted_length; - uint32_t num = 0U; - - inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph), 20U, 21U); - num = ((uint32_t)ADC_OFFSET_LENGTH - ((uint32_t)inserted_length - (uint32_t)inserted_channel)); - - if (num <= ADC_OFFSET_LENGTH) { - /* calculate the offset of the register */ - num = num * ADC_OFFSET_SHIFT_LENGTH; - /* config the offset of the selected channels */ - REG32((adc_periph) + 0x14U + num) = IOFFX_IOFF((uint32_t)offset); - } -} - -/*! - \brief configure ADC external trigger source - \param[in] adc_periph: ADCx, x=0,1 - \param[in] adc_channel_group: select the channel group - only one parameter can be selected which is shown as below: - \arg ADC_REGULAR_CHANNEL: regular channel group - \arg ADC_INSERTED_CHANNEL: inserted channel group - \param[in] external_trigger_source: regular or inserted group trigger source - only one parameter can be selected - for regular channel: - \arg ADC0_1_EXTTRIG_REGULAR_T0_CH0: TIMER0 CH0 event select - \arg ADC0_1_EXTTRIG_REGULAR_T0_CH1: TIMER0 CH1 event select - \arg ADC0_1_EXTTRIG_REGULAR_T0_CH2: TIMER0 CH2 event select - \arg ADC0_1_EXTTRIG_REGULAR_T1_CH1: TIMER1 CH1 event select - \arg ADC0_1_EXTTRIG_REGULAR_T2_TRGO: TIMER2 TRGO event select - \arg ADC0_1_EXTTRIG_REGULAR_T3_CH3: TIMER3 CH3 event select - \arg ADC0_1_EXTTRIG_REGULAR_EXTI_11: external interrupt line 11 - \arg ADC0_1_EXTTRIG_REGULAR_NONE: software trigger - for inserted channel: - \arg ADC0_1_EXTTRIG_INSERTED_T0_TRGO: TIMER0 TRGO event select - \arg ADC0_1_EXTTRIG_INSERTED_T0_CH3: TIMER0 CH3 event select - \arg ADC0_1_EXTTRIG_INSERTED_T1_TRGO: TIMER1 TRGO event select - \arg ADC0_1_EXTTRIG_INSERTED_T1_CH0: TIMER1 CH0 event select - \arg ADC0_1_EXTTRIG_INSERTED_T2_CH3: TIMER2 CH3 event select - \arg ADC0_1_EXTTRIG_INSERTED_T3_TRGO: TIMER3 TRGO event select - \arg ADC0_1_EXTTRIG_INSERTED_EXTI_15: external interrupt line 15 - \arg ADC0_1_EXTTRIG_INSERTED_NONE: software trigger - \param[out] none - \retval none -*/ -void adc_external_trigger_source_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t external_trigger_source) { - switch (adc_channel_group) { - case ADC_REGULAR_CHANNEL: - /* configure ADC regular group external trigger source */ - ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSRC); - ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source; - break; - case ADC_INSERTED_CHANNEL: - /* configure ADC inserted group external trigger source */ - ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSIC); - ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source; - break; - default: - break; - } -} - -/*! - \brief configure ADC external trigger - \param[in] adc_periph: ADCx, x=0,1 - \param[in] adc_channel_group: select the channel group - one or more parameters can be selected which are shown as below: - \arg ADC_REGULAR_CHANNEL: regular channel group - \arg ADC_INSERTED_CHANNEL: inserted channel group - \param[in] newvalue: ENABLE or DISABLE - \param[out] none - \retval none -*/ -void adc_external_trigger_config(uint32_t adc_periph, uint8_t adc_channel_group, ControlStatus newvalue) { - if (newvalue) { - if (0U != (adc_channel_group & ADC_REGULAR_CHANNEL)) { - /* enable ADC regular channel group external trigger */ - ADC_CTL1(adc_periph) |= ADC_CTL1_ETERC; - } - if (0U != (adc_channel_group & ADC_INSERTED_CHANNEL)) { - /* enable ADC inserted channel group external trigger */ - ADC_CTL1(adc_periph) |= ADC_CTL1_ETEIC; - } - } else { - if (0U != (adc_channel_group & ADC_REGULAR_CHANNEL)) { - /* disable ADC regular channel group external trigger */ - ADC_CTL1(adc_periph) &= ~ADC_CTL1_ETERC; - } - if (0U != (adc_channel_group & ADC_INSERTED_CHANNEL)) { - /* disable ADC regular channel group external trigger */ - ADC_CTL1(adc_periph) &= ~ADC_CTL1_ETEIC; - } - } -} - -/*! - \brief enable ADC software trigger - \param[in] adc_periph: ADCx, x=0,1 - \param[in] adc_channel_group: select the channel group - one or more parameters can be selected which are shown as below: - \arg ADC_REGULAR_CHANNEL: regular channel group - \arg ADC_INSERTED_CHANNEL: inserted channel group - \param[out] none - \retval none -*/ -void adc_software_trigger_enable(uint32_t adc_periph, uint8_t adc_channel_group) { - if (0U != (adc_channel_group & ADC_REGULAR_CHANNEL)) { - /* enable ADC regular channel group software trigger */ - ADC_CTL1(adc_periph) |= ADC_CTL1_SWRCST; - } - if (0U != (adc_channel_group & ADC_INSERTED_CHANNEL)) { - /* enable ADC inserted channel group software trigger */ - ADC_CTL1(adc_periph) |= ADC_CTL1_SWICST; - } -} - -/*! - \brief read ADC regular group data register - \param[in] adc_periph: ADCx, x=0,1 - \param[in] none - \param[out] none - \retval the conversion value -*/ -uint16_t adc_regular_data_read(uint32_t adc_periph) { return (uint16_t)(ADC_RDATA(adc_periph)); } - -/*! - \brief read ADC inserted group data register - \param[in] adc_periph: ADCx, x=0,1 - \param[in] inserted_channel: insert channel select - only one parameter can be selected - \arg ADC_INSERTED_CHANNEL_0: inserted Channel0 - \arg ADC_INSERTED_CHANNEL_1: inserted channel1 - \arg ADC_INSERTED_CHANNEL_2: inserted Channel2 - \arg ADC_INSERTED_CHANNEL_3: inserted Channel3 - \param[out] none - \retval the conversion value -*/ -uint16_t adc_inserted_data_read(uint32_t adc_periph, uint8_t inserted_channel) { - uint32_t idata; - /* read the data of the selected channel */ - switch (inserted_channel) { - case ADC_INSERTED_CHANNEL_0: - /* read the data of channel 0 */ - idata = ADC_IDATA0(adc_periph); - break; - case ADC_INSERTED_CHANNEL_1: - /* read the data of channel 1 */ - idata = ADC_IDATA1(adc_periph); - break; - case ADC_INSERTED_CHANNEL_2: - /* read the data of channel 2 */ - idata = ADC_IDATA2(adc_periph); - break; - case ADC_INSERTED_CHANNEL_3: - /* read the data of channel 3 */ - idata = ADC_IDATA3(adc_periph); - break; - default: - idata = 0U; - break; - } - return (uint16_t)idata; -} - -/*! - \brief read the last ADC0 and ADC1 conversion result data in sync mode - \param[in] none - \param[out] none - \retval the conversion value -*/ -uint32_t adc_sync_mode_convert_value_read(void) { - /* return conversion value */ - return ADC_RDATA(ADC0); -} - -/*! - \brief configure ADC analog watchdog single channel - \param[in] adc_periph: ADCx, x=0,1 - \param[in] adc_channel: the selected ADC channel - only one parameter can be selected which is shown as below: - \arg ADC_CHANNEL_x: ADC Channelx(x=0..17)(x=16 and x=17 are only for ADC0) - \param[out] none - \retval none -*/ -void adc_watchdog_single_channel_enable(uint32_t adc_periph, uint8_t adc_channel) { - ADC_CTL0(adc_periph) &= (uint32_t) ~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL); - /* analog watchdog channel select */ - ADC_CTL0(adc_periph) |= (uint32_t)adc_channel; - ADC_CTL0(adc_periph) |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC); -} - -/*! - \brief configure ADC analog watchdog group channel - \param[in] adc_periph: ADCx, x=0,1 - \param[in] adc_channel_group: the channel group use analog watchdog - only one parameter can be selected which is shown as below: - \arg ADC_REGULAR_CHANNEL: regular channel group - \arg ADC_INSERTED_CHANNEL: inserted channel group - \arg ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group - \param[out] none - \retval none -*/ -void adc_watchdog_group_channel_enable(uint32_t adc_periph, uint8_t adc_channel_group) { - ADC_CTL0(adc_periph) &= (uint32_t) ~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC); - /* select the group */ - switch (adc_channel_group) { - case ADC_REGULAR_CHANNEL: - /* regular channel analog watchdog enable */ - ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_RWDEN; - break; - case ADC_INSERTED_CHANNEL: - /* inserted channel analog watchdog enable */ - ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_IWDEN; - break; - case ADC_REGULAR_INSERTED_CHANNEL: - /* regular and inserted channel analog watchdog enable */ - ADC_CTL0(adc_periph) |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN); - break; - default: - break; - } -} - -/*! - \brief disable ADC analog watchdog - \param[in] adc_periph: ADCx, x=0,1 - \param[out] none - \retval none -*/ -void adc_watchdog_disable(uint32_t adc_periph) { ADC_CTL0(adc_periph) &= (uint32_t) ~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL); } - -/*! - \brief configure ADC analog watchdog threshold - \param[in] adc_periph: ADCx, x=0,1 - \param[in] low_threshold: analog watchdog low threshold, 0..4095 - \param[in] high_threshold: analog watchdog high threshold, 0..4095 - \param[out] none - \retval none -*/ -void adc_watchdog_threshold_config(uint32_t adc_periph, uint16_t low_threshold, uint16_t high_threshold) { - ADC_WDLT(adc_periph) = (uint32_t)WDLT_WDLT(low_threshold); - ADC_WDHT(adc_periph) = (uint32_t)WDHT_WDHT(high_threshold); -} - -/*! - \brief get the ADC flag bits - \param[in] adc_periph: ADCx, x=0,1 - \param[in] adc_flag: the adc flag bits - only one parameter can be selected which is shown as below: - \arg ADC_FLAG_WDE: analog watchdog event flag - \arg ADC_FLAG_EOC: end of group conversion flag - \arg ADC_FLAG_EOIC: end of inserted group conversion flag - \arg ADC_FLAG_STIC: start flag of inserted channel group - \arg ADC_FLAG_STRC: start flag of regular channel group - \param[out] none - \retval FlagStatus: SET or RESET -*/ -FlagStatus adc_flag_get(uint32_t adc_periph, uint32_t adc_flag) { - FlagStatus reval = RESET; - if (ADC_STAT(adc_periph) & adc_flag) { - reval = SET; - } - return reval; -} - -/*! - \brief clear the ADC flag bits - \param[in] adc_periph: ADCx, x=0,1 - \param[in] adc_flag: the adc flag bits - one or more parameters can be selected which are shown as below: - \arg ADC_FLAG_WDE: analog watchdog event flag - \arg ADC_FLAG_EOC: end of group conversion flag - \arg ADC_FLAG_EOIC: end of inserted group conversion flag - \arg ADC_FLAG_STIC: start flag of inserted channel group - \arg ADC_FLAG_STRC: start flag of regular channel group - \param[out] none - \retval none -*/ -void adc_flag_clear(uint32_t adc_periph, uint32_t adc_flag) { ADC_STAT(adc_periph) &= ~((uint32_t)adc_flag); } - -/*! - \brief get the bit state of ADCx software start conversion - \param[in] adc_periph: ADCx, x=0,1 - \param[in] none - \param[out] none - \retval FlagStatus: SET or RESET -*/ -FlagStatus adc_regular_software_startconv_flag_get(uint32_t adc_periph) { - FlagStatus reval = RESET; - if ((uint32_t)RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_SWRCST)) { - reval = SET; - } - return reval; -} - -/*! - \brief get the bit state of ADCx software inserted channel start conversion - \param[in] adc_periph: ADCx, x=0,1 - \param[in] none - \param[out] none - \retval FlagStatus: SET or RESET -*/ -FlagStatus adc_inserted_software_startconv_flag_get(uint32_t adc_periph) { - FlagStatus reval = RESET; - if ((uint32_t)RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_SWICST)) { - reval = SET; - } - return reval; -} - -/*! - \brief get the ADC interrupt bits - \param[in] adc_periph: ADCx, x=0,1 - \param[in] adc_interrupt: the adc interrupt bits - only one parameter can be selected which is shown as below: - \arg ADC_INT_FLAG_WDE: analog watchdog interrupt - \arg ADC_INT_FLAG_EOC: end of group conversion interrupt - \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt - \param[out] none - \retval FlagStatus: SET or RESET -*/ -FlagStatus adc_interrupt_flag_get(uint32_t adc_periph, uint32_t adc_interrupt) { - FlagStatus interrupt_flag = RESET; - uint32_t state; - /* check the interrupt bits */ - switch (adc_interrupt) { - case ADC_INT_FLAG_WDE: - /* get the ADC analog watchdog interrupt bits */ - state = ADC_STAT(adc_periph) & ADC_STAT_WDE; - if ((ADC_CTL0(adc_periph) & ADC_CTL0_WDEIE) && state) { - interrupt_flag = SET; - } - break; - case ADC_INT_FLAG_EOC: - /* get the ADC end of group conversion interrupt bits */ - state = ADC_STAT(adc_periph) & ADC_STAT_EOC; - if ((ADC_CTL0(adc_periph) & ADC_CTL0_EOCIE) && state) { - interrupt_flag = SET; - } - break; - case ADC_INT_FLAG_EOIC: - /* get the ADC end of inserted group conversion interrupt bits */ - state = ADC_STAT(adc_periph) & ADC_STAT_EOIC; - if ((ADC_CTL0(adc_periph) & ADC_CTL0_EOICIE) && state) { - interrupt_flag = SET; - } - break; - default: - break; - } - return interrupt_flag; -} - -/*! - \brief clear the ADC flag - \param[in] adc_periph: ADCx, x=0,1 - \param[in] adc_interrupt: the adc status flag - one or more parameters can be selected which are shown as below: - \arg ADC_INT_FLAG_WDE: analog watchdog interrupt - \arg ADC_INT_FLAG_EOC: end of group conversion interrupt - \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt - \param[out] none - \retval none -*/ -void adc_interrupt_flag_clear(uint32_t adc_periph, uint32_t adc_interrupt) { ADC_STAT(adc_periph) &= ~((uint32_t)adc_interrupt); } - -/*! - \brief enable ADC interrupt - \param[in] adc_periph: ADCx, x=0,1 - \param[in] adc_interrupt: the adc interrupt - one or more parameters can be selected which are shown as below: - \arg ADC_INT_WDE: analog watchdog interrupt flag - \arg ADC_INT_EOC: end of group conversion interrupt flag - \arg ADC_INT_EOIC: end of inserted group conversion interrupt flag - \param[out] none - \retval none -*/ -void adc_interrupt_enable(uint32_t adc_periph, uint32_t adc_interrupt) { - /* enable ADC analog watchdog interrupt */ - if (0U != (adc_interrupt & ADC_INT_WDE)) { - ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_WDEIE; - } - /* enable ADC end of group conversion interrupt */ - if (0U != (adc_interrupt & ADC_INT_EOC)) { - ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_EOCIE; - } - /* enable ADC end of inserted group conversion interrupt */ - if (0U != (adc_interrupt & ADC_INT_EOIC)) { - ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_EOICIE; - } -} - -/*! - \brief disable ADC interrupt - \param[in] adc_periph: ADCx, x=0,1 - \param[in] adc_interrupt: the adc interrupt flag - one or more parameters can be selected which are shown as below: - \arg ADC_INT_WDE: analog watchdog interrupt flag - \arg ADC_INT_EOC: end of group conversion interrupt flag - \arg ADC_INT_EOIC: end of inserted group conversion interrupt flag - \param[out] none - \retval none -*/ -void adc_interrupt_disable(uint32_t adc_periph, uint32_t adc_interrupt) { - /* disable ADC analog watchdog interrupt */ - if (0U != (adc_interrupt & ADC_INT_WDE)) { - ADC_CTL0(adc_periph) &= ~(uint32_t)ADC_CTL0_WDEIE; - } - /* disable ADC end of group conversion interrupt */ - if (0U != (adc_interrupt & ADC_INT_EOC)) { - ADC_CTL0(adc_periph) &= ~(uint32_t)ADC_CTL0_EOCIE; - } - /* disable ADC end of inserted group conversion interrupt */ - if (0U != (adc_interrupt & ADC_INT_EOIC)) { - ADC_CTL0(adc_periph) &= ~(uint32_t)ADC_CTL0_EOICIE; - } -} - -/*! - \brief adc resolution config - \param[in] adc_periph: ADCx, x=0,1 - \param[in] resolution: ADC resolution - only one parameter can be selected which is shown as below: - \arg ADC_RESOLUTION_12B: 12-bit ADC resolution - \arg ADC_RESOLUTION_10B: 10-bit ADC resolution - \arg ADC_RESOLUTION_8B: 8-bit ADC resolution - \arg ADC_RESOLUTION_6B: 6-bit ADC resolution - \param[out] none - \retval none -*/ -void adc_resolution_config(uint32_t adc_periph, uint32_t resolution) { - ADC_OVSCR(adc_periph) &= ~((uint32_t)ADC_OVSCR_DRES); - ADC_OVSCR(adc_periph) |= (uint32_t)resolution; -} - -/*! - \brief adc oversample mode config - \param[in] adc_periph: ADCx, x=0,1 - \param[in] mode: ADC oversampling mode - only one parameter can be selected which is shown as below: - \arg ADC_OVERSAMPLING_ALL_CONVERT: all oversampled conversions for a channel - are done consecutively after a trigger - \arg ADC_OVERSAMPLING_ONE_CONVERT: each oversampled conversion for a channel - needs a trigger - \param[in] shift: ADC oversampling shift - only one parameter can be selected which is shown as below: - \arg ADC_OVERSAMPLING_SHIFT_NONE: no oversampling shift - \arg ADC_OVERSAMPLING_SHIFT_1B: 1-bit oversampling shift - \arg ADC_OVERSAMPLING_SHIFT_2B: 2-bit oversampling shift - \arg ADC_OVERSAMPLING_SHIFT_3B: 3-bit oversampling shift - \arg ADC_OVERSAMPLING_SHIFT_4B: 3-bit oversampling shift - \arg ADC_OVERSAMPLING_SHIFT_5B: 5-bit oversampling shift - \arg ADC_OVERSAMPLING_SHIFT_6B: 6-bit oversampling shift - \arg ADC_OVERSAMPLING_SHIFT_7B: 7-bit oversampling shift - \arg ADC_OVERSAMPLING_SHIFT_8B: 8-bit oversampling shift - \param[in] ratio: ADC oversampling ratio - only one parameter can be selected which is shown as below: - \arg ADC_OVERSAMPLING_RATIO_MUL2: oversampling ratio X2 - \arg ADC_OVERSAMPLING_RATIO_MUL4: oversampling ratio X4 - \arg ADC_OVERSAMPLING_RATIO_MUL8: oversampling ratio X8 - \arg ADC_OVERSAMPLING_RATIO_MUL16: oversampling ratio X16 - \arg ADC_OVERSAMPLING_RATIO_MUL32: oversampling ratio X32 - \arg ADC_OVERSAMPLING_RATIO_MUL64: oversampling ratio X64 - \arg ADC_OVERSAMPLING_RATIO_MUL128: oversampling ratio X128 - \arg ADC_OVERSAMPLING_RATIO_MUL256: oversampling ratio X256 - \param[out] none - \retval none -*/ -void adc_oversample_mode_config(uint32_t adc_periph, uint8_t mode, uint16_t shift, uint8_t ratio) { - if (mode) { - ADC_OVSCR(adc_periph) |= (uint32_t)ADC_OVSCR_TOVS; - } else { - ADC_OVSCR(adc_periph) &= ~((uint32_t)ADC_OVSCR_TOVS); - } - /* config the shift and ratio */ - ADC_OVSCR(adc_periph) &= ~((uint32_t)(ADC_OVSCR_OVSR | ADC_OVSCR_OVSS)); - ADC_OVSCR(adc_periph) |= ((uint32_t)shift | (uint32_t)ratio); -} - -/*! - \brief enable ADC oversample mode - \param[in] adc_periph: ADCx, x=0,1 - \param[out] none - \retval none -*/ -void adc_oversample_mode_enable(uint32_t adc_periph) { ADC_OVSCR(adc_periph) |= ADC_OVSCR_OVSEN; } - -/*! - \brief disable ADC oversample mode - \param[in] adc_periph: ADCx, x=0,1 - \param[out] none - \retval none -*/ -void adc_oversample_mode_disable(uint32_t adc_periph) { ADC_OVSCR(adc_periph) &= ~((uint32_t)ADC_OVSCR_OVSEN); } +/*!
+ \file gd32vf103_adc.c
+ \brief ADC driver
+
+ \version 2020-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
+*/
+
+/*
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
+
+ Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ 3. Neither the name of the copyright holder nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+OF SUCH DAMAGE.
+*/
+
+#include "gd32vf103_adc.h"
+#include "gd32vf103_rcu.h"
+
+/* discontinuous mode macro*/
+#define ADC_CHANNEL_LENGTH_SUBTRACT_ONE ((uint8_t)1U)
+
+/* ADC regular channel macro */
+#define ADC_REGULAR_CHANNEL_RANK_SIX ((uint8_t)6U)
+#define ADC_REGULAR_CHANNEL_RANK_TWELVE ((uint8_t)12U)
+#define ADC_REGULAR_CHANNEL_RANK_SIXTEEN ((uint8_t)16U)
+#define ADC_REGULAR_CHANNEL_RANK_LENGTH ((uint8_t)5U)
+
+/* ADC sampling time macro */
+#define ADC_CHANNEL_SAMPLE_TEN ((uint8_t)10U)
+#define ADC_CHANNEL_SAMPLE_EIGHTEEN ((uint8_t)18U)
+#define ADC_CHANNEL_SAMPLE_LENGTH ((uint8_t)3U)
+
+/* ADC inserted channel macro */
+#define ADC_INSERTED_CHANNEL_RANK_LENGTH ((uint8_t)5U)
+#define ADC_INSERTED_CHANNEL_SHIFT_LENGTH ((uint8_t)15U)
+
+/* ADC inserted channel offset macro */
+#define ADC_OFFSET_LENGTH ((uint8_t)3U)
+#define ADC_OFFSET_SHIFT_LENGTH ((uint8_t)4U)
+
+/*!
+ \brief reset ADC
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[out] none
+ \retval none
+*/
+void adc_deinit(uint32_t adc_periph) {
+ switch (adc_periph) {
+ case ADC0:
+ /* reset ADC0 */
+ rcu_periph_reset_enable(RCU_ADC0RST);
+ rcu_periph_reset_disable(RCU_ADC0RST);
+ break;
+ case ADC1:
+ /* reset ADC1 */
+ rcu_periph_reset_enable(RCU_ADC1RST);
+ rcu_periph_reset_disable(RCU_ADC1RST);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief configure the ADC sync mode
+ \param[in] mode: ADC mode
+ only one parameter can be selected which is shown as below:
+ \arg ADC_MODE_FREE: all the ADCs work independently
+ \arg ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL: ADC0 and ADC1 work in combined regular parallel + inserted parallel mode
+ \arg ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION: ADC0 and ADC1 work in combined regular parallel + trigger rotation mode
+ \arg ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_FAST: ADC0 and ADC1 work in combined inserted parallel + follow-up fast mode
+ \arg ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_SLOW: ADC0 and ADC1 work in combined inserted parallel + follow-up slow mode
+ \arg ADC_DAUL_INSERTED_PARALLEL: ADC0 and ADC1 work in inserted parallel mode only
+ \arg ADC_DAUL_REGULAL_PARALLEL: ADC0 and ADC1 work in regular parallel mode only
+ \arg ADC_DAUL_REGULAL_FOLLOWUP_FAST: ADC0 and ADC1 work in follow-up fast mode only
+ \arg ADC_DAUL_REGULAL_FOLLOWUP_SLOW: ADC0 and ADC1 work in follow-up slow mode only
+ \arg ADC_DAUL_INSERTED_TRIGGER_ROTATION: ADC0 and ADC1 work in trigger rotation mode only
+ \param[out] none
+ \retval none
+*/
+void adc_mode_config(uint32_t mode) {
+ ADC_CTL0(ADC0) &= ~(ADC_CTL0_SYNCM);
+ ADC_CTL0(ADC0) |= mode;
+}
+
+/*!
+ \brief enable or disable ADC special function
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] function: the function to config
+ only one parameter can be selected which is shown as below:
+ \arg ADC_SCAN_MODE: scan mode select
+ \arg ADC_INSERTED_CHANNEL_AUTO: inserted channel group convert automatically
+ \arg ADC_CONTINUOUS_MODE: continuous mode select
+ \param[in] newvalue: ENABLE or DISABLE
+ \param[out] none
+ \retval none
+*/
+void adc_special_function_config(uint32_t adc_periph, uint32_t function, ControlStatus newvalue) {
+ if (newvalue) {
+ if (0U != (function & ADC_SCAN_MODE)) {
+ /* enable scan mode */
+ ADC_CTL0(adc_periph) |= ADC_SCAN_MODE;
+ }
+ if (0U != (function & ADC_INSERTED_CHANNEL_AUTO)) {
+ /* enable inserted channel group convert automatically */
+ ADC_CTL0(adc_periph) |= ADC_INSERTED_CHANNEL_AUTO;
+ }
+ if (0U != (function & ADC_CONTINUOUS_MODE)) {
+ /* enable continuous mode */
+ ADC_CTL1(adc_periph) |= ADC_CONTINUOUS_MODE;
+ }
+ } else {
+ if (0U != (function & ADC_SCAN_MODE)) {
+ /* disable scan mode */
+ ADC_CTL0(adc_periph) &= ~ADC_SCAN_MODE;
+ }
+ if (0U != (function & ADC_INSERTED_CHANNEL_AUTO)) {
+ /* disable inserted channel group convert automatically */
+ ADC_CTL0(adc_periph) &= ~ADC_INSERTED_CHANNEL_AUTO;
+ }
+ if (0U != (function & ADC_CONTINUOUS_MODE)) {
+ /* disable continuous mode */
+ ADC_CTL1(adc_periph) &= ~ADC_CONTINUOUS_MODE;
+ }
+ }
+}
+
+/*!
+ \brief configure ADC data alignment
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] data_alignment: data alignment select
+ only one parameter can be selected which is shown as below:
+ \arg ADC_DATAALIGN_RIGHT: LSB alignment
+ \arg ADC_DATAALIGN_LEFT: MSB alignment
+ \param[out] none
+ \retval none
+*/
+void adc_data_alignment_config(uint32_t adc_periph, uint32_t data_alignment) {
+ if (ADC_DATAALIGN_RIGHT != data_alignment) {
+ /* MSB alignment */
+ ADC_CTL1(adc_periph) |= ADC_CTL1_DAL;
+ } else {
+ /* LSB alignment */
+ ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DAL);
+ }
+}
+
+/*!
+ \brief enable ADC interface
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[out] none
+ \retval none
+*/
+void adc_enable(uint32_t adc_periph) {
+ if ((uint32_t)RESET == (ADC_CTL1(adc_periph) & ADC_CTL1_ADCON)) {
+ /* enable ADC */
+ ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_ADCON;
+ }
+}
+
+/*!
+ \brief disable ADC interface
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[out] none
+ \retval none
+*/
+void adc_disable(uint32_t adc_periph) {
+ /* disable ADC */
+ ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ADCON);
+}
+
+/*!
+ \brief ADC calibration and reset calibration
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[out] none
+ \retval none
+*/
+void adc_calibration_enable(uint32_t adc_periph) {
+ /* reset the selected ADC1 calibration registers */
+ ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_RSTCLB;
+ /* check the RSTCLB bit state */
+ while ((uint32_t)RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_RSTCLB)) {}
+ /* enable ADC calibration process */
+ ADC_CTL1(adc_periph) |= ADC_CTL1_CLB;
+ /* check the CLB bit state */
+ while ((uint32_t)RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_CLB)) {}
+}
+
+/*!
+ \brief enable the temperature sensor and Vrefint channel
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void adc_tempsensor_vrefint_enable(void) {
+ /* enable the temperature sensor and Vrefint channel */
+ ADC_CTL1(ADC0) |= ADC_CTL1_TSVREN;
+}
+
+/*!
+ \brief disable the temperature sensor and Vrefint channel
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void adc_tempsensor_vrefint_disable(void) {
+ /* disable the temperature sensor and Vrefint channel */
+ ADC_CTL1(ADC0) &= ~ADC_CTL1_TSVREN;
+}
+
+/*!
+ \brief enable DMA request
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[out] none
+ \retval none
+*/
+void adc_dma_mode_enable(uint32_t adc_periph) {
+ /* enable DMA request */
+ ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_DMA);
+}
+
+/*!
+ \brief disable DMA request
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[out] none
+ \retval none
+*/
+void adc_dma_mode_disable(uint32_t adc_periph) {
+ /* disable DMA request */
+ ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DMA);
+}
+
+/*!
+ \brief configure ADC discontinuous mode
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] adc_channel_group: select the channel group
+ only one parameter can be selected which is shown as below:
+ \arg ADC_REGULAR_CHANNEL: regular channel group
+ \arg ADC_INSERTED_CHANNEL: inserted channel group
+ \arg ADC_CHANNEL_DISCON_DISABLE: disable discontinuous mode of regular & inserted channel
+ \param[in] length: number of conversions in discontinuous mode,the number can be 1..8
+ for regular channel, the number has no effect for inserted channel
+ \param[out] none
+ \retval none
+*/
+void adc_discontinuous_mode_config(uint32_t adc_periph, uint8_t adc_channel_group, uint8_t length) {
+ /* disable discontinuous mode of regular & inserted channel */
+ ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_DISRC | ADC_CTL0_DISIC));
+ switch (adc_channel_group) {
+ case ADC_REGULAR_CHANNEL:
+ /* config the number of conversions in discontinuous mode */
+ ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_DISNUM);
+ ADC_CTL0(adc_periph) |= CTL0_DISNUM(((uint32_t)length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE));
+ /* enable regular channel group discontinuous mode */
+ ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISRC;
+ break;
+ case ADC_INSERTED_CHANNEL:
+ /* enable inserted channel group discontinuous mode */
+ ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISIC;
+ break;
+ case ADC_CHANNEL_DISCON_DISABLE:
+ /* disable discontinuous mode of regular & inserted channel */
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief configure the length of regular channel group or inserted channel group
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] adc_channel_group: select the channel group
+ only one parameter can be selected which is shown as below:
+ \arg ADC_REGULAR_CHANNEL: regular channel group
+ \arg ADC_INSERTED_CHANNEL: inserted channel group
+ \param[in] length: the length of the channel
+ regular channel 1-16
+ inserted channel 1-4
+ \param[out] none
+ \retval none
+*/
+void adc_channel_length_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t length) {
+ switch (adc_channel_group) {
+ case ADC_REGULAR_CHANNEL:
+ /* configure the length of regular channel group */
+ ADC_RSQ0(adc_periph) &= ~((uint32_t)ADC_RSQ0_RL);
+ ADC_RSQ0(adc_periph) |= RSQ0_RL((uint32_t)(length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE));
+ break;
+ case ADC_INSERTED_CHANNEL:
+ /* configure the length of inserted channel group */
+ ADC_ISQ(adc_periph) &= ~((uint32_t)ADC_ISQ_IL);
+ ADC_ISQ(adc_periph) |= ISQ_IL((uint32_t)(length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE));
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief configure ADC regular channel
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] rank: the regular group sequence rank,this parameter must be between 0 to 15
+ \param[in] adc_channel: the selected ADC channel
+ only one parameter can be selected which is shown as below:
+ \arg ADC_CHANNEL_x(x=0..17)(x=16 and x=17 are only for ADC0): ADC Channelx
+ \param[in] sample_time: the sample time value
+ only one parameter can be selected which is shown as below:
+ \arg ADC_SAMPLETIME_1POINT5: 1.5 cycles
+ \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles
+ \arg ADC_SAMPLETIME_13POINT5: 13.5 cycles
+ \arg ADC_SAMPLETIME_28POINT5: 28.5 cycles
+ \arg ADC_SAMPLETIME_41POINT5: 41.5 cycles
+ \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles
+ \arg ADC_SAMPLETIME_71POINT5: 71.5 cycles
+ \arg ADC_SAMPLETIME_239POINT5: 239.5 cycles
+ \param[out] none
+ \retval none
+*/
+void adc_regular_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time) {
+ uint32_t rsq, sampt;
+
+ /* ADC regular sequence config */
+ if (rank < ADC_REGULAR_CHANNEL_RANK_SIX) {
+ /* the regular group sequence rank is smaller than six */
+ rsq = ADC_RSQ2(adc_periph);
+ rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH * rank)));
+ /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */
+ rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH * rank));
+ ADC_RSQ2(adc_periph) = rsq;
+ } else if (rank < ADC_REGULAR_CHANNEL_RANK_TWELVE) {
+ /* the regular group sequence rank is smaller than twelve */
+ rsq = ADC_RSQ1(adc_periph);
+ rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH * (rank - ADC_REGULAR_CHANNEL_RANK_SIX))));
+ /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */
+ rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH * (rank - ADC_REGULAR_CHANNEL_RANK_SIX)));
+ ADC_RSQ1(adc_periph) = rsq;
+ } else if (rank < ADC_REGULAR_CHANNEL_RANK_SIXTEEN) {
+ /* the regular group sequence rank is smaller than sixteen */
+ rsq = ADC_RSQ0(adc_periph);
+ rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH * (rank - ADC_REGULAR_CHANNEL_RANK_TWELVE))));
+ /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */
+ rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH * (rank - ADC_REGULAR_CHANNEL_RANK_TWELVE)));
+ ADC_RSQ0(adc_periph) = rsq;
+ } else {
+ }
+
+ /* ADC sampling time config */
+ if (adc_channel < ADC_CHANNEL_SAMPLE_TEN) {
+ /* the regular group sequence rank is smaller than ten */
+ sampt = ADC_SAMPT1(adc_periph);
+ sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel)));
+ /* channel sample time set*/
+ sampt |= (uint32_t)(sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel));
+ ADC_SAMPT1(adc_periph) = sampt;
+ } else if (adc_channel < ADC_CHANNEL_SAMPLE_EIGHTEEN) {
+ /* the regular group sequence rank is smaller than eighteen */
+ sampt = ADC_SAMPT0(adc_periph);
+ sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN))));
+ /* channel sample time set*/
+ sampt |= (uint32_t)(sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN)));
+ ADC_SAMPT0(adc_periph) = sampt;
+ } else {
+ }
+}
+
+/*!
+ \brief configure ADC inserted channel
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] rank: the inserted group sequencer rank,this parameter must be between 0 to 3
+ \param[in] adc_channel: the selected ADC channel
+ only one parameter can be selected which is shown as below:
+ \arg ADC_CHANNEL_x(x=0..17)(x=16 and x=17 are only for ADC0): ADC Channelx
+ \param[in] sample_time: The sample time value
+ only one parameter can be selected which is shown as below:
+ \arg ADC_SAMPLETIME_1POINT5: 1.5 cycles
+ \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles
+ \arg ADC_SAMPLETIME_13POINT5: 13.5 cycles
+ \arg ADC_SAMPLETIME_28POINT5: 28.5 cycles
+ \arg ADC_SAMPLETIME_41POINT5: 41.5 cycles
+ \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles
+ \arg ADC_SAMPLETIME_71POINT5: 71.5 cycles
+ \arg ADC_SAMPLETIME_239POINT5: 239.5 cycles
+ \param[out] none
+ \retval none
+*/
+void adc_inserted_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time) {
+ uint8_t inserted_length;
+ uint32_t isq, sampt;
+ /* get inserted channel group length */
+ inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph), 20U, 21U);
+ /* the channel number is written to these bits to select a channel as the nth conversion in the inserted channel group */
+ isq = ADC_ISQ(adc_periph);
+ isq &= ~((uint32_t)(ADC_ISQ_ISQN << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH - (inserted_length - rank) * ADC_INSERTED_CHANNEL_RANK_LENGTH)));
+ isq |= ((uint32_t)adc_channel << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH - (inserted_length - rank) * ADC_INSERTED_CHANNEL_RANK_LENGTH));
+ ADC_ISQ(adc_periph) = isq;
+
+ /* ADC sampling time config */
+ if (adc_channel < ADC_CHANNEL_SAMPLE_TEN) {
+ /* the inserted group sequence rank is smaller than ten */
+ sampt = ADC_SAMPT1(adc_periph);
+ sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel)));
+ /* channel sample time set*/
+ sampt |= (uint32_t)sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel);
+ ADC_SAMPT1(adc_periph) = sampt;
+ } else if (adc_channel < ADC_CHANNEL_SAMPLE_EIGHTEEN) {
+ /* the inserted group sequence rank is smaller than eighteen */
+ sampt = ADC_SAMPT0(adc_periph);
+ sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN))));
+ /* channel sample time set*/
+ sampt |= ((uint32_t)sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN)));
+ ADC_SAMPT0(adc_periph) = sampt;
+ } else {
+ }
+}
+
+/*!
+ \brief configure ADC inserted channel offset
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] inserted_channel: insert channel select
+ only one parameter can be selected
+ \arg ADC_INSERTED_CHANNEL_0: inserted channel0
+ \arg ADC_INSERTED_CHANNEL_1: inserted channel1
+ \arg ADC_INSERTED_CHANNEL_2: inserted channel2
+ \arg ADC_INSERTED_CHANNEL_3: inserted channel3
+ \param[in] offset: the offset data
+ \param[out] none
+ \retval none
+*/
+void adc_inserted_channel_offset_config(uint32_t adc_periph, uint8_t inserted_channel, uint16_t offset) {
+ uint8_t inserted_length;
+ uint32_t num = 0U;
+
+ inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph), 20U, 21U);
+ num = ((uint32_t)ADC_OFFSET_LENGTH - ((uint32_t)inserted_length - (uint32_t)inserted_channel));
+
+ if (num <= ADC_OFFSET_LENGTH) {
+ /* calculate the offset of the register */
+ num = num * ADC_OFFSET_SHIFT_LENGTH;
+ /* config the offset of the selected channels */
+ REG32((adc_periph) + 0x14U + num) = IOFFX_IOFF((uint32_t)offset);
+ }
+}
+
+/*!
+ \brief configure ADC external trigger source
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] adc_channel_group: select the channel group
+ only one parameter can be selected which is shown as below:
+ \arg ADC_REGULAR_CHANNEL: regular channel group
+ \arg ADC_INSERTED_CHANNEL: inserted channel group
+ \param[in] external_trigger_source: regular or inserted group trigger source
+ only one parameter can be selected
+ for regular channel:
+ \arg ADC0_1_EXTTRIG_REGULAR_T0_CH0: TIMER0 CH0 event select
+ \arg ADC0_1_EXTTRIG_REGULAR_T0_CH1: TIMER0 CH1 event select
+ \arg ADC0_1_EXTTRIG_REGULAR_T0_CH2: TIMER0 CH2 event select
+ \arg ADC0_1_EXTTRIG_REGULAR_T1_CH1: TIMER1 CH1 event select
+ \arg ADC0_1_EXTTRIG_REGULAR_T2_TRGO: TIMER2 TRGO event select
+ \arg ADC0_1_EXTTRIG_REGULAR_T3_CH3: TIMER3 CH3 event select
+ \arg ADC0_1_EXTTRIG_REGULAR_EXTI_11: external interrupt line 11
+ \arg ADC0_1_EXTTRIG_REGULAR_NONE: software trigger
+ for inserted channel:
+ \arg ADC0_1_EXTTRIG_INSERTED_T0_TRGO: TIMER0 TRGO event select
+ \arg ADC0_1_EXTTRIG_INSERTED_T0_CH3: TIMER0 CH3 event select
+ \arg ADC0_1_EXTTRIG_INSERTED_T1_TRGO: TIMER1 TRGO event select
+ \arg ADC0_1_EXTTRIG_INSERTED_T1_CH0: TIMER1 CH0 event select
+ \arg ADC0_1_EXTTRIG_INSERTED_T2_CH3: TIMER2 CH3 event select
+ \arg ADC0_1_EXTTRIG_INSERTED_T3_TRGO: TIMER3 TRGO event select
+ \arg ADC0_1_EXTTRIG_INSERTED_EXTI_15: external interrupt line 15
+ \arg ADC0_1_EXTTRIG_INSERTED_NONE: software trigger
+ \param[out] none
+ \retval none
+*/
+void adc_external_trigger_source_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t external_trigger_source) {
+ switch (adc_channel_group) {
+ case ADC_REGULAR_CHANNEL:
+ /* configure ADC regular group external trigger source */
+ ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSRC);
+ ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source;
+ break;
+ case ADC_INSERTED_CHANNEL:
+ /* configure ADC inserted group external trigger source */
+ ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSIC);
+ ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source;
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief configure ADC external trigger
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] adc_channel_group: select the channel group
+ one or more parameters can be selected which are shown as below:
+ \arg ADC_REGULAR_CHANNEL: regular channel group
+ \arg ADC_INSERTED_CHANNEL: inserted channel group
+ \param[in] newvalue: ENABLE or DISABLE
+ \param[out] none
+ \retval none
+*/
+void adc_external_trigger_config(uint32_t adc_periph, uint8_t adc_channel_group, ControlStatus newvalue) {
+ if (newvalue) {
+ if (0U != (adc_channel_group & ADC_REGULAR_CHANNEL)) {
+ /* enable ADC regular channel group external trigger */
+ ADC_CTL1(adc_periph) |= ADC_CTL1_ETERC;
+ }
+ if (0U != (adc_channel_group & ADC_INSERTED_CHANNEL)) {
+ /* enable ADC inserted channel group external trigger */
+ ADC_CTL1(adc_periph) |= ADC_CTL1_ETEIC;
+ }
+ } else {
+ if (0U != (adc_channel_group & ADC_REGULAR_CHANNEL)) {
+ /* disable ADC regular channel group external trigger */
+ ADC_CTL1(adc_periph) &= ~ADC_CTL1_ETERC;
+ }
+ if (0U != (adc_channel_group & ADC_INSERTED_CHANNEL)) {
+ /* disable ADC regular channel group external trigger */
+ ADC_CTL1(adc_periph) &= ~ADC_CTL1_ETEIC;
+ }
+ }
+}
+
+/*!
+ \brief enable ADC software trigger
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] adc_channel_group: select the channel group
+ one or more parameters can be selected which are shown as below:
+ \arg ADC_REGULAR_CHANNEL: regular channel group
+ \arg ADC_INSERTED_CHANNEL: inserted channel group
+ \param[out] none
+ \retval none
+*/
+void adc_software_trigger_enable(uint32_t adc_periph, uint8_t adc_channel_group) {
+ if (0U != (adc_channel_group & ADC_REGULAR_CHANNEL)) {
+ /* enable ADC regular channel group software trigger */
+ ADC_CTL1(adc_periph) |= ADC_CTL1_SWRCST;
+ }
+ if (0U != (adc_channel_group & ADC_INSERTED_CHANNEL)) {
+ /* enable ADC inserted channel group software trigger */
+ ADC_CTL1(adc_periph) |= ADC_CTL1_SWICST;
+ }
+}
+
+/*!
+ \brief read ADC regular group data register
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] none
+ \param[out] none
+ \retval the conversion value
+*/
+uint16_t adc_regular_data_read(uint32_t adc_periph) { return (uint16_t)(ADC_RDATA(adc_periph)); }
+
+/*!
+ \brief read ADC inserted group data register
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] inserted_channel: insert channel select
+ only one parameter can be selected
+ \arg ADC_INSERTED_CHANNEL_0: inserted Channel0
+ \arg ADC_INSERTED_CHANNEL_1: inserted channel1
+ \arg ADC_INSERTED_CHANNEL_2: inserted Channel2
+ \arg ADC_INSERTED_CHANNEL_3: inserted Channel3
+ \param[out] none
+ \retval the conversion value
+*/
+uint16_t adc_inserted_data_read(uint32_t adc_periph, uint8_t inserted_channel) {
+ uint32_t idata;
+ /* read the data of the selected channel */
+ switch (inserted_channel) {
+ case ADC_INSERTED_CHANNEL_0:
+ /* read the data of channel 0 */
+ idata = ADC_IDATA0(adc_periph);
+ break;
+ case ADC_INSERTED_CHANNEL_1:
+ /* read the data of channel 1 */
+ idata = ADC_IDATA1(adc_periph);
+ break;
+ case ADC_INSERTED_CHANNEL_2:
+ /* read the data of channel 2 */
+ idata = ADC_IDATA2(adc_periph);
+ break;
+ case ADC_INSERTED_CHANNEL_3:
+ /* read the data of channel 3 */
+ idata = ADC_IDATA3(adc_periph);
+ break;
+ default:
+ idata = 0U;
+ break;
+ }
+ return (uint16_t)idata;
+}
+
+/*!
+ \brief read the last ADC0 and ADC1 conversion result data in sync mode
+ \param[in] none
+ \param[out] none
+ \retval the conversion value
+*/
+uint32_t adc_sync_mode_convert_value_read(void) {
+ /* return conversion value */
+ return ADC_RDATA(ADC0);
+}
+
+/*!
+ \brief configure ADC analog watchdog single channel
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] adc_channel: the selected ADC channel
+ only one parameter can be selected which is shown as below:
+ \arg ADC_CHANNEL_x: ADC Channelx(x=0..17)(x=16 and x=17 are only for ADC0)
+ \param[out] none
+ \retval none
+*/
+void adc_watchdog_single_channel_enable(uint32_t adc_periph, uint8_t adc_channel) {
+ ADC_CTL0(adc_periph) &= (uint32_t) ~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL);
+ /* analog watchdog channel select */
+ ADC_CTL0(adc_periph) |= (uint32_t)adc_channel;
+ ADC_CTL0(adc_periph) |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC);
+}
+
+/*!
+ \brief configure ADC analog watchdog group channel
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] adc_channel_group: the channel group use analog watchdog
+ only one parameter can be selected which is shown as below:
+ \arg ADC_REGULAR_CHANNEL: regular channel group
+ \arg ADC_INSERTED_CHANNEL: inserted channel group
+ \arg ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group
+ \param[out] none
+ \retval none
+*/
+void adc_watchdog_group_channel_enable(uint32_t adc_periph, uint8_t adc_channel_group) {
+ ADC_CTL0(adc_periph) &= (uint32_t) ~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC);
+ /* select the group */
+ switch (adc_channel_group) {
+ case ADC_REGULAR_CHANNEL:
+ /* regular channel analog watchdog enable */
+ ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_RWDEN;
+ break;
+ case ADC_INSERTED_CHANNEL:
+ /* inserted channel analog watchdog enable */
+ ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_IWDEN;
+ break;
+ case ADC_REGULAR_INSERTED_CHANNEL:
+ /* regular and inserted channel analog watchdog enable */
+ ADC_CTL0(adc_periph) |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \brief disable ADC analog watchdog
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[out] none
+ \retval none
+*/
+void adc_watchdog_disable(uint32_t adc_periph) { ADC_CTL0(adc_periph) &= (uint32_t) ~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL); }
+
+/*!
+ \brief configure ADC analog watchdog threshold
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] low_threshold: analog watchdog low threshold, 0..4095
+ \param[in] high_threshold: analog watchdog high threshold, 0..4095
+ \param[out] none
+ \retval none
+*/
+void adc_watchdog_threshold_config(uint32_t adc_periph, uint16_t low_threshold, uint16_t high_threshold) {
+ ADC_WDLT(adc_periph) = (uint32_t)WDLT_WDLT(low_threshold);
+ ADC_WDHT(adc_periph) = (uint32_t)WDHT_WDHT(high_threshold);
+}
+
+/*!
+ \brief get the ADC flag bits
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] adc_flag: the adc flag bits
+ only one parameter can be selected which is shown as below:
+ \arg ADC_FLAG_WDE: analog watchdog event flag
+ \arg ADC_FLAG_EOC: end of group conversion flag
+ \arg ADC_FLAG_EOIC: end of inserted group conversion flag
+ \arg ADC_FLAG_STIC: start flag of inserted channel group
+ \arg ADC_FLAG_STRC: start flag of regular channel group
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus adc_flag_get(uint32_t adc_periph, uint32_t adc_flag) {
+ FlagStatus reval = RESET;
+ if (ADC_STAT(adc_periph) & adc_flag) {
+ reval = SET;
+ }
+ return reval;
+}
+
+/*!
+ \brief clear the ADC flag bits
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] adc_flag: the adc flag bits
+ one or more parameters can be selected which are shown as below:
+ \arg ADC_FLAG_WDE: analog watchdog event flag
+ \arg ADC_FLAG_EOC: end of group conversion flag
+ \arg ADC_FLAG_EOIC: end of inserted group conversion flag
+ \arg ADC_FLAG_STIC: start flag of inserted channel group
+ \arg ADC_FLAG_STRC: start flag of regular channel group
+ \param[out] none
+ \retval none
+*/
+void adc_flag_clear(uint32_t adc_periph, uint32_t adc_flag) { ADC_STAT(adc_periph) &= ~((uint32_t)adc_flag); }
+
+/*!
+ \brief get the bit state of ADCx software start conversion
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] none
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus adc_regular_software_startconv_flag_get(uint32_t adc_periph) {
+ FlagStatus reval = RESET;
+ if ((uint32_t)RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_SWRCST)) {
+ reval = SET;
+ }
+ return reval;
+}
+
+/*!
+ \brief get the bit state of ADCx software inserted channel start conversion
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] none
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus adc_inserted_software_startconv_flag_get(uint32_t adc_periph) {
+ FlagStatus reval = RESET;
+ if ((uint32_t)RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_SWICST)) {
+ reval = SET;
+ }
+ return reval;
+}
+
+/*!
+ \brief get the ADC interrupt bits
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] adc_interrupt: the adc interrupt bits
+ only one parameter can be selected which is shown as below:
+ \arg ADC_INT_FLAG_WDE: analog watchdog interrupt
+ \arg ADC_INT_FLAG_EOC: end of group conversion interrupt
+ \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt
+ \param[out] none
+ \retval FlagStatus: SET or RESET
+*/
+FlagStatus adc_interrupt_flag_get(uint32_t adc_periph, uint32_t adc_interrupt) {
+ FlagStatus interrupt_flag = RESET;
+ uint32_t state;
+ /* check the interrupt bits */
+ switch (adc_interrupt) {
+ case ADC_INT_FLAG_WDE:
+ /* get the ADC analog watchdog interrupt bits */
+ state = ADC_STAT(adc_periph) & ADC_STAT_WDE;
+ if ((ADC_CTL0(adc_periph) & ADC_CTL0_WDEIE) && state) {
+ interrupt_flag = SET;
+ }
+ break;
+ case ADC_INT_FLAG_EOC:
+ /* get the ADC end of group conversion interrupt bits */
+ state = ADC_STAT(adc_periph) & ADC_STAT_EOC;
+ if ((ADC_CTL0(adc_periph) & ADC_CTL0_EOCIE) && state) {
+ interrupt_flag = SET;
+ }
+ break;
+ case ADC_INT_FLAG_EOIC:
+ /* get the ADC end of inserted group conversion interrupt bits */
+ state = ADC_STAT(adc_periph) & ADC_STAT_EOIC;
+ if ((ADC_CTL0(adc_periph) & ADC_CTL0_EOICIE) && state) {
+ interrupt_flag = SET;
+ }
+ break;
+ default:
+ break;
+ }
+ return interrupt_flag;
+}
+
+/*!
+ \brief clear the ADC flag
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] adc_interrupt: the adc status flag
+ one or more parameters can be selected which are shown as below:
+ \arg ADC_INT_FLAG_WDE: analog watchdog interrupt
+ \arg ADC_INT_FLAG_EOC: end of group conversion interrupt
+ \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt
+ \param[out] none
+ \retval none
+*/
+void adc_interrupt_flag_clear(uint32_t adc_periph, uint32_t adc_interrupt) { ADC_STAT(adc_periph) &= ~((uint32_t)adc_interrupt); }
+
+/*!
+ \brief enable ADC interrupt
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] adc_interrupt: the adc interrupt
+ one or more parameters can be selected which are shown as below:
+ \arg ADC_INT_WDE: analog watchdog interrupt flag
+ \arg ADC_INT_EOC: end of group conversion interrupt flag
+ \arg ADC_INT_EOIC: end of inserted group conversion interrupt flag
+ \param[out] none
+ \retval none
+*/
+void adc_interrupt_enable(uint32_t adc_periph, uint32_t adc_interrupt) {
+ /* enable ADC analog watchdog interrupt */
+ if (0U != (adc_interrupt & ADC_INT_WDE)) {
+ ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_WDEIE;
+ }
+ /* enable ADC end of group conversion interrupt */
+ if (0U != (adc_interrupt & ADC_INT_EOC)) {
+ ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_EOCIE;
+ }
+ /* enable ADC end of inserted group conversion interrupt */
+ if (0U != (adc_interrupt & ADC_INT_EOIC)) {
+ ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_EOICIE;
+ }
+}
+
+/*!
+ \brief disable ADC interrupt
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] adc_interrupt: the adc interrupt flag
+ one or more parameters can be selected which are shown as below:
+ \arg ADC_INT_WDE: analog watchdog interrupt flag
+ \arg ADC_INT_EOC: end of group conversion interrupt flag
+ \arg ADC_INT_EOIC: end of inserted group conversion interrupt flag
+ \param[out] none
+ \retval none
+*/
+void adc_interrupt_disable(uint32_t adc_periph, uint32_t adc_interrupt) {
+ /* disable ADC analog watchdog interrupt */
+ if (0U != (adc_interrupt & ADC_INT_WDE)) {
+ ADC_CTL0(adc_periph) &= ~(uint32_t)ADC_CTL0_WDEIE;
+ }
+ /* disable ADC end of group conversion interrupt */
+ if (0U != (adc_interrupt & ADC_INT_EOC)) {
+ ADC_CTL0(adc_periph) &= ~(uint32_t)ADC_CTL0_EOCIE;
+ }
+ /* disable ADC end of inserted group conversion interrupt */
+ if (0U != (adc_interrupt & ADC_INT_EOIC)) {
+ ADC_CTL0(adc_periph) &= ~(uint32_t)ADC_CTL0_EOICIE;
+ }
+}
+
+/*!
+ \brief adc resolution config
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] resolution: ADC resolution
+ only one parameter can be selected which is shown as below:
+ \arg ADC_RESOLUTION_12B: 12-bit ADC resolution
+ \arg ADC_RESOLUTION_10B: 10-bit ADC resolution
+ \arg ADC_RESOLUTION_8B: 8-bit ADC resolution
+ \arg ADC_RESOLUTION_6B: 6-bit ADC resolution
+ \param[out] none
+ \retval none
+*/
+void adc_resolution_config(uint32_t adc_periph, uint32_t resolution) {
+ ADC_OVSCR(adc_periph) &= ~((uint32_t)ADC_OVSCR_DRES);
+ ADC_OVSCR(adc_periph) |= (uint32_t)resolution;
+}
+
+/*!
+ \brief adc oversample mode config
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[in] mode: ADC oversampling mode
+ only one parameter can be selected which is shown as below:
+ \arg ADC_OVERSAMPLING_ALL_CONVERT: all oversampled conversions for a channel
+ are done consecutively after a trigger
+ \arg ADC_OVERSAMPLING_ONE_CONVERT: each oversampled conversion for a channel
+ needs a trigger
+ \param[in] shift: ADC oversampling shift
+ only one parameter can be selected which is shown as below:
+ \arg ADC_OVERSAMPLING_SHIFT_NONE: no oversampling shift
+ \arg ADC_OVERSAMPLING_SHIFT_1B: 1-bit oversampling shift
+ \arg ADC_OVERSAMPLING_SHIFT_2B: 2-bit oversampling shift
+ \arg ADC_OVERSAMPLING_SHIFT_3B: 3-bit oversampling shift
+ \arg ADC_OVERSAMPLING_SHIFT_4B: 3-bit oversampling shift
+ \arg ADC_OVERSAMPLING_SHIFT_5B: 5-bit oversampling shift
+ \arg ADC_OVERSAMPLING_SHIFT_6B: 6-bit oversampling shift
+ \arg ADC_OVERSAMPLING_SHIFT_7B: 7-bit oversampling shift
+ \arg ADC_OVERSAMPLING_SHIFT_8B: 8-bit oversampling shift
+ \param[in] ratio: ADC oversampling ratio
+ only one parameter can be selected which is shown as below:
+ \arg ADC_OVERSAMPLING_RATIO_MUL2: oversampling ratio X2
+ \arg ADC_OVERSAMPLING_RATIO_MUL4: oversampling ratio X4
+ \arg ADC_OVERSAMPLING_RATIO_MUL8: oversampling ratio X8
+ \arg ADC_OVERSAMPLING_RATIO_MUL16: oversampling ratio X16
+ \arg ADC_OVERSAMPLING_RATIO_MUL32: oversampling ratio X32
+ \arg ADC_OVERSAMPLING_RATIO_MUL64: oversampling ratio X64
+ \arg ADC_OVERSAMPLING_RATIO_MUL128: oversampling ratio X128
+ \arg ADC_OVERSAMPLING_RATIO_MUL256: oversampling ratio X256
+ \param[out] none
+ \retval none
+*/
+void adc_oversample_mode_config(uint32_t adc_periph, uint8_t mode, uint16_t shift, uint8_t ratio) {
+ if (mode) {
+ ADC_OVSCR(adc_periph) |= (uint32_t)ADC_OVSCR_TOVS;
+ } else {
+ ADC_OVSCR(adc_periph) &= ~((uint32_t)ADC_OVSCR_TOVS);
+ }
+ /* config the shift and ratio */
+ ADC_OVSCR(adc_periph) &= ~((uint32_t)(ADC_OVSCR_OVSR | ADC_OVSCR_OVSS));
+ ADC_OVSCR(adc_periph) |= ((uint32_t)shift | (uint32_t)ratio);
+}
+
+/*!
+ \brief enable ADC oversample mode
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[out] none
+ \retval none
+*/
+void adc_oversample_mode_enable(uint32_t adc_periph) { ADC_OVSCR(adc_periph) |= ADC_OVSCR_OVSEN; }
+
+/*!
+ \brief disable ADC oversample mode
+ \param[in] adc_periph: ADCx, x=0,1
+ \param[out] none
+ \retval none
+*/
+void adc_oversample_mode_disable(uint32_t adc_periph) { ADC_OVSCR(adc_periph) &= ~((uint32_t)ADC_OVSCR_OVSEN); }
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_bkp.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_bkp.c index 2abede0c..2c26ab52 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_bkp.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_bkp.c @@ -2,11 +2,12 @@ \file gd32vf103_bkp.c
\brief BKP driver
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -33,6 +34,7 @@ OF SUCH DAMAGE. */
#include "gd32vf103_bkp.h"
+#include "gd32vf103_rcu.h"
/* BKP register bits offset */
#define BKP_TAMPER_BITS_OFFSET ((uint32_t)8U)
@@ -43,10 +45,7 @@ OF SUCH DAMAGE. \param[out] none
\retval none
*/
-void bkp_deinit(void) {
- /* reset BKP domain register*/
- rcu_bkp_reset_enable();
- rcu_bkp_reset_disable();
+void bkp_deinit(void) { /* reset BKP domain register*/
}
/*!
@@ -60,9 +59,9 @@ void bkp_deinit(void) { */
void bkp_data_write(bkp_data_register_enum register_number, uint16_t data) {
if ((register_number >= BKP_DATA_10) && (register_number <= BKP_DATA_41)) {
- BKP_DATA10_41(register_number - 1U) = data;
+ BKP_DATA10_41((uint32_t)register_number - 1U) = data;
} else if ((register_number >= BKP_DATA_0) && (register_number <= BKP_DATA_9)) {
- BKP_DATA0_9(register_number - 1U) = data;
+ BKP_DATA0_9((uint32_t)register_number - 1U) = data;
} else {
/* illegal parameters */
}
@@ -81,9 +80,9 @@ uint16_t bkp_data_read(bkp_data_register_enum register_number) { /* get the data from the BKP data register */
if ((register_number >= BKP_DATA_10) && (register_number <= BKP_DATA_41)) {
- data = BKP_DATA10_41(register_number - 1U);
+ data = BKP_DATA10_41((uint32_t)register_number - 1U);
} else if ((register_number >= BKP_DATA_0) && (register_number <= BKP_DATA_9)) {
- data = BKP_DATA0_9(register_number - 1U);
+ data = BKP_DATA0_9((uint32_t)register_number - 1U);
} else {
/* illegal parameters */
}
@@ -216,7 +215,7 @@ void bkp_interrupt_disable(void) { BKP_TPCS &= (uint16_t)~BKP_TPCS_TPIE; } \retval FlagStatus: SET or RESET
*/
FlagStatus bkp_flag_get(void) {
- if (RESET != (BKP_TPCS & BKP_FLAG_TAMPER)) {
+ if (BKP_TPCS & BKP_FLAG_TAMPER) {
return SET;
} else {
return RESET;
@@ -238,7 +237,7 @@ void bkp_flag_clear(void) { BKP_TPCS |= (uint16_t)(BKP_FLAG_TAMPER >> BKP_TAMPER \retval FlagStatus: SET or RESET
*/
FlagStatus bkp_interrupt_flag_get(void) {
- if (RESET != (BKP_TPCS & BKP_INT_FLAG_TAMPER)) {
+ if (BKP_TPCS & BKP_INT_FLAG_TAMPER) {
return SET;
} else {
return RESET;
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_can.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_can.c deleted file mode 100644 index 64bcecf8..00000000 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_can.c +++ /dev/null @@ -1,940 +0,0 @@ -/*!
- \file gd32vf103_can.c
- \brief CAN driver
-
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
-*/
-
-/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
-
- Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- 3. Neither the name of the copyright holder nor the names of its contributors
- may be used to endorse or promote products derived from this software without
- specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-OF SUCH DAMAGE.
-*/
-
-#include "gd32vf103_can.h"
-
-#define CAN_ERROR_HANDLE(s) \
- do { \
- } while (1)
-
-/*!
- \brief deinitialize CAN
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[out] none
- \retval none
-*/
-void can_deinit(uint32_t can_periph) {
- if (CAN0 == can_periph) {
- rcu_periph_reset_enable(RCU_CAN0RST);
- rcu_periph_reset_disable(RCU_CAN0RST);
- } else {
- rcu_periph_reset_enable(RCU_CAN1RST);
- rcu_periph_reset_disable(RCU_CAN1RST);
- }
-}
-
-/*!
- \brief initialize CAN parameter struct with a default value
- \param[in] type: the type of CAN parameter struct
- only one parameter can be selected which is shown as below:
- \arg CAN_INIT_STRUCT: the CAN initial struct
- \arg CAN_FILTER_STRUCT: the CAN filter struct
- \arg CAN_TX_MESSAGE_STRUCT: the CAN TX message struct
- \arg CAN_RX_MESSAGE_STRUCT: the CAN RX message struct
- \param[in] p_struct: the pointer of the specific struct
- \param[out] none
- \retval none
-*/
-void can_struct_para_init(can_struct_type_enum type, void *p_struct) {
- uint8_t i;
-
- /* get type of the struct */
- switch (type) {
- /* used for can_init() */
- case CAN_INIT_STRUCT:
- ((can_parameter_struct *)p_struct)->auto_bus_off_recovery = DISABLE;
- ((can_parameter_struct *)p_struct)->no_auto_retrans = DISABLE;
- ((can_parameter_struct *)p_struct)->auto_wake_up = DISABLE;
- ((can_parameter_struct *)p_struct)->prescaler = 0x03FFU;
- ((can_parameter_struct *)p_struct)->rec_fifo_overwrite = DISABLE;
- ((can_parameter_struct *)p_struct)->resync_jump_width = CAN_BT_SJW_1TQ;
- ((can_parameter_struct *)p_struct)->time_segment_1 = CAN_BT_BS1_3TQ;
- ((can_parameter_struct *)p_struct)->time_segment_2 = CAN_BT_BS2_1TQ;
- ((can_parameter_struct *)p_struct)->time_triggered = DISABLE;
- ((can_parameter_struct *)p_struct)->trans_fifo_order = DISABLE;
- ((can_parameter_struct *)p_struct)->working_mode = CAN_NORMAL_MODE;
-
- break;
- /* used for can_filter_init() */
- case CAN_FILTER_STRUCT:
- ((can_filter_parameter_struct *)p_struct)->filter_bits = CAN_FILTERBITS_32BIT;
- ((can_filter_parameter_struct *)p_struct)->filter_enable = DISABLE;
- ((can_filter_parameter_struct *)p_struct)->filter_fifo_number = CAN_FIFO0;
- ((can_filter_parameter_struct *)p_struct)->filter_list_high = 0x0000U;
- ((can_filter_parameter_struct *)p_struct)->filter_list_low = 0x0000U;
- ((can_filter_parameter_struct *)p_struct)->filter_mask_high = 0x0000U;
- ((can_filter_parameter_struct *)p_struct)->filter_mask_low = 0x0000U;
- ((can_filter_parameter_struct *)p_struct)->filter_mode = CAN_FILTERMODE_MASK;
- ((can_filter_parameter_struct *)p_struct)->filter_number = 0U;
-
- break;
- /* used for can_message_transmit() */
- case CAN_TX_MESSAGE_STRUCT:
- for (i = 0U; i < 8U; i++) {
- ((can_trasnmit_message_struct *)p_struct)->tx_data[i] = 0U;
- }
-
- ((can_trasnmit_message_struct *)p_struct)->tx_dlen = 0u;
- ((can_trasnmit_message_struct *)p_struct)->tx_efid = 0U;
- ((can_trasnmit_message_struct *)p_struct)->tx_ff = (uint8_t)CAN_FF_STANDARD;
- ((can_trasnmit_message_struct *)p_struct)->tx_ft = (uint8_t)CAN_FT_DATA;
- ((can_trasnmit_message_struct *)p_struct)->tx_sfid = 0U;
-
- break;
- /* used for can_message_receive() */
- case CAN_RX_MESSAGE_STRUCT:
- for (i = 0U; i < 8U; i++) {
- ((can_receive_message_struct *)p_struct)->rx_data[i] = 0U;
- }
-
- ((can_receive_message_struct *)p_struct)->rx_dlen = 0U;
- ((can_receive_message_struct *)p_struct)->rx_efid = 0U;
- ((can_receive_message_struct *)p_struct)->rx_ff = (uint8_t)CAN_FF_STANDARD;
- ((can_receive_message_struct *)p_struct)->rx_fi = 0U;
- ((can_receive_message_struct *)p_struct)->rx_ft = (uint8_t)CAN_FT_DATA;
- ((can_receive_message_struct *)p_struct)->rx_sfid = 0U;
-
- break;
-
- default:
- CAN_ERROR_HANDLE("parameter is invalid \r\n");
- }
-}
-
-/*!
- \brief initialize CAN
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[in] can_parameter_init: parameters for CAN initializtion
- \arg working_mode: CAN_NORMAL_MODE, CAN_LOOPBACK_MODE, CAN_SILENT_MODE, CAN_SILENT_LOOPBACK_MODE
- \arg resync_jump_width: CAN_BT_SJW_xTQ(x=1, 2, 3, 4)
- \arg time_segment_1: CAN_BT_BS1_xTQ(1..16)
- \arg time_segment_2: CAN_BT_BS2_xTQ(1..8)
- \arg time_triggered: ENABLE or DISABLE
- \arg auto_bus_off_recovery: ENABLE or DISABLE
- \arg auto_wake_up: ENABLE or DISABLE
- \arg no_auto_retrans: ENABLE or DISABLE
- \arg rec_fifo_overwrite: ENABLE or DISABLE
- \arg trans_fifo_order: ENABLE or DISABLE
- \arg prescaler: 0x0000 - 0x03FF
- \param[out] none
- \retval ErrStatus: SUCCESS or ERROR
-*/
-ErrStatus can_init(uint32_t can_periph, can_parameter_struct *can_parameter_init) {
- uint32_t timeout = CAN_TIMEOUT;
- ErrStatus flag = ERROR;
-
- /* disable sleep mode */
- CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD;
- /* enable initialize mode */
- CAN_CTL(can_periph) |= CAN_CTL_IWMOD;
- /* wait ACK */
- while ((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)) {
- timeout--;
- }
- /* check initialize working success */
- if (CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) {
- flag = ERROR;
- } else {
- /* set the bit timing register */
- CAN_BT(can_periph) = (BT_MODE((uint32_t)can_parameter_init->working_mode) | BT_SJW((uint32_t)can_parameter_init->resync_jump_width) | BT_BS1((uint32_t)can_parameter_init->time_segment_1)
- | BT_BS2((uint32_t)can_parameter_init->time_segment_2) | BT_BAUDPSC(((uint32_t)(can_parameter_init->prescaler) - 1U)));
-
- /* time trigger communication mode */
- if (ENABLE == can_parameter_init->time_triggered) {
- CAN_CTL(can_periph) |= CAN_CTL_TTC;
- } else {
- CAN_CTL(can_periph) &= ~CAN_CTL_TTC;
- }
- /* automatic bus-off managment */
- if (ENABLE == can_parameter_init->auto_bus_off_recovery) {
- CAN_CTL(can_periph) |= CAN_CTL_ABOR;
- } else {
- CAN_CTL(can_periph) &= ~CAN_CTL_ABOR;
- }
- /* automatic wakeup mode */
- if (ENABLE == can_parameter_init->auto_wake_up) {
- CAN_CTL(can_periph) |= CAN_CTL_AWU;
- } else {
- CAN_CTL(can_periph) &= ~CAN_CTL_AWU;
- }
- /* automatic retransmission mode disable*/
- if (ENABLE == can_parameter_init->no_auto_retrans) {
- CAN_CTL(can_periph) |= CAN_CTL_ARD;
- } else {
- CAN_CTL(can_periph) &= ~CAN_CTL_ARD;
- }
- /* receive fifo overwrite mode */
- if (ENABLE == can_parameter_init->rec_fifo_overwrite) {
- CAN_CTL(can_periph) |= CAN_CTL_RFOD;
- } else {
- CAN_CTL(can_periph) &= ~CAN_CTL_RFOD;
- }
- /* transmit fifo order */
- if (ENABLE == can_parameter_init->trans_fifo_order) {
- CAN_CTL(can_periph) |= CAN_CTL_TFO;
- } else {
- CAN_CTL(can_periph) &= ~CAN_CTL_TFO;
- }
- /* disable initialize mode */
- CAN_CTL(can_periph) &= ~CAN_CTL_IWMOD;
- timeout = CAN_TIMEOUT;
- /* wait the ACK */
- while ((CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)) {
- timeout--;
- }
- /* check exit initialize mode */
- if (0U != timeout) {
- flag = SUCCESS;
- }
- }
- CAN_TMI0(can_periph) = 0x0;
- CAN_TMI1(can_periph) = 0x0;
- CAN_TMI2(can_periph) = 0x0;
- CAN_TMP0(can_periph) = 0x0;
- CAN_TMP1(can_periph) = 0x0;
- CAN_TMP2(can_periph) = 0x0;
- CAN_TMDATA00(can_periph) = 0x0;
- CAN_TMDATA01(can_periph) = 0x0;
- CAN_TMDATA02(can_periph) = 0x0;
- CAN_TMDATA10(can_periph) = 0x0;
- CAN_TMDATA11(can_periph) = 0x0;
- CAN_TMDATA12(can_periph) = 0x0;
-
- return flag;
-}
-
-/*!
- \brief initialize CAN filter
- \param[in] can_filter_parameter_init: struct for CAN filter initialization
- \arg filter_list_high: 0x0000 - 0xFFFF
- \arg filter_list_low: 0x0000 - 0xFFFF
- \arg filter_mask_high: 0x0000 - 0xFFFF
- \arg filter_mask_low: 0x0000 - 0xFFFF
- \arg filter_fifo_number: CAN_FIFO0, CAN_FIFO1
- \arg filter_number: 0 - 27
- \arg filter_mode: CAN_FILTERMODE_MASK, CAN_FILTERMODE_LIST
- \arg filter_bits: CAN_FILTERBITS_32BIT, CAN_FILTERBITS_16BIT
- \arg filter_enable: ENABLE or DISABLE
- \param[out] none
- \retval none
-*/
-void can_filter_init(can_filter_parameter_struct *can_filter_parameter_init) {
- uint32_t val = 0U;
-
- val = ((uint32_t)1) << (can_filter_parameter_init->filter_number);
- /* filter lock disable */
- CAN_FCTL(CAN0) |= CAN_FCTL_FLD;
- /* disable filter */
- CAN_FW(CAN0) &= ~(uint32_t)val;
-
- /* filter 16 bits */
- if (CAN_FILTERBITS_16BIT == can_filter_parameter_init->filter_bits) {
- /* set filter 16 bits */
- CAN_FSCFG(CAN0) &= ~(uint32_t)val;
- /* first 16 bits list and first 16 bits mask or first 16 bits list and second 16 bits list */
- CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number)
- = FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS) | FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS);
- /* second 16 bits list and second 16 bits mask or third 16 bits list and fourth 16 bits list */
- CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number)
- = FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | FDATA_MASK_LOW((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS);
- }
- /* filter 32 bits */
- if (CAN_FILTERBITS_32BIT == can_filter_parameter_init->filter_bits) {
- /* set filter 32 bits */
- CAN_FSCFG(CAN0) |= (uint32_t)val;
- /* 32 bits list or first 32 bits list */
- CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number)
- = FDATA_MASK_HIGH((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS) | FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS);
- /* 32 bits mask or second 32 bits list */
- CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number)
- = FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | FDATA_MASK_LOW((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS);
- }
-
- /* filter mode */
- if (CAN_FILTERMODE_MASK == can_filter_parameter_init->filter_mode) {
- /* mask mode */
- CAN_FMCFG(CAN0) &= ~(uint32_t)val;
- } else {
- /* list mode */
- CAN_FMCFG(CAN0) |= (uint32_t)val;
- }
-
- /* filter FIFO */
- if (CAN_FIFO0 == (can_filter_parameter_init->filter_fifo_number)) {
- /* FIFO0 */
- CAN_FAFIFO(CAN0) &= ~(uint32_t)val;
- } else {
- /* FIFO1 */
- CAN_FAFIFO(CAN0) |= (uint32_t)val;
- }
-
- /* filter working */
- if (ENABLE == can_filter_parameter_init->filter_enable) {
-
- CAN_FW(CAN0) |= (uint32_t)val;
- }
-
- /* filter lock enable */
- CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD;
-}
-
-/*!
- \brief set CAN1 fliter start bank number
- \param[in] start_bank: CAN1 start bank number
- only one parameter can be selected which is shown as below:
- \arg (1..27)
- \param[out] none
- \retval none
-*/
-void can1_filter_start_bank(uint8_t start_bank) {
- /* filter lock disable */
- CAN_FCTL(CAN0) |= CAN_FCTL_FLD;
- /* set CAN1 filter start number */
- CAN_FCTL(CAN0) &= ~(uint32_t)CAN_FCTL_HBC1F;
- CAN_FCTL(CAN0) |= FCTL_HBC1F(start_bank);
- /* filter lock enaable */
- CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD;
-}
-
-/*!
- \brief enable CAN debug freeze
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[out] none
- \retval none
-*/
-void can_debug_freeze_enable(uint32_t can_periph) {
- /* set DFZ bit */
- CAN_CTL(can_periph) |= CAN_CTL_DFZ;
- if (CAN0 == can_periph) {
- dbg_periph_enable(DBG_CAN0_HOLD);
- } else {
- dbg_periph_enable(DBG_CAN1_HOLD);
- }
-}
-
-/*!
- \brief disable CAN debug freeze
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[out] none
- \retval none
-*/
-void can_debug_freeze_disable(uint32_t can_periph) {
- /* set DFZ bit */
- CAN_CTL(can_periph) &= ~CAN_CTL_DFZ;
- if (CAN0 == can_periph) {
- dbg_periph_disable(DBG_CAN0_HOLD);
- } else {
- dbg_periph_disable(DBG_CAN1_HOLD);
- }
-}
-
-/*!
- \brief enable CAN time trigger mode
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[out] none
- \retval none
-*/
-void can_time_trigger_mode_enable(uint32_t can_periph) {
- uint8_t mailbox_number;
-
- /* enable the tcc mode */
- CAN_CTL(can_periph) |= CAN_CTL_TTC;
- /* enable time stamp */
- for (mailbox_number = 0U; mailbox_number < 3U; mailbox_number++) {
- CAN_TMP(can_periph, mailbox_number) |= CAN_TMP_TSEN;
- }
-}
-
-/*!
- \brief disable CAN time trigger mode
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[out] none
- \retval none
-*/
-void can_time_trigger_mode_disable(uint32_t can_periph) {
- uint8_t mailbox_number;
-
- /* disable the TCC mode */
- CAN_CTL(can_periph) &= ~CAN_CTL_TTC;
- /* reset TSEN bits */
- for (mailbox_number = 0U; mailbox_number < 3U; mailbox_number++) {
- CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_TSEN;
- }
-}
-
-/*!
- \brief transmit CAN message
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[in] transmit_message: struct for CAN transmit message
- \arg tx_sfid: 0x00000000 - 0x000007FF
- \arg tx_efid: 0x00000000 - 0x1FFFFFFF
- \arg tx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
- \arg tx_ft: CAN_FT_DATA, CAN_FT_REMOTE
- \arg tx_dlenc: 1 - 7
- \arg tx_data[]: 0x00 - 0xFF
- \param[out] none
- \retval mailbox_number
-*/
-uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct *transmit_message) {
- uint8_t mailbox_number = CAN_MAILBOX0;
-
- /* select one empty mailbox */
- if (CAN_TSTAT_TME0 == (CAN_TSTAT(can_periph) & CAN_TSTAT_TME0)) {
- mailbox_number = CAN_MAILBOX0;
- } else if (CAN_TSTAT_TME1 == (CAN_TSTAT(can_periph) & CAN_TSTAT_TME1)) {
- mailbox_number = CAN_MAILBOX1;
- } else if (CAN_TSTAT_TME2 == (CAN_TSTAT(can_periph) & CAN_TSTAT_TME2)) {
- mailbox_number = CAN_MAILBOX2;
- } else {
- mailbox_number = CAN_NOMAILBOX;
- }
- /* return no mailbox empty */
- if (CAN_NOMAILBOX == mailbox_number) {
- return CAN_NOMAILBOX;
- }
-
- CAN_TMI(can_periph, mailbox_number) &= CAN_TMI_TEN;
- if (CAN_FF_STANDARD == transmit_message->tx_ff) {
- /* set transmit mailbox standard identifier */
- CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_SFID(transmit_message->tx_sfid) | transmit_message->tx_ft);
- } else {
- /* set transmit mailbox extended identifier */
- CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_EFID(transmit_message->tx_efid) | transmit_message->tx_ff | transmit_message->tx_ft);
- }
- /* set the data length */
- CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_DLENC;
- CAN_TMP(can_periph, mailbox_number) |= transmit_message->tx_dlen;
- /* set the data */
- CAN_TMDATA0(can_periph, mailbox_number)
- = TMDATA0_DB3(transmit_message->tx_data[3]) | TMDATA0_DB2(transmit_message->tx_data[2]) | TMDATA0_DB1(transmit_message->tx_data[1]) | TMDATA0_DB0(transmit_message->tx_data[0]);
- CAN_TMDATA1(can_periph, mailbox_number)
- = TMDATA1_DB7(transmit_message->tx_data[7]) | TMDATA1_DB6(transmit_message->tx_data[6]) | TMDATA1_DB5(transmit_message->tx_data[5]) | TMDATA1_DB4(transmit_message->tx_data[4]);
- /* enable transmission */
- CAN_TMI(can_periph, mailbox_number) |= CAN_TMI_TEN;
-
- return mailbox_number;
-}
-
-/*!
- \brief get CAN transmit state
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[in] mailbox_number
- only one parameter can be selected which is shown as below:
- \arg CAN_MAILBOX(x=0,1,2)
- \param[out] none
- \retval can_transmit_state_enum
-*/
-can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox_number) {
- can_transmit_state_enum state = CAN_TRANSMIT_FAILED;
- uint32_t val = 0U;
-
- /* check selected mailbox state */
- switch (mailbox_number) {
- /* mailbox0 */
- case CAN_MAILBOX0:
- val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0);
- break;
- /* mailbox1 */
- case CAN_MAILBOX1:
- val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1);
- break;
- /* mailbox2 */
- case CAN_MAILBOX2:
- val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2);
- break;
- default:
- val = CAN_TRANSMIT_FAILED;
- break;
- }
-
- switch (val) {
- /* transmit pending */
- case (CAN_STATE_PENDING):
- state = CAN_TRANSMIT_PENDING;
- break;
- /* mailbox0 transmit succeeded */
- case (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0):
- state = CAN_TRANSMIT_OK;
- break;
- /* mailbox1 transmit succeeded */
- case (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1):
- state = CAN_TRANSMIT_OK;
- break;
- /* mailbox2 transmit succeeded */
- case (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2):
- state = CAN_TRANSMIT_OK;
- break;
- /* transmit failed */
- default:
- state = CAN_TRANSMIT_FAILED;
- break;
- }
- return state;
-}
-
-/*!
- \brief stop CAN transmission
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[in] mailbox_number
- only one parameter can be selected which is shown as below:
- \arg CAN_MAILBOXx(x=0,1,2)
- \param[out] none
- \retval none
-*/
-void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number) {
- if (CAN_MAILBOX0 == mailbox_number) {
- CAN_TSTAT(can_periph) |= CAN_TSTAT_MST0;
- while (CAN_TSTAT_MST0 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST0)) {}
- } else if (CAN_MAILBOX1 == mailbox_number) {
- CAN_TSTAT(can_periph) |= CAN_TSTAT_MST1;
- while (CAN_TSTAT_MST1 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST1)) {}
- } else if (CAN_MAILBOX2 == mailbox_number) {
- CAN_TSTAT(can_periph) |= CAN_TSTAT_MST2;
- while (CAN_TSTAT_MST2 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST2)) {}
- } else {
- /* illegal parameters */
- }
-}
-
-/*!
- \brief CAN receive message
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[in] fifo_number
- \arg CAN_FIFOx(x=0,1)
- \param[out] receive_message: struct for CAN receive message
- \arg rx_sfid: 0x00000000 - 0x000007FF
- \arg rx_efid: 0x00000000 - 0x1FFFFFFF
- \arg rx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
- \arg rx_ft: CAN_FT_DATA, CAN_FT_REMOTE
- \arg rx_dlenc: 1 - 7
- \arg rx_data[]: 0x00 - 0xFF
- \arg rx_fi: 0 - 27
- \retval none
-*/
-void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct *receive_message) {
- /* get the frame format */
- receive_message->rx_ff = (uint8_t)(CAN_RFIFOMI_FF & CAN_RFIFOMI(can_periph, fifo_number));
- if (CAN_FF_STANDARD == receive_message->rx_ff) {
- /* get standard identifier */
- receive_message->rx_sfid = (uint32_t)(GET_RFIFOMI_SFID(CAN_RFIFOMI(can_periph, fifo_number)));
- } else {
- /* get extended identifier */
- receive_message->rx_efid = (uint32_t)(GET_RFIFOMI_EFID(CAN_RFIFOMI(can_periph, fifo_number)));
- }
-
- /* get frame type */
- receive_message->rx_ft = (uint8_t)(CAN_RFIFOMI_FT & CAN_RFIFOMI(can_periph, fifo_number));
- /* filtering index */
- receive_message->rx_fi = (uint8_t)(GET_RFIFOMP_FI(CAN_RFIFOMP(can_periph, fifo_number)));
- /* get recevie data length */
- receive_message->rx_dlen = (uint8_t)(GET_RFIFOMP_DLENC(CAN_RFIFOMP(can_periph, fifo_number)));
-
- /* receive data */
- receive_message->rx_data[0] = (uint8_t)(GET_RFIFOMDATA0_DB0(CAN_RFIFOMDATA0(can_periph, fifo_number)));
- receive_message->rx_data[1] = (uint8_t)(GET_RFIFOMDATA0_DB1(CAN_RFIFOMDATA0(can_periph, fifo_number)));
- receive_message->rx_data[2] = (uint8_t)(GET_RFIFOMDATA0_DB2(CAN_RFIFOMDATA0(can_periph, fifo_number)));
- receive_message->rx_data[3] = (uint8_t)(GET_RFIFOMDATA0_DB3(CAN_RFIFOMDATA0(can_periph, fifo_number)));
- receive_message->rx_data[4] = (uint8_t)(GET_RFIFOMDATA1_DB4(CAN_RFIFOMDATA1(can_periph, fifo_number)));
- receive_message->rx_data[5] = (uint8_t)(GET_RFIFOMDATA1_DB5(CAN_RFIFOMDATA1(can_periph, fifo_number)));
- receive_message->rx_data[6] = (uint8_t)(GET_RFIFOMDATA1_DB6(CAN_RFIFOMDATA1(can_periph, fifo_number)));
- receive_message->rx_data[7] = (uint8_t)(GET_RFIFOMDATA1_DB7(CAN_RFIFOMDATA1(can_periph, fifo_number)));
-
- /* release FIFO */
- if (CAN_FIFO0 == fifo_number) {
- CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0;
- } else {
- CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1;
- }
-}
-
-/*!
- \brief release FIFO0
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[in] fifo_number
- only one parameter can be selected which is shown as below:
- \arg CAN_FIFOx(x=0,1)
- \param[out] none
- \retval none
-*/
-void can_fifo_release(uint32_t can_periph, uint8_t fifo_number) {
- if (CAN_FIFO0 == fifo_number) {
- CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0;
- } else if (CAN_FIFO1 == fifo_number) {
- CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1;
- } else {
- /* illegal parameters */
- CAN_ERROR_HANDLE("CAN FIFO NUM is invalid \r\n");
- }
-}
-
-/*!
- \brief CAN receive message length
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[in] fifo_number
- only one parameter can be selected which is shown as below:
- \arg CAN_FIFOx(x=0,1)
- \param[out] none
- \retval message length
-*/
-uint8_t can_receive_message_length_get(uint32_t can_periph, uint8_t fifo_number) {
- uint8_t val = 0U;
-
- if (CAN_FIFO0 == fifo_number) {
- /* FIFO0 */
- val = (uint8_t)(CAN_RFIFO0(can_periph) & CAN_RFIF_RFL_MASK);
- } else if (CAN_FIFO1 == fifo_number) {
- /* FIFO1 */
- val = (uint8_t)(CAN_RFIFO1(can_periph) & CAN_RFIF_RFL_MASK);
- } else {
- /* illegal parameters */
- }
- return val;
-}
-
-/*!
- \brief set CAN working mode
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[in] can_working_mode
- only one parameter can be selected which is shown as below:
- \arg CAN_MODE_INITIALIZE
- \arg CAN_MODE_NORMAL
- \arg CAN_MODE_SLEEP
- \param[out] none
- \retval ErrStatus: SUCCESS or ERROR
-*/
-ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode) {
- ErrStatus flag = ERROR;
- /* timeout for IWS or also for SLPWS bits */
- uint32_t timeout = CAN_TIMEOUT;
-
- if (CAN_MODE_INITIALIZE == working_mode) {
- /* disable sleep mode */
- CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_SLPWMOD);
- /* set initialize mode */
- CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_IWMOD;
- /* wait the acknowledge */
- while ((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)) {
- timeout--;
- }
- if (CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) {
- flag = ERROR;
- } else {
- flag = SUCCESS;
- }
- } else if (CAN_MODE_NORMAL == working_mode) {
- /* enter normal mode */
- CAN_CTL(can_periph) &= ~(uint32_t)(CAN_CTL_SLPWMOD | CAN_CTL_IWMOD);
- /* wait the acknowledge */
- while ((0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))) && (0U != timeout)) {
- timeout--;
- }
- if (0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))) {
- flag = ERROR;
- } else {
- flag = SUCCESS;
- }
- } else if (CAN_MODE_SLEEP == working_mode) {
- /* disable initialize mode */
- CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_IWMOD);
- /* set sleep mode */
- CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_SLPWMOD;
- /* wait the acknowledge */
- while ((CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0U != timeout)) {
- timeout--;
- }
- if (CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) {
- flag = ERROR;
- } else {
- flag = SUCCESS;
- }
- } else {
- flag = ERROR;
- }
- return flag;
-}
-
-/*!
- \brief wake up CAN
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[out] none
- \retval ErrStatus: SUCCESS or ERROR
-*/
-ErrStatus can_wakeup(uint32_t can_periph) {
- ErrStatus flag = ERROR;
- uint32_t timeout = CAN_TIMEOUT;
-
- /* wakeup */
- CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD;
-
- while ((0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0x00U != timeout)) {
- timeout--;
- }
- /* check state */
- if (0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) {
- flag = ERROR;
- } else {
- flag = SUCCESS;
- }
- return flag;
-}
-
-/*!
- \brief get CAN error type
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[out] none
- \retval can_error_enum
- \arg CAN_ERROR_NONE: no error
- \arg CAN_ERROR_FILL: fill error
- \arg CAN_ERROR_FORMATE: format error
- \arg CAN_ERROR_ACK: ACK error
- \arg CAN_ERROR_BITRECESSIVE: bit recessive
- \arg CAN_ERROR_BITDOMINANTER: bit dominant error
- \arg CAN_ERROR_CRC: CRC error
- \arg CAN_ERROR_SOFTWARECFG: software configure
-*/
-can_error_enum can_error_get(uint32_t can_periph) {
- can_error_enum error;
- error = CAN_ERROR_NONE;
-
- /* get error type */
- error = (can_error_enum)(GET_ERR_ERRN(CAN_ERR(can_periph)));
- return error;
-}
-
-/*!
- \brief get CAN receive error number
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[out] none
- \retval error number
-*/
-uint8_t can_receive_error_number_get(uint32_t can_periph) {
- uint8_t val;
-
- /* get error count */
- val = (uint8_t)(GET_ERR_RECNT(CAN_ERR(can_periph)));
- return val;
-}
-
-/*!
- \brief get CAN transmit error number
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[out] none
- \retval error number
-*/
-uint8_t can_transmit_error_number_get(uint32_t can_periph) {
- uint8_t val;
-
- val = (uint8_t)(GET_ERR_TECNT(CAN_ERR(can_periph)));
- return val;
-}
-
-/*!
- \brief enable CAN interrupt
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[in] interrupt
- one or more parameters can be selected which are shown as below:
- \arg CAN_INT_TME: transmit mailbox empty interrupt enable
- \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable
- \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable
- \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable
- \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable
- \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable
- \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable
- \arg CAN_INT_WERR: warning error interrupt enable
- \arg CAN_INT_PERR: passive error interrupt enable
- \arg CAN_INT_BO: bus-off interrupt enable
- \arg CAN_INT_ERRN: error number interrupt enable
- \arg CAN_INT_ERR: error interrupt enable
- \arg CAN_INT_WU: wakeup interrupt enable
- \arg CAN_INT_SLPW: sleep working interrupt enable
- \param[out] none
- \retval none
-*/
-void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt) { CAN_INTEN(can_periph) |= interrupt; }
-
-/*!
- \brief disable CAN interrupt
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[in] interrupt
- one or more parameters can be selected which are shown as below:
- \arg CAN_INT_TME: transmit mailbox empty interrupt enable
- \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable
- \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable
- \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable
- \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable
- \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable
- \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable
- \arg CAN_INT_WERR: warning error interrupt enable
- \arg CAN_INT_PERR: passive error interrupt enable
- \arg CAN_INT_BO: bus-off interrupt enable
- \arg CAN_INT_ERRN: error number interrupt enable
- \arg CAN_INT_ERR: error interrupt enable
- \arg CAN_INT_WU: wakeup interrupt enable
- \arg CAN_INT_SLPW: sleep working interrupt enable
- \param[out] none
- \retval none
-*/
-void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt) { CAN_INTEN(can_periph) &= ~interrupt; }
-
-/*!
- \brief get CAN flag state
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[in] flag: CAN flags, refer to can_flag_enum
- only one parameter can be selected which is shown as below:
- \arg CAN_FLAG_MTE2: mailbox 2 transmit error
- \arg CAN_FLAG_MTE1: mailbox 1 transmit error
- \arg CAN_FLAG_MTE0: mailbox 0 transmit error
- \arg CAN_FLAG_MTF2: mailbox 2 transmit finished
- \arg CAN_FLAG_MTF1: mailbox 1 transmit finished
- \arg CAN_FLAG_MTF0: mailbox 0 transmit finished
- \arg CAN_FLAG_RFO0: receive FIFO0 overfull
- \arg CAN_FLAG_RFF0: receive FIFO0 full
- \arg CAN_FLAG_RFO1: receive FIFO1 overfull
- \arg CAN_FLAG_RFF1: receive FIFO1 full
- \arg CAN_FLAG_BOERR: bus-off error
- \arg CAN_FLAG_PERR: passive error
- \arg CAN_FLAG_WERR: warning error
- \param[out] none
- \retval FlagStatus: SET or RESET
-*/
-FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag) {
- /* get flag and interrupt enable state */
- if (RESET != (CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag)))) {
- return SET;
- } else {
- return RESET;
- }
-}
-
-/*!
- \brief clear CAN flag state
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[in] flag: CAN flags, refer to can_flag_enum
- only one parameter can be selected which is shown as below:
- \arg CAN_FLAG_MTE2: mailbox 2 transmit error
- \arg CAN_FLAG_MTE1: mailbox 1 transmit error
- \arg CAN_FLAG_MTE0: mailbox 0 transmit error
- \arg CAN_FLAG_MTF2: mailbox 2 transmit finished
- \arg CAN_FLAG_MTF1: mailbox 1 transmit finished
- \arg CAN_FLAG_MTF0: mailbox 0 transmit finished
- \arg CAN_FLAG_RFO0: receive FIFO0 overfull
- \arg CAN_FLAG_RFF0: receive FIFO0 full
- \arg CAN_FLAG_RFO1: receive FIFO1 overfull
- \arg CAN_FLAG_RFF1: receive FIFO1 full
- \arg CAN_FLAG_BOERR: bus-off error
- \arg CAN_FLAG_PERR: passive error
- \arg CAN_FLAG_WERR: warning error
- \param[out] none
- \retval none
-*/
-void can_flag_clear(uint32_t can_periph, can_flag_enum flag) { CAN_REG_VAL(can_periph, flag) = BIT(CAN_BIT_POS(flag)); }
-
-/*!
- \brief get CAN interrupt flag state
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[in] flag: CAN interrupt flags, refer to can_interrupt_flag_enum
- only one parameter can be selected which is shown as below:
- \arg CAN_INT_FLAG_SLPIF: status change interrupt flag of sleep working mode entering
- \arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode
- \arg CAN_INT_FLAG_ERRIF: error interrupt flag
- \arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag
- \arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag
- \arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag
- \arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag
- \arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag
- \arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag
- \arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag
- \param[out] none
- \retval FlagStatus: SET or RESET
-*/
-FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag) {
- uint32_t ret1 = RESET;
- uint32_t ret2 = RESET;
-
- /* get the staus of interrupt flag */
- ret1 = CAN_REG_VALS(can_periph, flag) & BIT(CAN_BIT_POS0(flag));
- /* get the staus of interrupt enale bit */
- ret2 = CAN_INTEN(can_periph) & BIT(CAN_BIT_POS1(flag));
- if (ret1 && ret2) {
- return SET;
- } else {
- return RESET;
- }
-}
-
-/*!
- \brief clear CAN interrupt flag state
- \param[in] can_periph
- \arg CANx(x=0,1)
- \param[in] flag: CAN interrupt flags, refer to can_interrupt_flag_enum
- only one parameter can be selected which is shown as below:
- \arg CAN_INT_FLAG_SLPIF: status change interrupt flag of sleep working mode entering
- \arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode
- \arg CAN_INT_FLAG_ERRIF: error interrupt flag
- \arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag
- \arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag
- \arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag
- \arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag
- \arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag
- \arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag
- \arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag
- \arg CAN_FLAG_BOERR: bus-off error
- \arg CAN_FLAG_PERR: passive error
- \arg CAN_FLAG_WERR: warning error
- \param[out] none
- \retval none
-*/
-void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum flag) { CAN_REG_VALS(can_periph, flag) = BIT(CAN_BIT_POS0(flag)); }
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_crc.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_crc.c index 523088ce..7c2272f1 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_crc.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_crc.c @@ -1,12 +1,13 @@ /*!
- \file gd32vf103_crc.c
- \brief CRC driver
+ \file gd32vf103_crc.c
+ \brief CRC driver
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -33,6 +34,7 @@ OF SUCH DAMAGE. */
#include "gd32vf103_crc.h"
+#include "gd32vf103_rcu.h"
#define CRC_DATA_RESET_VALUE ((uint32_t)0xFFFFFFFFU)
#define CRC_FDATA_RESET_VALUE ((uint32_t)0x00000000U)
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_dac.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_dac.c index a3da3d74..b412309c 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_dac.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_dac.c @@ -2,11 +2,12 @@ \file gd32vf103_dac.c
\brief DAC driver
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -33,6 +34,7 @@ OF SUCH DAMAGE. */
#include "gd32vf103_dac.h"
+#include "gd32vf103_rcu.h"
/* DAC register bit offset */
#define DAC1_REG_OFFSET ((uint32_t)16U)
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_dbg.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_dbg.c index 1ad7fdba..7778a2d4 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_dbg.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_dbg.c @@ -1,12 +1,13 @@ /*!
- \file gd32vf103_dbg.c
- \brief DBG driver
+ \file gd32vf103_dbg.c
+ \brief DBG driver
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -33,6 +34,7 @@ OF SUCH DAMAGE. */
#include "gd32vf103_dbg.h"
+#include "gd32vf103_rcu.h"
/*!
\brief read DBG_ID code register
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_dma.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_dma.c index b1d29a64..e129f7cc 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_dma.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_dma.c @@ -2,11 +2,13 @@ \file gd32vf103_dma.c
\brief DMA driver
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2019-10-30, V1.0.1, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -33,6 +35,7 @@ OF SUCH DAMAGE. */
#include "gd32vf103_dma.h"
+#include "gd32vf103_rcu.h"
#define DMA_WRONG_HANDLE \
while (1) {}
@@ -62,7 +65,7 @@ void dma_deinit(uint32_t dma_periph, dma_channel_enum channelx) { DMA_CHCNT(dma_periph, channelx) = DMA_CHCNT_RESET_VALUE;
DMA_CHPADDR(dma_periph, channelx) = DMA_CHPADDR_RESET_VALUE;
DMA_CHMADDR(dma_periph, channelx) = DMA_CHMADDR_RESET_VALUE;
- DMA_INTC(dma_periph) |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE, channelx);
+ DMA_INTC(dma_periph) |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE, (uint32_t)channelx);
}
/*!
@@ -508,7 +511,7 @@ void dma_periph_increase_disable(uint32_t dma_periph, dma_channel_enum channelx) \param[out] none
\retval none
*/
-void dma_transfer_direction_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t direction) {
+void dma_transfer_direction_config(uint32_t dma_periph, dma_channel_enum channelx, uint8_t direction) {
if (ERROR == dma_periph_and_channel_check(dma_periph, channelx)) {
DMA_WRONG_HANDLE
}
@@ -539,7 +542,7 @@ void dma_transfer_direction_config(uint32_t dma_periph, dma_channel_enum channel FlagStatus dma_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag) {
FlagStatus reval;
- if (RESET != (DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx))) {
+ if (DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, (uint32_t)channelx)) {
reval = SET;
} else {
reval = RESET;
@@ -564,7 +567,7 @@ FlagStatus dma_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t \param[out] none
\retval none
*/
-void dma_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag) { DMA_INTC(dma_periph) |= DMA_FLAG_ADD(flag, channelx); }
+void dma_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag) { DMA_INTC(dma_periph) |= DMA_FLAG_ADD(flag, (uint32_t)channelx); }
/*!
\brief check DMA flag and interrupt enable bit is set or not
@@ -587,18 +590,18 @@ FlagStatus dma_interrupt_flag_get(uint32_t dma_periph, dma_channel_enum channelx switch (flag) {
case DMA_INT_FLAG_FTF:
/* check whether the full transfer finish interrupt flag is set and enabled */
- interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx);
- interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_FTFIE;
+ interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, (uint32_t)channelx);
+ interrupt_enable = DMA_CHCTL(dma_periph, (uint32_t)channelx) & DMA_CHXCTL_FTFIE;
break;
case DMA_INT_FLAG_HTF:
/* check whether the half transfer finish interrupt flag is set and enabled */
- interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx);
- interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_HTFIE;
+ interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, (uint32_t)channelx);
+ interrupt_enable = DMA_CHCTL(dma_periph, (uint32_t)channelx) & DMA_CHXCTL_HTFIE;
break;
case DMA_INT_FLAG_ERR:
/* check whether the error interrupt flag is set and enabled */
- interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx);
- interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_ERRIE;
+ interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, (uint32_t)channelx);
+ interrupt_enable = DMA_CHCTL(dma_periph, (uint32_t)channelx) & DMA_CHXCTL_ERRIE;
break;
default:
DMA_WRONG_HANDLE
@@ -628,7 +631,7 @@ FlagStatus dma_interrupt_flag_get(uint32_t dma_periph, dma_channel_enum channelx \param[out] none
\retval none
*/
-void dma_interrupt_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag) { DMA_INTC(dma_periph) |= DMA_FLAG_ADD(flag, channelx); }
+void dma_interrupt_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag) { DMA_INTC(dma_periph) |= DMA_FLAG_ADD(flag, (uint32_t)channelx); }
/*!
\brief enable DMA interrupt
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_eclic.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_eclic.c index e4fcf5a5..b9729113 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_eclic.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_eclic.c @@ -1,12 +1,13 @@ /*!
- \file gd32vf103_eclic.c
- \brief ECLIC(Enhancement Core-Local Interrupt Controller) driver
+ \file gd32vf103_eclic.c
+ \brief ECLIC(Enhancement Core-Local Interrupt Controller) driver
- \version 2019-06-05, V1.0.1, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -33,9 +34,34 @@ OF SUCH DAMAGE. */
#include "gd32vf103_eclic.h"
+#include "gd32vf103_rcu.h"
+#include "n200_func.h"
#include "riscv_encoding.h"
-#define REG_DBGMCU2 ((uint32_t)0xE0042008)
-#define REG_DBGMCU2EN ((uint32_t)0xE004200C)
+
+#define REG_DBGMCU2 ((uint32_t)0xE0042008U)
+#define REG_DBGMCU2EN ((uint32_t)0xE004200CU)
+
+/*!
+ \brief enable the global interrupt
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void eclic_global_interrupt_enable(void) {
+ /* set machine interrupt enable bit */
+ set_csr(mstatus, MSTATUS_MIE);
+}
+
+/*!
+ \brief disable the global interrupt
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void eclic_global_interrupt_disable(void) {
+ /* clear machine interrupt enable bit */
+ clear_csr(mstatus, MSTATUS_MIE);
+}
/*!
\brief set the priority group
@@ -48,7 +74,7 @@ OF SUCH DAMAGE. \param[out] none
\retval none
*/
-void eclic_priority_group_set(uint32_t prigroup) { ECLIC_SetCfgNlbits(prigroup); }
+void eclic_priority_group_set(uint8_t prigroup) { eclic_set_nlbits(prigroup); }
/*!
\brief enable the interrupt request
@@ -59,9 +85,9 @@ void eclic_priority_group_set(uint32_t prigroup) { ECLIC_SetCfgNlbits(prigroup); \retval none
*/
void eclic_irq_enable(uint32_t source, uint8_t level, uint8_t priority) {
- ECLIC_EnableIRQ(source);
- ECLIC_SetLevelIRQ(source, level);
- ECLIC_SetPriorityIRQ(source, priority);
+ eclic_enable_interrupt(source);
+ eclic_set_irq_lvl_abs(source, level);
+ eclic_set_irq_priority(source, priority);
}
/*!
@@ -70,7 +96,7 @@ void eclic_irq_enable(uint32_t source, uint8_t level, uint8_t priority) { \param[out] none
\retval none
*/
-void eclic_irq_disable(uint32_t source) { ECLIC_DisableIRQ(source); }
+void eclic_irq_disable(uint32_t source) { eclic_disable_interrupt(source); }
/*!
\brief reset system
@@ -79,6 +105,14 @@ void eclic_irq_disable(uint32_t source) { ECLIC_DisableIRQ(source); } \retval none
*/
void eclic_system_reset(void) {
- REG32(REG_DBGMCU2EN) = 0x4b5a6978;
- REG32(REG_DBGMCU2) = 0x1;
+ REG32(REG_DBGMCU2EN) = (uint32_t)0x4b5a6978U;
+ REG32(REG_DBGMCU2) = (uint32_t)0x1U;
}
+
+/*!
+ \brief send event(SEV)
+ \param[in] none
+ \param[out] none
+ \retval none
+*/
+void eclic_send_event(void) { set_csr(0x812U, 0x1U); }
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_exmc.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_exmc.c index ca3fec6e..d1485881 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_exmc.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_exmc.c @@ -2,11 +2,12 @@ \file gd32vf103_exmc.c
\brief EXMC driver
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -33,6 +34,7 @@ OF SUCH DAMAGE. */
#include "gd32vf103_exmc.h"
+#include "gd32vf103_rcu.h"
/* EXMC bank0 register reset value */
#define BANK0_SNCTL0_REGION_RESET ((uint32_t)0x000030DAU)
@@ -112,9 +114,9 @@ void exmc_norsram_init(exmc_norsram_parameter_struct *exmc_norsram_init_struct) /* clear relative bits */
snctl &= ((uint32_t) ~(EXMC_SNCTL_NREN | EXMC_SNCTL_NRTP | EXMC_SNCTL_NRW | EXMC_SNCTL_NRWTPOL | EXMC_SNCTL_WREN | EXMC_SNCTL_NRWTEN | EXMC_SNCTL_ASYNCWAIT | EXMC_SNCTL_NRMUX));
- snctl |= (uint32_t)(exmc_norsram_init_struct->address_data_mux << SNCTL_NRMUX_OFFSET) | exmc_norsram_init_struct->memory_type | exmc_norsram_init_struct->databus_width
- | exmc_norsram_init_struct->nwait_polarity | (exmc_norsram_init_struct->memory_write << SNCTL_WREN_OFFSET) | (exmc_norsram_init_struct->nwait_signal << SNCTL_NRWTEN_OFFSET)
- | (exmc_norsram_init_struct->asyn_wait << SNCTL_ASYNCWAIT_OFFSET);
+ snctl |= (uint32_t)((uint32_t)exmc_norsram_init_struct->address_data_mux << SNCTL_NRMUX_OFFSET) | exmc_norsram_init_struct->memory_type | exmc_norsram_init_struct->databus_width
+ | exmc_norsram_init_struct->nwait_polarity | ((uint32_t)exmc_norsram_init_struct->memory_write << SNCTL_WREN_OFFSET)
+ | ((uint32_t)exmc_norsram_init_struct->nwait_signal << SNCTL_NRWTEN_OFFSET) | ((uint32_t)exmc_norsram_init_struct->asyn_wait << SNCTL_ASYNCWAIT_OFFSET);
sntcfg = (uint32_t)((exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime - 1U) & EXMC_SNTCFG_ASET)
| (((exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime - 1U) << SNTCFG_AHLD_OFFSET) & EXMC_SNTCFG_AHLD)
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_exti.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_exti.c index e824ea1b..c0527ec6 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_exti.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_exti.c @@ -2,11 +2,12 @@ \file gd32vf103_exti.c
\brief EXTI driver
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -33,6 +34,7 @@ OF SUCH DAMAGE. */
#include "gd32vf103_exti.h"
+#include "gd32vf103_rcu.h"
#define EXTI_REG_RESET_VALUE ((uint32_t)0x00000000U)
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_fmc.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_fmc.c index 055bb427..4811ec87 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_fmc.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_fmc.c @@ -1,12 +1,15 @@ /*!
- \file gd32vf103_fmc.c
- \brief FMC driver
+ \file gd32vf103_fmc.c
+ \brief FMC driver
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2019-09-18, V1.0.1, firmware for GD32VF103
+ \version 2020-02-20, V1.0.2, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -33,9 +36,10 @@ OF SUCH DAMAGE. */
#include "gd32vf103_fmc.h"
+#include "gd32vf103_rcu.h"
/*!
- \brief set the wait state counter value
+ \brief set the FMC wait state counter
\param[in] wscnt��wait state counter value
\arg WS_WSCNT_0: FMC 0 wait state
\arg WS_WSCNT_1: FMC 1 wait state
@@ -59,10 +63,10 @@ void fmc_wscnt_set(uint32_t wscnt) { \retval none
*/
void fmc_unlock(void) {
- if ((RESET != (FMC_CTL0 & FMC_CTL0_LK))) {
+ if ((RESET != (FMC_CTL & FMC_CTL_LK))) {
/* write the FMC unlock key */
- FMC_KEY0 = UNLOCK_KEY0;
- FMC_KEY0 = UNLOCK_KEY1;
+ FMC_KEY = UNLOCK_KEY0;
+ FMC_KEY = UNLOCK_KEY1;
}
}
@@ -74,7 +78,7 @@ void fmc_unlock(void) { */
void fmc_lock(void) {
/* set the LK bit */
- FMC_CTL0 |= FMC_CTL0_LK;
+ FMC_CTL |= FMC_CTL_LK;
}
/*!
@@ -88,13 +92,13 @@ fmc_state_enum fmc_page_erase(uint32_t page_address) { fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
/* if the last operation is completed, start page erase */
if (FMC_READY == fmc_state) {
- FMC_CTL0 |= FMC_CTL0_PER;
- FMC_ADDR0 = page_address;
- FMC_CTL0 |= FMC_CTL0_START;
+ FMC_CTL |= FMC_CTL_PER;
+ FMC_ADDR = page_address;
+ FMC_CTL |= FMC_CTL_START;
/* wait for the FMC ready */
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
/* reset the PER bit */
- FMC_CTL0 &= ~FMC_CTL0_PER;
+ FMC_CTL &= ~FMC_CTL_PER;
}
/* return the FMC state */
return fmc_state;
@@ -112,12 +116,12 @@ fmc_state_enum fmc_mass_erase(void) { if (FMC_READY == fmc_state) {
/* start whole chip erase */
- FMC_CTL0 |= FMC_CTL0_MER;
- FMC_CTL0 |= FMC_CTL0_START;
+ FMC_CTL |= FMC_CTL_MER;
+ FMC_CTL |= FMC_CTL_START;
/* wait for the FMC ready */
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
/* reset the MER bit */
- FMC_CTL0 &= ~FMC_CTL0_MER;
+ FMC_CTL &= ~FMC_CTL_MER;
}
/* return the FMC state */
return fmc_state;
@@ -136,12 +140,12 @@ fmc_state_enum fmc_word_program(uint32_t address, uint32_t data) { if (FMC_READY == fmc_state) {
/* set the PG bit to start program */
- FMC_CTL0 |= FMC_CTL0_PG;
+ FMC_CTL |= FMC_CTL_PG;
REG32(address) = data;
/* wait for the FMC ready */
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
/* reset the PG bit */
- FMC_CTL0 &= ~FMC_CTL0_PG;
+ FMC_CTL &= ~FMC_CTL_PG;
}
/* return the FMC state */
return fmc_state;
@@ -159,12 +163,12 @@ fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data) { if (FMC_READY == fmc_state) {
/* set the PG bit to start program */
- FMC_CTL0 |= FMC_CTL0_PG;
+ FMC_CTL |= FMC_CTL_PG;
REG16(address) = data;
/* wait for the FMC ready */
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
/* reset the PG bit */
- FMC_CTL0 &= ~FMC_CTL0_PG;
+ FMC_CTL &= ~FMC_CTL_PG;
}
/* return the FMC state */
return fmc_state;
@@ -177,14 +181,14 @@ fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data) { \retval none
*/
void ob_unlock(void) {
- if (RESET == (FMC_CTL0 & FMC_CTL0_OBWEN)) {
+ if (RESET == (FMC_CTL & FMC_CTL_OBWEN)) {
/* write the FMC key */
FMC_OBKEY = UNLOCK_KEY0;
FMC_OBKEY = UNLOCK_KEY1;
}
/* wait until OBWEN bit is set by hardware */
- while (RESET == (FMC_CTL0 & FMC_CTL0_OBWEN)) {}
+ while (RESET == (FMC_CTL & FMC_CTL_OBWEN)) {}
}
/*!
@@ -195,12 +199,12 @@ void ob_unlock(void) { */
void ob_lock(void) {
/* reset the OBWEN bit */
- FMC_CTL0 &= ~FMC_CTL0_OBWEN;
+ FMC_CTL &= ~FMC_CTL_OBWEN;
}
/*!
\brief erase the FMC option byte
- unlock the FMC_CTL0 and option byte before calling this function
+ unlock the FMC_CTL and option byte before calling this function
\param[in] none
\param[out] none
\retval state of FMC, refer to fmc_state_enum
@@ -218,29 +222,29 @@ fmc_state_enum ob_erase(void) { if (FMC_READY == fmc_state) {
/* start erase the option byte */
- FMC_CTL0 |= FMC_CTL0_OBER;
- FMC_CTL0 |= FMC_CTL0_START;
+ FMC_CTL |= FMC_CTL_OBER;
+ FMC_CTL |= FMC_CTL_START;
/* wait for the FMC ready */
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
if (FMC_READY == fmc_state) {
/* reset the OBER bit */
- FMC_CTL0 &= ~FMC_CTL0_OBER;
+ FMC_CTL &= ~FMC_CTL_OBER;
/* set the OBPG bit */
- FMC_CTL0 |= FMC_CTL0_OBPG;
+ FMC_CTL |= FMC_CTL_OBPG;
/* no security protection */
OB_SPC = (uint16_t)temp_spc;
/* wait for the FMC ready */
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
if (FMC_TOERR != fmc_state) {
/* reset the OBPG bit */
- FMC_CTL0 &= ~FMC_CTL0_OBPG;
+ FMC_CTL &= ~FMC_CTL_OBPG;
}
} else {
if (FMC_TOERR != fmc_state) {
/* reset the OBPG bit */
- FMC_CTL0 &= ~FMC_CTL0_OBPG;
+ FMC_CTL &= ~FMC_CTL_OBPG;
}
}
}
@@ -254,7 +258,7 @@ fmc_state_enum ob_erase(void) { you want to protect the corresponding pages. meanwhile, sector
macro could used to set specific sector write protected.
one or more parameters can be selected which are shown as below:
- \arg OB_WPx(x = 0..31): write protect specify sector
+ \arg OB_WP_x(x = 0..31): write protect specify sector
\arg OB_WP_ALL: write protect all sector
\param[out] none
\retval state of FMC, refer to fmc_state_enum
@@ -273,7 +277,7 @@ fmc_state_enum ob_write_protection_enable(uint32_t ob_wp) { if (FMC_READY == fmc_state) {
/* set the OBPG bit*/
- FMC_CTL0 |= FMC_CTL0_OBPG;
+ FMC_CTL |= FMC_CTL_OBPG;
if (0xFFU != temp_wp0) {
OB_WP0 = temp_wp0;
@@ -301,7 +305,7 @@ fmc_state_enum ob_write_protection_enable(uint32_t ob_wp) { }
if (FMC_TOERR != fmc_state) {
/* reset the OBPG bit */
- FMC_CTL0 &= ~FMC_CTL0_OBPG;
+ FMC_CTL &= ~FMC_CTL_OBPG;
}
}
/* return the FMC state */
@@ -321,18 +325,18 @@ fmc_state_enum ob_security_protection_config(uint8_t ob_spc) { fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
if (FMC_READY == fmc_state) {
- FMC_CTL0 |= FMC_CTL0_OBER;
- FMC_CTL0 |= FMC_CTL0_START;
+ FMC_CTL |= FMC_CTL_OBER;
+ FMC_CTL |= FMC_CTL_START;
/* wait for the FMC ready */
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
if (FMC_READY == fmc_state) {
/* reset the OBER bit */
- FMC_CTL0 &= ~FMC_CTL0_OBER;
+ FMC_CTL &= ~FMC_CTL_OBER;
/* start the option byte program */
- FMC_CTL0 |= FMC_CTL0_OBPG;
+ FMC_CTL |= FMC_CTL_OBPG;
OB_SPC = (uint16_t)ob_spc;
@@ -341,12 +345,12 @@ fmc_state_enum ob_security_protection_config(uint8_t ob_spc) { if (FMC_TOERR != fmc_state) {
/* reset the OBPG bit */
- FMC_CTL0 &= ~FMC_CTL0_OBPG;
+ FMC_CTL &= ~FMC_CTL_OBPG;
}
} else {
if (FMC_TOERR != fmc_state) {
/* reset the OBER bit */
- FMC_CTL0 &= ~FMC_CTL0_OBER;
+ FMC_CTL &= ~FMC_CTL_OBER;
}
}
}
@@ -358,12 +362,12 @@ fmc_state_enum ob_security_protection_config(uint8_t ob_spc) { \brief program the FMC user option byte
\param[in] ob_fwdgt: option byte watchdog value
\arg OB_FWDGT_SW: software free watchdog
- \arg OB_FWDGT_HW: hardware free watchdog
+ \arg OB_FWDGT_HW: hardware free watchdog
\param[in] ob_deepsleep: option byte deepsleep reset value
\arg OB_DEEPSLEEP_NRST: no reset when entering deepsleep mode
\arg OB_DEEPSLEEP_RST: generate a reset instead of entering deepsleep mode
\param[in] ob_stdby:option byte standby reset value
- \arg OB_STDBY_NRST: no reset when entering standby mode
+ \arg OB_STDBY_NRST: no reset when entering standby mode
\arg OB_STDBY_RST: generate a reset instead of entering standby mode
\param[in] ob_boot: specifies the option byte boot bank value
\arg OB_BOOT_B0: boot from bank0
@@ -379,7 +383,7 @@ fmc_state_enum ob_user_write(uint8_t ob_fwdgt, uint8_t ob_deepsleep, uint8_t ob_ if (FMC_READY == fmc_state) {
/* set the OBPG bit*/
- FMC_CTL0 |= FMC_CTL0_OBPG;
+ FMC_CTL |= FMC_CTL_OBPG;
temp = ((uint8_t)((uint8_t)((uint8_t)(ob_boot | ob_fwdgt) | ob_deepsleep) | ob_stdby) | OB_USER_MASK);
OB_USER = (uint16_t)temp;
@@ -389,7 +393,7 @@ fmc_state_enum ob_user_write(uint8_t ob_fwdgt, uint8_t ob_deepsleep, uint8_t ob_ if (FMC_TOERR != fmc_state) {
/* reset the OBPG bit */
- FMC_CTL0 &= ~FMC_CTL0_OBPG;
+ FMC_CTL &= ~FMC_CTL_OBPG;
}
}
/* return the FMC state */
@@ -397,7 +401,7 @@ fmc_state_enum ob_user_write(uint8_t ob_fwdgt, uint8_t ob_deepsleep, uint8_t ob_ }
/*!
- \brief program option bytes data
+ \brief program the FMC data option byte
\param[in] address: the option bytes address to be programmed
\param[in] data: the byte to be programmed
\param[out] none
@@ -408,7 +412,7 @@ fmc_state_enum ob_data_program(uint32_t address, uint8_t data) { if (FMC_READY == fmc_state) {
/* set the OBPG bit */
- FMC_CTL0 |= FMC_CTL0_OBPG;
+ FMC_CTL |= FMC_CTL_OBPG;
REG16(address) = data;
/* wait for the FMC ready */
@@ -416,7 +420,7 @@ fmc_state_enum ob_data_program(uint32_t address, uint8_t data) { if (FMC_TOERR != fmc_state) {
/* reset the OBPG bit */
- FMC_CTL0 &= ~FMC_CTL0_OBPG;
+ FMC_CTL &= ~FMC_CTL_OBPG;
}
}
/* return the FMC state */
@@ -424,7 +428,7 @@ fmc_state_enum ob_data_program(uint32_t address, uint8_t data) { }
/*!
- \brief get the FMC user option byte
+ \brief get OB_USER in register FMC_OBSTAT
\param[in] none
\param[out] none
\retval the FMC user option byte values
@@ -454,7 +458,7 @@ uint32_t ob_write_protection_get(void) { }
/*!
- \brief get the FMC option byte security protection
+ \brief get FMC option byte security protection state
\param[in] none
\param[out] none
\retval FlagStatus: SET or RESET
@@ -479,7 +483,7 @@ FlagStatus ob_spc_get(void) { \param[out] none
\retval none
*/
-void fmc_interrupt_enable(uint32_t interrupt) { FMC_REG_VAL(interrupt) |= BIT(FMC_BIT_POS(interrupt)); }
+void fmc_interrupt_enable(fmc_int_enum interrupt) { FMC_CTL |= (uint32_t)interrupt; }
/*!
\brief disable FMC interrupt
@@ -490,79 +494,78 @@ void fmc_interrupt_enable(uint32_t interrupt) { FMC_REG_VAL(interrupt) |= BIT(FM \param[out] none
\retval none
*/
-void fmc_interrupt_disable(uint32_t interrupt) { FMC_REG_VAL(interrupt) &= ~BIT(FMC_BIT_POS(interrupt)); }
+void fmc_interrupt_disable(fmc_int_enum interrupt) { FMC_CTL &= ~(uint32_t)interrupt; }
/*!
\brief check flag is set or not
\param[in] flag: check FMC flag
only one parameter can be selected which is shown as below:
- \arg FMC_FLAG_BUSY: FMC busy flag bit
- \arg FMC_FLAG_PGERR: FMC operation error flag bit
- \arg FMC_FLAG_WPERR: FMC erase/program protection error flag bit
- \arg FMC_FLAG_END: FMC end of operation flag bit
- \arg FMC_FLAG_OBERR: FMC option bytes read error flag bit
+ \arg FMC_FLAG_BUSY: FMC busy flag
+ \arg FMC_FLAG_PGERR: FMC operation error flag
+ \arg FMC_FLAG_WPERR: FMC erase/program protection error flag
+ \arg FMC_FLAG_END: FMC end of operation flag
\param[out] none
\retval FlagStatus: SET or RESET
*/
-FlagStatus fmc_flag_get(uint32_t flag) {
- if (RESET != (FMC_REG_VAL(flag) & BIT(FMC_BIT_POS(flag)))) {
- return SET;
- } else {
- return RESET;
+FlagStatus fmc_flag_get(fmc_flag_enum flag) {
+ FlagStatus status = RESET;
+
+ if (FMC_STAT & flag) {
+ status = SET;
}
+ /* return the state of corresponding FMC flag */
+ return status;
}
/*!
\brief clear the FMC flag
\param[in] flag: clear FMC flag
only one parameter can be selected which is shown as below:
- \arg FMC_FLAG_PGERR: FMC operation error flag bit
- \arg FMC_FLAG_WPERR: FMC erase/program protection error flag bit
- \arg FMC_FLAG_END: FMC end of operation flag bit
+ \arg FMC_FLAG_PGERR: FMC operation error flag
+ \arg FMC_FLAG_WPERR: FMC erase/program protection error flag
+ \arg FMC_FLAG_END: FMC end of operation flag
\param[out] none
\retval none
*/
-void fmc_flag_clear(uint32_t flag) { FMC_REG_VAL(flag) = (!FMC_REG_VAL(flag)) | BIT(FMC_BIT_POS(flag)); }
+void fmc_flag_clear(fmc_flag_enum flag) {
+ /* clear the flags */
+ FMC_STAT = flag;
+}
/*!
\brief get FMC interrupt flag state
\param[in] flag: FMC interrupt flags, refer to fmc_interrupt_flag_enum
only one parameter can be selected which is shown as below:
- \arg FMC_INT_FLAG_PGERR: FMC operation error interrupt flag bit
- \arg FMC_INT_FLAG_WPERR: FMC erase/program protection error interrupt flag bit
- \arg FMC_INT_FLAG_END: FMC end of operation interrupt flag bit
+ \arg FMC_INT_FLAG_PGERR: FMC operation error interrupt flag
+ \arg FMC_INT_FLAG_WPERR: FMC erase/program protection error interrupt flag
+ \arg FMC_INT_FLAG_END: FMC end of operation interrupt flag
\param[out] none
\retval FlagStatus: SET or RESET
*/
FlagStatus fmc_interrupt_flag_get(fmc_interrupt_flag_enum flag) {
- FlagStatus ret1 = RESET;
- FlagStatus ret2 = RESET;
-
- if (FMC_STAT0_REG_OFFSET == FMC_REG_OFFSET_GET(flag)) {
- /* get the staus of interrupt flag */
- ret1 = (FlagStatus)(FMC_REG_VALS(flag) & BIT(FMC_BIT_POS0(flag)));
- /* get the staus of interrupt enale bit */
- ret2 = (FlagStatus)(FMC_CTL0 & BIT(FMC_BIT_POS1(flag)));
- }
+ FlagStatus status = RESET;
- if (ret1 && ret2) {
- return SET;
- } else {
- return RESET;
+ if (FMC_STAT & flag) {
+ status = SET;
}
+ /* return the state of corresponding FMC flag */
+ return status;
}
/*!
\brief clear FMC interrupt flag state
\param[in] flag: FMC interrupt flags, refer to can_interrupt_flag_enum
only one parameter can be selected which is shown as below:
- \arg FMC_INT_FLAG_PGERR: FMC operation error interrupt flag bit
- \arg FMC_INT_FLAG_WPERR: FMC erase/program protection error interrupt flag bit
- \arg FMC_INT_FLAG_END: FMC end of operation interrupt flag bit
+ \arg FMC_INT_FLAG_PGERR: FMC operation error interrupt flag
+ \arg FMC_INT_FLAG_WPERR: FMC erase/program protection error interrupt flag
+ \arg FMC_INT_FLAG_END: FMC end of operation interrupt flag
\param[out] none
\retval none
*/
-void fmc_interrupt_flag_clear(fmc_interrupt_flag_enum flag) { FMC_REG_VALS(flag) |= BIT(FMC_BIT_POS0(flag)); }
+void fmc_interrupt_flag_clear(fmc_interrupt_flag_enum flag) {
+ /* clear the flags */
+ FMC_STAT = flag;
+}
/*!
\brief get the FMC state
@@ -573,13 +576,13 @@ void fmc_interrupt_flag_clear(fmc_interrupt_flag_enum flag) { FMC_REG_VALS(flag) fmc_state_enum fmc_state_get(void) {
fmc_state_enum fmc_state = FMC_READY;
- if ((uint32_t)0x00U != (FMC_STAT0 & FMC_STAT0_BUSY)) {
+ if ((uint32_t)0x00U != (FMC_STAT & FMC_STAT_BUSY)) {
fmc_state = FMC_BUSY;
} else {
- if ((uint32_t)0x00U != (FMC_STAT0 & FMC_STAT0_WPERR)) {
+ if ((uint32_t)0x00U != (FMC_STAT & FMC_STAT_WPERR)) {
fmc_state = FMC_WPERR;
} else {
- if ((uint32_t)0x00U != (FMC_STAT0 & (FMC_STAT0_PGERR))) {
+ if ((uint32_t)0x00U != (FMC_STAT & (FMC_STAT_PGERR))) {
fmc_state = FMC_PGERR;
}
}
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_fwdgt.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_fwdgt.c index 4e1a6bf0..66a400e4 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_fwdgt.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_fwdgt.c @@ -1,12 +1,13 @@ /*!
- \file gd32vf103_fwdgt.c
- \brief FWDGT driver
+ \file gd32vf103_fwdgt.c
+ \brief FWDGT driver
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -33,6 +34,7 @@ OF SUCH DAMAGE. */
#include "gd32vf103_fwdgt.h"
+#include "gd32vf103_rcu.h"
/* write value to FWDGT_CTL_CMD bit field */
#define CTL_CMD(regval) (BITS(0, 15) & ((uint32_t)(regval) << 0))
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_gpio.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_gpio.c index e496fb4d..d8ecc457 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_gpio.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_gpio.c @@ -1,12 +1,13 @@ /*!
- \file gd32vf103_gpio.c
- \brief GPIO driver
+ \file gd32vf103_gpio.c
+ \brief GPIO driver
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -33,6 +34,7 @@ OF SUCH DAMAGE. */
#include "gd32vf103_gpio.h"
+#include "gd32vf103_rcu.h"
#define AFIO_EXTI_SOURCE_MASK ((uint8_t)0x03U) /*!< AFIO exti source selection mask*/
#define AFIO_EXTI_SOURCE_FIELDS ((uint8_t)0x04U) /*!< select AFIO exti source registers */
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_i2c.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_i2c.c index 1062f29e..4e737fd0 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_i2c.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_i2c.c @@ -1,12 +1,13 @@ /*!
- \file gd32vf103_i2c.c
- \brief I2C driver
+ \file gd32vf103_i2c.c
+ \brief I2C driver
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -33,9 +34,10 @@ OF SUCH DAMAGE. */
#include "gd32vf103_i2c.h"
+#include "gd32vf103_rcu.h"
/* I2C register bit mask */
-#define I2CCLK_MAX ((uint32_t)0x00000048U) /*!< i2cclk maximum value */
+#define I2CCLK_MAX ((uint32_t)0x00000036U) /*!< i2cclk maximum value */
#define I2CCLK_MIN ((uint32_t)0x00000002U) /*!< i2cclk minimum value */
#define I2C_FLAG_MASK ((uint32_t)0x0000FFFFU) /*!< i2c flag mask */
#define I2C_ADDRESS_MASK ((uint32_t)0x000003FFU) /*!< i2c address mask */
@@ -71,10 +73,11 @@ void i2c_deinit(uint32_t i2c_periph) { \brief configure I2C clock
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] clkspeed: I2C clock speed, supports standard mode (up to 100 kHz), fast mode (up to 400 kHz)
- \param[in] dutycyc: duty cycle in fast mode
+ and fast mode plus (up to 1MHz)
+ \param[in] dutycyc: duty cycle in fast mode or fast mode plus
only one parameter can be selected which is shown as below:
- \arg I2C_DTCY_2: T_low/T_high=2
- \arg I2C_DTCY_16_9: T_low/T_high=16/9
+ \arg I2C_DTCY_2: T_low/T_high=2
+ \arg I2C_DTCY_16_9: T_low/T_high=16/9
\param[out] none
\retval none
*/
@@ -93,7 +96,6 @@ void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc) temp |= freq;
I2C_CTL1(i2c_periph) = temp;
-
if (100000U >= clkspeed) {
/* the maximum SCL rise time is 1000ns in standard mode */
risetime = (uint32_t)((pclk1 / 1000000U) + 1U);
@@ -130,6 +132,22 @@ void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc) I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST;
I2C_CKCFG(i2c_periph) |= clkc;
} else {
+ /* fast mode plus, the maximum SCL rise time is 120ns */
+ I2C_RT(i2c_periph) = (uint32_t)(((freq * (uint32_t)120U) / (uint32_t)1000U) + (uint32_t)1U);
+ if (I2C_DTCY_2 == dutycyc) {
+ /* I2C duty cycle is 2 */
+ clkc = (uint32_t)(pclk1 / (clkspeed * 3U));
+ I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY;
+ } else {
+ /* I2C duty cycle is 16/9 */
+ clkc = (uint32_t)(pclk1 / (clkspeed * 25U));
+ I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY;
+ }
+ /* enable fast mode */
+ I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST;
+ I2C_CKCFG(i2c_periph) |= clkc;
+ /* enable I2C fast mode plus */
+ I2C_FMPCFG(i2c_periph) |= I2C_FMPCFG_FMPEN;
}
}
@@ -239,28 +257,16 @@ void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandire }
/*!
- \brief configure I2C saddress1
- \param[in] i2c_periph: I2Cx(x=0,1)
- \param[in] addr: I2C address
- \param[out] none
- \retval none
-*/
-void i2c_saddr1_config(uint32_t i2c_periph, uint32_t addr) {
- /* configure saddress1 */
- I2C_SADDR1(i2c_periph) = (0xFE & addr);
-}
-
-/*!
\brief enable dual-address mode
\param[in] i2c_periph: I2Cx(x=0,1)
- \param[in] addr: the second address in dual-address mode
+ \param[in] dualaddr: the second address in dual-address mode
\param[out] none
\retval none
*/
-void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t addr) {
+void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t dualaddr) {
/* configure address */
- addr = addr & I2C_ADDRESS2_MASK;
- I2C_SADDR1(i2c_periph) = (I2C_SADDR1_DUADEN | addr);
+ dualaddr = dualaddr & I2C_ADDRESS2_MASK;
+ I2C_SADDR1(i2c_periph) = (I2C_SADDR1_DUADEN | dualaddr);
}
/*!
@@ -562,12 +568,10 @@ FlagStatus i2c_flag_get(uint32_t i2c_periph, i2c_flag_enum flag) { \retval none
*/
void i2c_flag_clear(uint32_t i2c_periph, i2c_flag_enum flag) {
- uint32_t temp;
if (I2C_FLAG_ADDSEND == flag) {
/* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */
- temp = I2C_STAT0(i2c_periph);
- temp = I2C_STAT1(i2c_periph);
- (void)temp;
+ I2C_STAT0(i2c_periph);
+ I2C_STAT1(i2c_periph);
} else {
I2C_REG_VAL(i2c_periph, flag) &= ~BIT(I2C_BIT_POS(flag));
}
@@ -608,7 +612,7 @@ void i2c_interrupt_disable(uint32_t i2c_periph, i2c_interrupt_enum interrupt) { \arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag
\arg I2C_INT_FLAG_BTC: byte transmission finishes
\arg I2C_INT_FLAG_ADD10SEND: header of 10-bit address is sent in master mode interrupt flag
- \arg I2C_INT_FLAG_STPDET: etop condition detected in slave mode interrupt flag
+ \arg I2C_INT_FLAG_STPDET: stop condition detected in slave mode interrupt flag
\arg I2C_INT_FLAG_RBNE: I2C_DATA is not Empty during receiving interrupt flag
\arg I2C_INT_FLAG_TBE: I2C_DATA is empty during transmitting interrupt flag
\arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag
@@ -663,12 +667,10 @@ FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum i \retval none
*/
void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag) {
- uint32_t temp;
if (I2C_INT_FLAG_ADDSEND == int_flag) {
/* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */
- temp = I2C_STAT0(i2c_periph);
- temp = I2C_STAT1(i2c_periph);
- (void)temp;
+ I2C_STAT0(i2c_periph);
+ I2C_STAT1(i2c_periph);
} else {
I2C_REG_VAL2(i2c_periph, int_flag) &= ~BIT(I2C_BIT_POS2(int_flag));
}
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_pmu.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_pmu.c index 1052d4eb..f0ebae90 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_pmu.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_pmu.c @@ -2,11 +2,12 @@ \file gd32vf103_pmu.c
\brief PMU driver
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -33,7 +34,8 @@ OF SUCH DAMAGE. */
#include "gd32vf103_pmu.h"
-
+#include "gd32vf103_rcu.h"
+#include "riscv_encoding.h"
/*!
\brief reset PMU register
\param[in] none
@@ -94,15 +96,17 @@ void pmu_lvd_disable(void) { */
void pmu_to_sleepmode(uint8_t sleepmodecmd) {
/* clear sleepdeep bit of RISC-V system control register */
- __RV_CSR_CLEAR(CSR_WFE, WFE_WFE);
+ clear_csr(0x811U, 0x1U);
/* select WFI or WFE command to enter sleep mode */
if (WFI_CMD == sleepmodecmd) {
__WFI();
} else {
- __disable_irq();
- __WFE();
- __enable_irq();
+ clear_csr(mstatus, MSTATUS_MIE);
+ set_csr(0x810U, 0x1U);
+ __WFI();
+ clear_csr(0x810U, 0x1U);
+ set_csr(mstatus, MSTATUS_MIE);
}
}
@@ -125,17 +129,19 @@ void pmu_to_deepsleepmode(uint32_t ldo, uint8_t deepsleepmodecmd) { /* set ldolp bit according to pmu_ldo */
PMU_CTL |= ldo;
/* set CSR_SLEEPVALUE bit of RISC-V system control register */
- __RV_CSR_SET(CSR_WFE, WFE_WFE);
+ set_csr(0x811U, 0x1U);
/* select WFI or WFE command to enter deepsleep mode */
if (WFI_CMD == deepsleepmodecmd) {
__WFI();
} else {
- __disable_irq();
- __WFE();
- __enable_irq();
+ clear_csr(mstatus, MSTATUS_MIE);
+ set_csr(0x810U, 0x1U);
+ __WFI();
+ clear_csr(0x810U, 0x1U);
+ set_csr(mstatus, MSTATUS_MIE);
}
/* reset sleepdeep bit of RISC-V system control register */
- __RV_CSR_CLEAR(CSR_WFE, WFE_WFE);
+ clear_csr(0x811U, 0x1U);
}
/*!
@@ -149,7 +155,7 @@ void pmu_to_deepsleepmode(uint32_t ldo, uint8_t deepsleepmodecmd) { */
void pmu_to_standbymode(uint8_t standbymodecmd) {
/* set CSR_SLEEPVALUE bit of RISC-V system control register */
- __RV_CSR_SET(CSR_WFE, WFE_WFE);
+ set_csr(0x811U, 0x1U);
/* set stbmod bit */
PMU_CTL |= PMU_CTL_STBMOD;
@@ -161,11 +167,13 @@ void pmu_to_standbymode(uint8_t standbymodecmd) { if (WFI_CMD == standbymodecmd) {
__WFI();
} else {
- __disable_irq();
- __WFE();
- __enable_irq();
+ clear_csr(mstatus, MSTATUS_MIE);
+ set_csr(0x810U, 0x1U);
+ __WFI();
+ clear_csr(0x810U, 0x1U);
+ set_csr(mstatus, MSTATUS_MIE);
}
- __RV_CSR_CLEAR(CSR_WFE, WFE_WFE);
+ clear_csr(0x811U, 0x1U);
}
/*!
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_rcu.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_rcu.c index b1f476e2..af0b669d 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_rcu.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_rcu.c @@ -2,11 +2,12 @@ \file gd32vf103_rcu.c
\brief RCU driver
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -34,6 +35,10 @@ OF SUCH DAMAGE. #include "gd32vf103_rcu.h"
+/* define startup timeout count */
+#define OSC_STARTUP_TIMEOUT ((uint32_t)0xFFFFFU)
+#define LXTAL_STARTUP_TIMEOUT ((uint32_t)0x3FFFFFFU)
+
/*!
\brief deinitialize the RCU
\param[in] none
@@ -44,14 +49,13 @@ void rcu_deinit(void) { /* enable IRC8M */
RCU_CTL |= RCU_CTL_IRC8MEN;
rcu_osci_stab_wait(RCU_IRC8M);
-
- /* reset CFG0 register */
- RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC | RCU_CFG0_ADCPSC | RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0_LSB | RCU_CFG0_PLLMF | RCU_CFG0_USBFSPSC | RCU_CFG0_CKOUT0SEL
- | RCU_CFG0_ADCPSC_2 | RCU_CFG0_PLLMF_4);
/* reset CTL register */
RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLLEN);
RCU_CTL &= ~RCU_CTL_HXTALBPS;
RCU_CTL &= ~(RCU_CTL_PLL1EN | RCU_CTL_PLL2EN);
+ /* reset CFG0 register */
+ RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC | RCU_CFG0_ADCPSC | RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0_LSB | RCU_CFG0_PLLMF | RCU_CFG0_USBFSPSC | RCU_CFG0_CKOUT0SEL
+ | RCU_CFG0_ADCPSC_2 | RCU_CFG0_PLLMF_4);
/* reset INT and CFG1 register */
RCU_INT = 0x00ff0000U;
RCU_CFG1 &= ~(RCU_CFG1_PREDV0 | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PLL2MF | RCU_CFG1_PREDV0SEL | RCU_CFG1_I2S1SEL | RCU_CFG1_I2S2SEL);
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_rtc.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_rtc.c index 32d48c1a..8a7bb21f 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_rtc.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_rtc.c @@ -1,12 +1,13 @@ /*!
- \file gd32vf103_rtc.c
- \brief RTC driver
+ \file gd32vf103_rtc.c
+ \brief RTC driver
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -33,6 +34,7 @@ OF SUCH DAMAGE. */
#include "gd32vf103_rtc.h"
+#include "gd32vf103_rcu.h"
/* RTC register high / low bits mask */
#define RTC_HIGH_BITS_MASK ((uint32_t)0x000F0000U) /* RTC high bits mask */
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_spi.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_spi.c index 57cfc342..2ff08fb9 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_spi.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_spi.c @@ -1,12 +1,13 @@ /*!
- \file gd32vf103_spi.c
- \brief SPI driver
+ \file gd32vf103_spi.c
+ \brief SPI driver
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -33,6 +34,7 @@ OF SUCH DAMAGE. */
#include "gd32vf103_spi.h"
+#include "gd32vf103_rcu.h"
/* SPI/I2S parameter initialization mask */
#define SPI_INIT_MASK ((uint32_t)0x00003040U) /*!< SPI parameter initialization mask */
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_timer.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_timer.c index e6755efe..08192e35 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_timer.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_timer.c @@ -1,12 +1,13 @@ /*!
- \file gd32vf103_timer.c
- \brief TIMER driver
+ \file gd32vf103_timer.c
+ \brief TIMER driver
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.1, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -32,6 +33,7 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSI OF SUCH DAMAGE.
*/
#include "gd32vf103_timer.h"
+#include "gd32vf103_rcu.h"
/* TIMER init parameter mask */
#define ALIGNEDMODE_MASK ((uint32_t)0x00000060U) /*!< TIMER init parameter aligne dmode mask */
@@ -40,7 +42,7 @@ OF SUCH DAMAGE. /*!
\brief deinit a timer
- \param[in] timer_periph: TIMERx(x=0..13)
+ \param[in] timer_periph: TIMERx(x=0..6)
\param[out] none
\retval none
*/
@@ -159,7 +161,7 @@ void timer_enable(uint32_t timer_periph) { TIMER_CTL0(timer_periph) |= (uint32_t /*!
\brief disable a timer
- \param[in] timer_periph: TIMERx(x=0..13)
+ \param[in] timer_periph: TIMERx(x=0..6)
\param[out] none
\retval none
*/
@@ -897,7 +899,7 @@ void timer_channel_output_fast_config(uint32_t timer_periph, uint16_t channel, u \param[in] channel:
only one parameter can be selected which is shown as below:
\arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0..4))
- \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0..41))
+ \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0..4))
\arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0..4))
\arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0..4))
\param[in] occlear: channel output clear function
@@ -1784,7 +1786,7 @@ FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt) { \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag, TIMERx(x=0..4)
\arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag, TIMERx(x=0..4)
\arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag, TIMERx(x=0)
- \arg TIMER_INT_FLAG_TRG: trigger interrupt flag, TIMERx(x=0)
+ \arg TIMER_INT_FLAG_TRG: trigger interrupt flag, TIMERx(x=0..4)
\arg TIMER_INT_FLAG_BRK: break interrupt flag, TIMERx(x=0)
\param[out] none
\retval none
@@ -1802,7 +1804,7 @@ void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt) { TIM \arg TIMER_FLAG_CH2: channel 2 flag, TIMERx(x=0..4)
\arg TIMER_FLAG_CH3: channel 3 flag, TIMERx(x=0..4)
\arg TIMER_FLAG_CMT: channel commutation flag, TIMERx(x=0)
- \arg TIMER_FLAG_TRG: trigger flag, TIMERx(x=0)
+ \arg TIMER_FLAG_TRG: trigger flag, TIMERx(x=0..4)
\arg TIMER_FLAG_BRK: break flag, TIMERx(x=0)
\arg TIMER_FLAG_CH0O: channel 0 overcapture flag, TIMERx(x=0..4)
\arg TIMER_FLAG_CH1O: channel 1 overcapture flag, TIMERx(x=0..4)
@@ -1830,7 +1832,7 @@ FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag) { \arg TIMER_FLAG_CH2: channel 2 flag, TIMERx(x=0..4)
\arg TIMER_FLAG_CH3: channel 3 flag, TIMERx(x=0..4)
\arg TIMER_FLAG_CMT: channel commutation flag, TIMERx(x=0)
- \arg TIMER_FLAG_TRG: trigger flag, TIMERx(x=0)
+ \arg TIMER_FLAG_TRG: trigger flag, TIMERx(x=0..4)
\arg TIMER_FLAG_BRK: break flag, TIMERx(x=0)
\arg TIMER_FLAG_CH0O: channel 0 overcapture flag, TIMERx(x=0..4)
\arg TIMER_FLAG_CH1O: channel 1 overcapture flag, TIMERx(x=0..4)
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_usart.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_usart.c index 555394dc..dd981615 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_usart.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_usart.c @@ -2,11 +2,13 @@ \file gd32vf103_usart.c
\brief USART driver
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2019-09-18, V1.0.1, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -33,6 +35,7 @@ OF SUCH DAMAGE. */
#include "gd32vf103_usart.h"
+#include "gd32vf103_rcu.h"
/*!
\brief reset USART/UART
@@ -556,12 +559,12 @@ void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd) { \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
\param[in] flag: USART flags, refer to usart_flag_enum
only one parameter can be selected which is shown as below:
- \arg USART_FLAG_CTSF: CTS change flag
- \arg USART_FLAG_LBDF: LIN break detected flag
+ \arg USART_FLAG_CTS: CTS change flag
+ \arg USART_FLAG_LBD: LIN break detected flag
\arg USART_FLAG_TBE: transmit data buffer empty
\arg USART_FLAG_TC: transmission complete
\arg USART_FLAG_RBNE: read data buffer not empty
- \arg USART_FLAG_IDLEF: IDLE frame detected flag
+ \arg USART_FLAG_IDLE: IDLE frame detected flag
\arg USART_FLAG_ORERR: overrun error
\arg USART_FLAG_NERR: noise error flag
\arg USART_FLAG_FERR: frame error flag
@@ -582,8 +585,8 @@ FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag) { \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
\param[in] flag: USART flags, refer to usart_flag_enum
only one parameter can be selected which is shown as below:
- \arg USART_FLAG_CTSF: CTS change flag
- \arg USART_FLAG_LBDF: LIN break detected flag
+ \arg USART_FLAG_CTS: CTS change flag
+ \arg USART_FLAG_LBD: LIN break detected flag
\arg USART_FLAG_TC: transmission complete
\arg USART_FLAG_RBNE: read data buffer not empty
\param[out] none
@@ -594,7 +597,7 @@ void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag) { USART_REG_V /*!
\brief enable USART interrupt
\param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
- \param[in] int_flag
+ \param[in] interrupt
only one parameter can be selected which is shown as below:
\arg USART_INT_PERR: parity error interrupt
\arg USART_INT_TBE: transmitter buffer empty interrupt
@@ -607,12 +610,12 @@ void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag) { USART_REG_V \param[out] none
\retval none
*/
-void usart_interrupt_enable(uint32_t usart_periph, uint32_t int_flag) { USART_REG_VAL(usart_periph, int_flag) |= BIT(USART_BIT_POS(int_flag)); }
+void usart_interrupt_enable(uint32_t usart_periph, uint32_t interrupt) { USART_REG_VAL(usart_periph, interrupt) |= BIT(USART_BIT_POS(interrupt)); }
/*!
\brief disable USART interrupt
\param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
- \param[in] int_flag
+ \param[in] interrupt
only one parameter can be selected which is shown as below:
\arg USART_INT_PERR: parity error interrupt
\arg USART_INT_TBE: transmitter buffer empty interrupt
@@ -625,7 +628,7 @@ void usart_interrupt_enable(uint32_t usart_periph, uint32_t int_flag) { USART_RE \param[out] none
\retval none
*/
-void usart_interrupt_disable(uint32_t usart_periph, uint32_t int_flag) { USART_REG_VAL(usart_periph, int_flag) &= ~BIT(USART_BIT_POS(int_flag)); }
+void usart_interrupt_disable(uint32_t usart_periph, uint32_t interrupt) { USART_REG_VAL(usart_periph, interrupt) &= ~BIT(USART_BIT_POS(interrupt)); }
/*!
\brief get USART interrupt and flag status
@@ -663,7 +666,7 @@ FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, uint32_t int_flag) { /*!
\brief clear USART interrupt flag in STAT register
\param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
- \param[in] flag: USART interrupt flag
+ \param[in] int_flag: USART interrupt flag
only one parameter can be selected which is shown as below:
\arg USART_INT_FLAG_CTS: CTS change flag
\arg USART_INT_FLAG_LBD: LIN break detected flag
@@ -672,18 +675,4 @@ FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, uint32_t int_flag) { \param[out] none
\retval none
*/
-void usart_interrupt_flag_clear(uint32_t usart_periph, uint32_t flag) { USART_REG_VAL2(usart_periph, flag) &= ~BIT(USART_BIT_POS2(flag)); }
-
-int usart_write(uint32_t usart_periph, int ch) {
- usart_data_transmit(usart_periph, (uint8_t)ch);
- while (usart_flag_get(usart_periph, USART_FLAG_TBE) == RESET) {}
-
- return ch;
-}
-
-uint8_t usart_read(uint32_t usart_periph) {
- /* loop until RBNE = 1 */
- while (usart_flag_get(usart_periph, USART_FLAG_RBNE) == RESET)
- ;
- return (usart_data_receive(usart_periph));
-}
+void usart_interrupt_flag_clear(uint32_t usart_periph, uint32_t int_flag) { USART_REG_VAL2(usart_periph, int_flag) &= ~BIT(USART_BIT_POS2(int_flag)); }
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_wwdgt.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_wwdgt.c index 12d06817..9186dfbf 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_wwdgt.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_wwdgt.c @@ -1,12 +1,13 @@ /*!
- \file gd32vf103_wwdgt.c
- \brief WWDGT driver
+ \file gd32vf103_wwdgt.c
+ \brief WWDGT driver
- \version 2019-6-5, V1.0.0, firmware for GD32VF103
+ \version 2019-06-05, V1.0.0, firmware for GD32VF103
+ \version 2020-08-04, V1.1.0, firmware for GD32VF103
*/
/*
- Copyright (c) 2019, GigaDevice Semiconductor Inc.
+ Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
@@ -33,6 +34,7 @@ OF SUCH DAMAGE. */
#include "gd32vf103_wwdgt.h"
+#include "gd32vf103_rcu.h"
/* write value to WWDGT_CTL_CNT bit field */
#define CTL_CNT(regval) (BITS(0, 6) & ((uint32_t)(regval) << 0))
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/n200_func.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/n200_func.c new file mode 100644 index 00000000..c4f213d1 --- /dev/null +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Drivers/n200_func.c @@ -0,0 +1,339 @@ +/* See LICENSE for license details. */
+#include <gd32vf103.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(__ICCRISCV__)
+#include "compiler.h"
+#elif defined(__GNUC__)
+#include <unistd.h>
+#endif
+
+#include "gd32vf103_rcu.h"
+#include "n200_func.h"
+#include "riscv_encoding.h"
+
+/* Configure PMP to make all the address space accesable and executable */
+void pmp_open_all_space(void) {
+ /* Config entry0 addr to all 1s to make the range cover all space */
+ asm volatile("li x6, 0xffffffff" ::: "x6");
+ asm volatile("csrw pmpaddr0, x6" :::);
+ /* Config entry0 cfg to make it NAPOT address mode, and R/W/X okay */
+ asm volatile("li x6, 0x7f" ::: "x6");
+ asm volatile("csrw pmpcfg0, x6" :::);
+}
+
+void switch_m2u_mode(void) {
+ clear_csr(mstatus, MSTATUS_MPP);
+ /* printf("\nIn the m2u function, the mstatus is 0x%x\n", read_csr(mstatus)); */
+ /* printf("\nIn the m2u function, the mepc is 0x%x\n", read_csr(mepc)); */
+#if defined(__GNUC__)
+ asm volatile("la x6, 1f " ::: "x6");
+#endif
+ asm volatile("csrw mepc, x6" :::);
+ asm volatile("mret" :::);
+ asm volatile("1:" :::);
+}
+
+uint32_t mtime_lo(void) { return *(volatile uint32_t *)(TIMER_CTRL_ADDR + TIMER_MTIME); }
+
+uint32_t mtime_hi(void) { return *(volatile uint32_t *)(TIMER_CTRL_ADDR + TIMER_MTIME + 4); }
+
+uint64_t get_timer_value(void) {
+ while (1) {
+ uint32_t hi = mtime_hi();
+ uint32_t lo = mtime_lo();
+ if (hi == mtime_hi())
+ return ((uint64_t)hi << 32) | lo;
+ }
+}
+
+uint32_t get_timer_freq(void) { return TIMER_FREQ; }
+
+uint64_t get_instret_value(void) {
+ while (1) {
+#if defined(__ICCRISCV__)
+ uint32_t hi = read_csr(CSR_MINSTRETH);
+ uint32_t lo = read_csr(CSR_MINSTRETH);
+ if (hi == read_csr(CSR_MINSTRETH))
+#elif defined(__GNUC__)
+ uint32_t hi = read_csr(minstreth);
+ uint32_t lo = read_csr(minstret);
+ if (hi == read_csr(minstreth))
+#endif
+
+ return ((uint64_t)hi << 32) | lo;
+ }
+}
+
+uint64_t get_cycle_value(void) {
+ while (1) {
+#if defined(__ICCRISCV__)
+ uint32_t hi = read_csr(CSR_MCYCLEH);
+ uint32_t lo = read_csr(CSR_MCYCLE);
+ if (hi == read_csr(CSR_MCYCLEH))
+#elif defined(__GNUC__)
+ uint32_t hi = read_csr(mcycleh);
+ uint32_t lo = read_csr(mcycle);
+ if (hi == read_csr(mcycleh))
+#endif
+
+ return ((uint64_t)hi << 32) | lo;
+ }
+}
+
+/* Note that there are no assertions or bounds checking on these */
+/* parameter values. */
+void eclic_init(uint32_t num_irq) {
+
+ typedef volatile uint32_t vuint32_t;
+
+ /* clear cfg register */
+ *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_CFG_OFFSET) = 0;
+
+ /* clear minthresh register */
+ *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_MTH_OFFSET) = 0;
+
+ /* clear all IP/IE/ATTR/CTRL bits for all interrupt sources */
+ vuint32_t *ptr;
+
+ vuint32_t *base = (vuint32_t *)(ECLIC_ADDR_BASE + ECLIC_INT_IP_OFFSET);
+ vuint32_t *upper = (vuint32_t *)(base + num_irq * 4);
+
+ for (ptr = base; ptr < upper; ptr = ptr + 4) {
+ *ptr = 0;
+ }
+}
+
+void eclic_enable_interrupt(uint32_t source) { *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_IE_OFFSET + source * 4) = 1; }
+
+void eclic_disable_interrupt(uint32_t source) { *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_IE_OFFSET + source * 4) = 0; }
+
+void eclic_set_pending(uint32_t source) { *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_IP_OFFSET + source * 4) = 1; }
+
+void eclic_clear_pending(uint32_t source) { *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_IP_OFFSET + source * 4) = 0; }
+
+void eclic_set_intctrl(uint32_t source, uint8_t intctrl) { *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_CTRL_OFFSET + source * 4) = intctrl; }
+
+uint8_t eclic_get_intctrl(uint32_t source) { return *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_CTRL_OFFSET + source * 4); }
+
+void eclic_set_intattr(uint32_t source, uint8_t intattr) { *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_ATTR_OFFSET + source * 4) = intattr; }
+
+uint8_t eclic_get_intattr(uint32_t source) { return *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_INT_ATTR_OFFSET + source * 4); }
+
+void eclic_set_cliccfg(uint8_t cliccfg) { *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_CFG_OFFSET) = cliccfg; }
+
+uint8_t eclic_get_cliccfg(void) { return *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_CFG_OFFSET); }
+
+void eclic_set_mth(uint8_t mth) { *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_MTH_OFFSET) = mth; }
+
+uint8_t eclic_get_mth(void) { return *(volatile uint8_t *)(ECLIC_ADDR_BASE + ECLIC_MTH_OFFSET); }
+
+/* sets nlbits */
+void eclic_set_nlbits(uint8_t nlbits) {
+ /* shift nlbits to correct position */
+ uint8_t nlbits_shifted = nlbits << ECLIC_CFG_NLBITS_LSB;
+
+ /* read the current cliccfg */
+ uint8_t old_cliccfg = eclic_get_cliccfg();
+ uint8_t new_cliccfg = (old_cliccfg & (~ECLIC_CFG_NLBITS_MASK)) | (ECLIC_CFG_NLBITS_MASK & nlbits_shifted);
+
+ eclic_set_cliccfg(new_cliccfg);
+}
+
+/* get nlbits */
+uint8_t eclic_get_nlbits(void) {
+ /* extract nlbits */
+ uint8_t nlbits = eclic_get_cliccfg();
+ nlbits = (nlbits & ECLIC_CFG_NLBITS_MASK) >> ECLIC_CFG_NLBITS_LSB;
+ return nlbits;
+}
+
+/* sets an interrupt level based encoding of nlbits and ECLICINTCTLBITS */
+void eclic_set_irq_lvl(uint32_t source, uint8_t lvl) {
+ /* extract nlbits */
+ uint8_t nlbits = eclic_get_nlbits();
+ if (nlbits > ECLICINTCTLBITS) {
+ nlbits = ECLICINTCTLBITS;
+ }
+
+ /* shift lvl right to mask off unused bits */
+ lvl = lvl >> (8 - nlbits);
+ /* shift lvl into correct bit position */
+ lvl = lvl << (8 - nlbits);
+
+ /* write to clicintctrl */
+ uint8_t current_intctrl = eclic_get_intctrl(source);
+ /* shift intctrl left to mask off unused bits */
+ current_intctrl = current_intctrl << nlbits;
+ /* shift intctrl into correct bit position */
+ current_intctrl = current_intctrl >> nlbits;
+
+ eclic_set_intctrl(source, (current_intctrl | lvl));
+}
+
+/* gets an interrupt level based encoding of nlbits */
+uint8_t eclic_get_irq_lvl(uint32_t source) {
+ /* extract nlbits */
+ uint8_t nlbits = eclic_get_nlbits();
+ if (nlbits > ECLICINTCTLBITS) {
+ nlbits = ECLICINTCTLBITS;
+ }
+
+ uint8_t intctrl = eclic_get_intctrl(source);
+
+ /* shift intctrl */
+ intctrl = intctrl >> (8 - nlbits);
+ /* shift intctrl */
+ uint8_t lvl = intctrl << (8 - nlbits);
+
+ return lvl;
+}
+
+void eclic_set_irq_lvl_abs(uint32_t source, uint8_t lvl_abs) {
+ /* extract nlbits */
+ uint8_t nlbits = eclic_get_nlbits();
+ if (nlbits > ECLICINTCTLBITS) {
+ nlbits = ECLICINTCTLBITS;
+ }
+
+ /* shift lvl_abs into correct bit position */
+ uint8_t lvl = lvl_abs << (8 - nlbits);
+
+ /* write to clicintctrl */
+ uint8_t current_intctrl = eclic_get_intctrl(source);
+ /* shift intctrl left to mask off unused bits */
+ current_intctrl = current_intctrl << nlbits;
+ /* shift intctrl into correct bit position */
+ current_intctrl = current_intctrl >> nlbits;
+
+ eclic_set_intctrl(source, (current_intctrl | lvl));
+}
+
+uint8_t eclic_get_irq_lvl_abs(uint32_t source) {
+ /* extract nlbits */
+ uint8_t nlbits = eclic_get_nlbits();
+ if (nlbits > ECLICINTCTLBITS) {
+ nlbits = ECLICINTCTLBITS;
+ }
+
+ uint8_t intctrl = eclic_get_intctrl(source);
+
+ /* shift intctrl */
+ intctrl = intctrl >> (8 - nlbits);
+ /* shift intctrl */
+ uint8_t lvl_abs = intctrl;
+
+ return lvl_abs;
+}
+
+/* sets an interrupt priority based encoding of nlbits and ECLICINTCTLBITS */
+uint8_t eclic_set_irq_priority(uint32_t source, uint8_t priority) {
+ /* extract nlbits */
+ uint8_t nlbits = eclic_get_nlbits();
+ if (nlbits >= ECLICINTCTLBITS) {
+ nlbits = ECLICINTCTLBITS;
+ return 0;
+ }
+
+ /* shift priority into correct bit position */
+ priority = priority << (8 - ECLICINTCTLBITS);
+
+ /* write to eclicintctrl */
+ uint8_t current_intctrl = eclic_get_intctrl(source);
+ /* shift intctrl right to mask off unused bits */
+ current_intctrl = current_intctrl >> (8 - nlbits);
+ /* shift intctrl into correct bit position */
+ current_intctrl = current_intctrl << (8 - nlbits);
+
+ eclic_set_intctrl(source, (current_intctrl | priority));
+
+ return priority;
+}
+
+/* gets an interrupt priority based encoding of nlbits */
+uint8_t eclic_get_irq_priority(uint32_t source) {
+ /* extract nlbits */
+ uint8_t nlbits = eclic_get_nlbits();
+ if (nlbits > ECLICINTCTLBITS) {
+ nlbits = ECLICINTCTLBITS;
+ }
+
+ uint8_t intctrl = eclic_get_intctrl(source);
+
+ /* shift intctrl */
+ intctrl = intctrl << nlbits;
+ /* shift intctrl */
+ uint8_t priority = intctrl >> (nlbits + (8 - ECLICINTCTLBITS));
+
+ return priority;
+}
+
+void eclic_mode_enable() {
+#if defined(__ICCRISCV__)
+ uint32_t mtvec_value = read_csr(CSR_MTVEC);
+ mtvec_value = mtvec_value & 0xFFFFFFC0;
+ mtvec_value = mtvec_value | 0x00000003;
+ write_csr(CSR_MTVEC, mtvec_value);
+#elif defined(__GNUC__)
+ uint32_t mtvec_value = read_csr(mtvec);
+ mtvec_value = mtvec_value & 0xFFFFFFC0;
+ mtvec_value = mtvec_value | 0x00000003;
+ write_csr(mtvec, mtvec_value);
+#endif
+}
+
+/* sets vector-mode or non-vector mode */
+void eclic_set_vmode(uint32_t source) {
+ /* read the current attr */
+ uint8_t old_intattr = eclic_get_intattr(source);
+ /* Keep other bits unchanged and only set the LSB bit */
+ uint8_t new_intattr = (old_intattr | 0x1);
+
+ eclic_set_intattr(source, new_intattr);
+}
+
+void eclic_set_nonvmode(uint32_t source) {
+ /* read the current attr */
+ uint8_t old_intattr = eclic_get_intattr(source);
+ /* Keep other bits unchanged and only clear the LSB bit*/
+ uint8_t new_intattr = (old_intattr & (~0x1));
+
+ eclic_set_intattr(source, new_intattr);
+}
+
+/* sets interrupt as level sensitive
+Bit 1, trig[0], is defined as "edge-triggered" (0: level-triggered, 1: edge-triggered);
+Bit 2, trig[1], is defined as "negative-edge" (0: positive-edge, 1: negative-edge).*/
+
+void eclic_set_level_trig(uint32_t source) {
+ /* read the current attr */
+ uint8_t old_intattr = eclic_get_intattr(source);
+ /* Keep other bits unchanged and only clear the bit 1 */
+ uint8_t new_intattr = (old_intattr & (~0x2));
+
+ eclic_set_intattr(source, new_intattr);
+}
+
+void eclic_set_posedge_trig(uint32_t source) {
+ /* read the current attr */
+ uint8_t old_intattr = eclic_get_intattr(source);
+ /* Keep other bits unchanged and only set the bit 1 */
+ uint8_t new_intattr = (old_intattr | 0x2);
+ /* Keep other bits unchanged and only clear the bit 2 */
+ new_intattr = (old_intattr & (~0x4));
+
+ eclic_set_intattr(source, new_intattr);
+}
+
+void eclic_set_negedge_trig(uint32_t source) {
+ /*read the current attr */
+ uint8_t old_intattr = eclic_get_intattr(source);
+ /* Keep other bits unchanged and only set the bit 1*/
+ uint8_t new_intattr = (old_intattr | 0x2);
+ /* Keep other bits unchanged and only set the bit 2*/
+ new_intattr = (old_intattr | 0x4);
+
+ eclic_set_intattr(source, new_intattr);
+}
diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Stubs/read.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Stubs/read.c index d828862a..85b12773 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Stubs/read.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Stubs/read.c @@ -1,5 +1,4 @@ #include "gd32vf103_usart.h" -#include "nuclei_sdk_hal.h" #include <errno.h> #include <stdint.h> #include <sys/types.h> diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Stubs/write.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Stubs/write.c deleted file mode 100644 index 835878ed..00000000 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/Stubs/write.c +++ /dev/null @@ -1,10 +0,0 @@ -/* See LICENSE of license details. */ - -#include "gd32vf103_usart.h" -#include <errno.h> -#include <nuclei_sdk_hal.h> -#include <stdint.h> -#include <sys/types.h> -#include <unistd.h> - -ssize_t _write(int fd, const void *ptr, size_t len) { return -1; } diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/gd32vf103_soc.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/gd32vf103_soc.c index 9599a793..c4cf2278 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/gd32vf103_soc.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/gd32vf103_soc.c @@ -41,12 +41,12 @@ uint32_t get_cpu_freq() { * \remarks */ void delay_1ms(uint32_t count) { - uint64_t start_mtime, delta_mtime; - uint64_t delay_ticks = (SOC_TIMER_FREQ * (uint64_t)count) / 1000; + uint64_t end_mtime; + uint64_t delay_ticks = ((SOC_TIMER_FREQ / 4) * (uint64_t)count) / 1000; - start_mtime = SysTimer_GetLoadValue(); + end_mtime = SysTimer_GetLoadValue() + delay_ticks; do { - delta_mtime = SysTimer_GetLoadValue() - start_mtime; - } while (delta_mtime < delay_ticks); + asm("nop"); + } while (SysTimer_GetLoadValue() < end_mtime); } diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/system_gd32vf103.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/system_gd32vf103.c index b34e55a4..171bb151 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/system_gd32vf103.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/system_gd32vf103.c @@ -23,7 +23,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "nuclei_sdk_hal.h" +#include "gd32vf103.h" +#include "gd32vf103_rcu.h" #include <stdint.h> #include <stdio.h> diff --git a/source/Core/BSP/Pine64/configuration.h b/source/Core/BSP/Pine64/configuration.h index ad19637e..97e692ba 100644 --- a/source/Core/BSP/Pine64/configuration.h +++ b/source/Core/BSP/Pine64/configuration.h @@ -132,11 +132,11 @@ #define MIN_BOOST_TEMP_C 250 // The min settable temp for boost mode °C #define MIN_BOOST_TEMP_F 480 // The min settable temp for boost mode °F -#define POW_PD -#define POW_QC -#define POW_DC -#define POW_QC_20V -#define ENABLE_QC2 +#define POW_PD 1 +#define POW_QC 1 +#define POW_DC 1 +#define POW_QC_20V 1 +#define ENABLE_QC2 1 #define TEMP_TMP36 #define ACCEL_BMA #define ACCEL_SC7 @@ -146,6 +146,6 @@ #define HARDWARE_MAX_WATTAGE_X10 750 #define TIP_THERMAL_MASS 65 // X10 watts to raise 1 deg C in 1 second -#define tipResistance 75 // x10 ohms, 7.5 typical for Pinecil tips +#define TIP_RESISTANCE 75 // x10 ohms, 7.5 typical for Pinecil tips #endif #endif diff --git a/source/Core/BSP/Pine64/fusb_user.cpp b/source/Core/BSP/Pine64/fusb_user.cpp index 5b9137ec..0e06e943 100644 --- a/source/Core/BSP/Pine64/fusb_user.cpp +++ b/source/Core/BSP/Pine64/fusb_user.cpp @@ -1,10 +1,8 @@ #include "configuration.h" -#ifdef POW_PD +#if POW_PD #include "BSP.h" #include "I2C_Wrapper.hpp" #include "Setup.h" -#include "fusb302b.h" -#include "fusb_user.h" /* * Read multiple bytes from the FUSB302B @@ -14,7 +12,7 @@ * size: The number of bytes to read * buf: The buffer into which data will be read */ -bool fusb_read_buf(uint8_t addr, uint8_t size, uint8_t *buf) { return FRToSI2C::Mem_Read(FUSB302B_ADDR, addr, buf, size); } +bool fusb_read_buf(const uint8_t deviceAddr, const uint8_t registerAdd, const uint8_t size, uint8_t *buf) { return FRToSI2C::Mem_Read(deviceAddr, registerAdd, buf, size); } /* * Write multiple bytes to the FUSB302B @@ -24,11 +22,6 @@ bool fusb_read_buf(uint8_t addr, uint8_t size, uint8_t *buf) { return FRToSI2C:: * size: The number of bytes to write * buf: The buffer to write */ -bool fusb_write_buf(uint8_t addr, uint8_t size, const uint8_t *buf) { return FRToSI2C::Mem_Write(FUSB302B_ADDR, addr, (uint8_t *)buf, size); } - -bool fusb302_detect() { - // Probe the I2C bus for its address - return FRToSI2C::probe(FUSB302B_ADDR); -} +bool fusb_write_buf(const uint8_t deviceAddr, const uint8_t registerAdd, const uint8_t size, uint8_t *buf) { return FRToSI2C::Mem_Write(deviceAddr, registerAdd, (uint8_t *)buf, size); } #endif diff --git a/source/Core/BSP/Pine64/postRTOS.cpp b/source/Core/BSP/Pine64/postRTOS.cpp index 107d2597..7e10c24e 100644 --- a/source/Core/BSP/Pine64/postRTOS.cpp +++ b/source/Core/BSP/Pine64/postRTOS.cpp @@ -5,7 +5,6 @@ #include "Settings.h" #include "Si7210.h" #include "cmsis_os.h" -#include "fusbpd.h" #include "main.hpp" #include "power.hpp" #include "stdlib.h" diff --git a/source/Core/BSP/Pine64/preRTOS.cpp b/source/Core/BSP/Pine64/preRTOS.cpp index 743a9de8..4a013b80 100644 --- a/source/Core/BSP/Pine64/preRTOS.cpp +++ b/source/Core/BSP/Pine64/preRTOS.cpp @@ -14,9 +14,8 @@ void preRToSInit() { // Normal system bringup -- GPIO etc
hardware_init();
- delay_ms(5);
gpio_bit_reset(OLED_RESET_GPIO_Port, OLED_RESET_Pin);
- delay_ms(50);
+ delay_ms(5);
gpio_bit_set(OLED_RESET_GPIO_Port, OLED_RESET_Pin);
FRToSI2C::FRToSInit();
}
diff --git a/source/Core/Drivers/FUSB302/fusb302b.cpp b/source/Core/Drivers/FUSB302/fusb302b.cpp deleted file mode 100644 index 83bab9c7..00000000 --- a/source/Core/Drivers/FUSB302/fusb302b.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* - * PD Buddy Firmware Library - USB Power Delivery for everyone - * Copyright 2017-2018 Clayton G. Hobbs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "fusb302b.h" -#include "BSP.h" -#include "I2C_Wrapper.hpp" -#include "Setup.h" -#include "fusb_user.h" -#include "int_n.h" -#include <pd.h> -uint8_t fusb_read_byte(uint8_t addr); -bool fusb_write_byte(uint8_t addr, uint8_t byte); -void fusb_send_message(const union pd_msg *msg) { - - /* Token sequences for the FUSB302B */ - static uint8_t sop_seq[5] = {FUSB_FIFO_TX_SOP1, FUSB_FIFO_TX_SOP1, FUSB_FIFO_TX_SOP1, FUSB_FIFO_TX_SOP2, FUSB_FIFO_TX_PACKSYM}; - static const uint8_t eop_seq[4] = {FUSB_FIFO_TX_JAM_CRC, FUSB_FIFO_TX_EOP, FUSB_FIFO_TX_TXOFF, FUSB_FIFO_TX_TXON}; - - /* Take the I2C2 mutex now so there can't be a race condition on sop_seq */ - /* Get the length of the message: a two-octet header plus NUMOBJ four-octet - * data objects */ - uint8_t msg_len = 2 + 4 * PD_NUMOBJ_GET(msg); - - /* Set the number of bytes to be transmitted in the packet */ - sop_seq[4] = FUSB_FIFO_TX_PACKSYM | msg_len; - - /* Write all three parts of the message to the TX FIFO */ - fusb_write_buf(FUSB_FIFOS, 5, sop_seq); - fusb_write_buf(FUSB_FIFOS, msg_len, msg->bytes); - fusb_write_buf(FUSB_FIFOS, 4, eop_seq); -} - -bool fusb_rx_pending() { return (fusb_read_byte(FUSB_STATUS1) & FUSB_STATUS1_RX_EMPTY) != FUSB_STATUS1_RX_EMPTY; } - -uint8_t fusb_read_message(union pd_msg *msg) { - - static uint8_t garbage[4]; - uint8_t numobj; - - // Read the header. If its not a SOP we dont actually want it at all - // But on some revisions of the fusb if you dont both pick them up and read them out of the fifo, it gets stuck - if ((fusb_read_byte(FUSB_FIFOS) & FUSB_FIFO_RX_TOKEN_BITS) != FUSB_FIFO_RX_SOP) { - return 1; - } - - // fusb_read_byte(FUSB_FIFOS); - /* Read the message header into msg */ - fusb_read_buf(FUSB_FIFOS, 2, msg->bytes); - /* Get the number of data objects */ - numobj = PD_NUMOBJ_GET(msg); - /* If there is at least one data object, read the data objects */ - if (numobj > 0) { - fusb_read_buf(FUSB_FIFOS, numobj * 4, msg->bytes + 2); - } - /* Throw the CRC32 in the garbage, since the PHY already checked it. */ - fusb_read_buf(FUSB_FIFOS, 4, garbage); - - return 0; -} - -void fusb_send_hardrst() { - - /* Send a hard reset */ - fusb_write_byte(FUSB_CONTROL3, 0x07 | FUSB_CONTROL3_SEND_HARD_RESET); -} - -bool fusb_setup() { - /* Fully reset the FUSB302B */ - fusb_write_byte(FUSB_RESET, FUSB_RESET_SW_RES); - vTaskDelay(TICKS_10MS); - uint8_t tries = 0; - while (!fusb_read_id()) { - vTaskDelay(TICKS_10MS); - tries++; - if (tries > 5) { - return false; // Welp :( - } - } - - /* Turn on all power */ - fusb_write_byte(FUSB_POWER, 0x0F); - - /* Set interrupt masks */ - // Setting to 0 so interrupts are allowed - fusb_write_byte(FUSB_MASK1, 0x00); - fusb_write_byte(FUSB_MASKA, 0x00); - fusb_write_byte(FUSB_MASKB, 0x00); - fusb_write_byte(FUSB_CONTROL0, 0b11 << 2); - - /* Enable automatic retransmission */ - fusb_write_byte(FUSB_CONTROL3, 0x07); - // set defaults - fusb_write_byte(FUSB_CONTROL2, 0x00); - /* Flush the RX buffer */ - fusb_write_byte(FUSB_CONTROL1, FUSB_CONTROL1_RX_FLUSH); - - /* Measure CC1 */ - fusb_write_byte(FUSB_SWITCHES0, 0x07); - vTaskDelay(TICKS_10MS); - uint8_t cc1 = fusb_read_byte(FUSB_STATUS0) & FUSB_STATUS0_BC_LVL; - - /* Measure CC2 */ - fusb_write_byte(FUSB_SWITCHES0, 0x0B); - vTaskDelay(TICKS_10MS); - uint8_t cc2 = fusb_read_byte(FUSB_STATUS0) & FUSB_STATUS0_BC_LVL; - - /* Select the correct CC line for BMC signaling; also enable AUTO_CRC */ - if (cc1 > cc2) { - fusb_write_byte(FUSB_SWITCHES1, 0x25); // TX_CC1|AUTO_CRC|SPECREV0 - fusb_write_byte(FUSB_SWITCHES0, 0x07); // PWDN1|PWDN2|MEAS_CC1 - } else { - fusb_write_byte(FUSB_SWITCHES1, 0x26); // TX_CC2|AUTO_CRC|SPECREV0 - fusb_write_byte(FUSB_SWITCHES0, 0x0B); // PWDN1|PWDN2|MEAS_CC2 - } - - fusb_reset(); - setupFUSBIRQ(); - return true; -} - -bool fusb_get_status(union fusb_status *status) { - - /* Read the interrupt and status flags into status */ - return fusb_read_buf(FUSB_STATUS0A, 7, status->bytes); -} - -enum fusb_typec_current fusb_get_typec_current() { - - /* Read the BC_LVL into a variable */ - enum fusb_typec_current bc_lvl = (enum fusb_typec_current)(fusb_read_byte(FUSB_STATUS0) & FUSB_STATUS0_BC_LVL); - - return bc_lvl; -} - -void fusb_reset() { - - /* Flush the TX buffer */ - fusb_write_byte(FUSB_CONTROL0, 0x44); - /* Flush the RX buffer */ - fusb_write_byte(FUSB_CONTROL1, FUSB_CONTROL1_RX_FLUSH); - /* Reset the PD logic */ - fusb_write_byte(FUSB_RESET, FUSB_RESET_PD_RESET); -} - -bool fusb_read_id() { - // Return true if read of the revision ID is sane - uint8_t version = 0; - fusb_read_buf(FUSB_DEVICE_ID, 1, &version); - if (version == 0 || version == 0xFF) - return false; - return true; -} -/* - * Read a single byte from the FUSB302B - * - * cfg: The FUSB302B to communicate with - * addr: The memory address from which to read - * - * Returns the value read from addr. - */ -uint8_t fusb_read_byte(uint8_t addr) { - uint8_t data[1]; - if (!fusb_read_buf(addr, 1, (uint8_t *)data)) { - return 0; - } - return data[0]; -} - -/* - * Write a single byte to the FUSB302B - * - * cfg: The FUSB302B to communicate with - * addr: The memory address to which we will write - * byte: The value to write - */ -bool fusb_write_byte(uint8_t addr, uint8_t byte) { return fusb_write_buf(addr, 1, (uint8_t *)&byte); } diff --git a/source/Core/Drivers/FUSB302/fusb302b.h b/source/Core/Drivers/FUSB302/fusb302b.h deleted file mode 100644 index 72736250..00000000 --- a/source/Core/Drivers/FUSB302/fusb302b.h +++ /dev/null @@ -1,305 +0,0 @@ -/* - * PD Buddy Firmware Library - USB Power Delivery for everyone - * Copyright 2017-2018 Clayton G. Hobbs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PDB_FUSB302B_H -#define PDB_FUSB302B_H - -#include <stdint.h> - -#include "pd.h" -#include <pdb_msg.h> - -/* I2C addresses of the FUSB302B chips */ -#define FUSB302B_ADDR (0x22 << 1) -#define FUSB302B01_ADDR (0x23 << 1) -#define FUSB302B10_ADDR (0x24 << 1) -#define FUSB302B11_ADDR (0x25 << 1) - -/* Device ID register */ -#define FUSB_DEVICE_ID 0x01 -#define FUSB_DEVICE_ID_VERSION_ID_SHIFT 4 -#define FUSB_DEVICE_ID_VERSION_ID (0xF << FUSB_DEVICE_ID_VERSION_ID_SHIFT) -#define FUSB_DEVICE_ID_PRODUCT_ID_SHIFT 2 -#define FUSB_DEVICE_ID_PRODUCT_ID (0x3 << FUSB_DEVICE_ID_PRODUCT_ID_SHIFT) -#define FUSB_DEVICE_ID_REVISION_ID_SHIFT 0 -#define FUSB_DEVICE_ID_REVISION_ID (0x3 << FUSB_DEVICE_ID_REVISION_ID_SHIFT) - -/* Switches0 register */ -#define FUSB_SWITCHES0 0x02 -#define FUSB_SWITCHES0_PU_EN2 (1 << 7) -#define FUSB_SWITCHES0_PU_EN1 (1 << 6) -#define FUSB_SWITCHES0_VCONN_CC2 (1 << 5) -#define FUSB_SWITCHES0_VCONN_CC1 (1 << 4) -#define FUSB_SWITCHES0_MEAS_CC2 (1 << 3) -#define FUSB_SWITCHES0_MEAS_CC1 (1 << 2) -#define FUSB_SWITCHES0_PDWN_2 (1 << 1) -#define FUSB_SWITCHES0_PDWN_1 1 - -/* Switches1 register */ -#define FUSB_SWITCHES1 0x03 -#define FUSB_SWITCHES1_POWERROLE (1 << 7) -#define FUSB_SWITCHES1_SPECREV_SHIFT 5 -#define FUSB_SWITCHES1_SPECREV (0x3 << FUSB_SWITCHES1_SPECREV_SHIFT) -#define FUSB_SWITCHES1_DATAROLE (1 << 4) -#define FUSB_SWITCHES1_AUTO_CRC (1 << 2) -#define FUSB_SWITCHES1_TXCC2 (1 << 1) -#define FUSB_SWITCHES1_TXCC1 1 - -/* Measure register */ -#define FUSB_MEASURE 0x04 -#define FUSB_MEASURE_MEAS_VBUS (1 << 6) -#define FUSB_MEASURE_MDAC_SHIFT 0 -#define FUSB_MEASURE_MDAC (0x3F << FUSB_MEASURE_MDAC_SHIFT) - -/* Slice register */ -#define FUSB_SLICE 0x05 -#define FUSB_SLICE_SDAC_HYS_SHIFT 6 -#define FUSB_SLICE_SDAC_HYS (0x3 << FUSB_SLICE_SDAC_HYS_SHIFT) -#define FUSB_SLICE_SDAC_SHIFT 0 -#define FUSB_SLICE_SDAC (0x3F << FUSB_SLICE_SDAC_SHIFT) - -/* Control0 register */ -#define FUSB_CONTROL0 0x06 -#define FUSB_CONTROL0_TX_FLUSH (1 << 6) -#define FUSB_CONTROL0_INT_MASK (1 << 5) -#define FUSB_CONTROL0_HOST_CUR_SHIFT 2 -#define FUSB_CONTROL0_HOST_CUR (0x3 << FUSB_CONTROL0_HOST_CUR_SHIFT) -#define FUSB_CONTROL0_AUTO_PRE (1 << 1) -#define FUSB_CONTROL0_TX_START 1 - -/* Control1 register */ -#define FUSB_CONTROL1 0x07 -#define FUSB_CONTROL1_ENSOP2DB (1 << 6) -#define FUSB_CONTROL1_ENSOP1DB (1 << 5) -#define FUSB_CONTROL1_BIST_MODE2 (1 << 4) -#define FUSB_CONTROL1_RX_FLUSH (1 << 2) -#define FUSB_CONTROL1_ENSOP2 (1 << 1) -#define FUSB_CONTROL1_ENSOP1 1 - -/* Control2 register */ -#define FUSB_CONTROL2 0x08 -#define FUSB_CONTROL2_TOG_SAVE_PWR_SHIFT 6 -#define FUSB_CONTROL2_TOG_SAVE_PWR (0x3 << FUSB_CONTROL2_TOG_SAVE_PWR) -#define FUSB_CONTROL2_TOG_RD_ONLY (1 << 5) -#define FUSB_CONTROL2_WAKE_EN (1 << 3) -#define FUSB_CONTROL2_MODE_SHIFT 1 -#define FUSB_CONTROL2_MODE (0x3 << FUSB_CONTROL2_MODE_SHIFT) -#define FUSB_CONTROL2_TOGGLE 1 - -/* Control3 register */ -#define FUSB_CONTROL3 0x09 -#define FUSB_CONTROL3_SEND_HARD_RESET (1 << 6) -#define FUSB_CONTROL3_BIST_TMODE (1 << 5) -#define FUSB_CONTROL3_AUTO_HARDRESET (1 << 4) -#define FUSB_CONTROL3_AUTO_SOFTRESET (1 << 3) -#define FUSB_CONTROL3_N_RETRIES_SHIFT 1 -#define FUSB_CONTROL3_N_RETRIES (0x3 << FUSB_CONTROL3_N_RETRIES_SHIFT) -#define FUSB_CONTROL3_AUTO_RETRY 1 - -/* Mask1 register */ -#define FUSB_MASK1 0x0A -#define FUSB_MASK1_M_VBUSOK (1 << 7) -#define FUSB_MASK1_M_ACTIVITY (1 << 6) -#define FUSB_MASK1_M_COMP_CHNG (1 << 5) -#define FUSB_MASK1_M_CRC_CHK (1 << 4) -#define FUSB_MASK1_M_ALERT (1 << 3) -#define FUSB_MASK1_M_WAKE (1 << 2) -#define FUSB_MASK1_M_COLLISION (1 << 1) -#define FUSB_MASK1_M_BC_LVL (1 << 0) - -/* Power register */ -#define FUSB_POWER 0x0B -#define FUSB_POWER_PWR3 (1 << 3) -#define FUSB_POWER_PWR2 (1 << 2) -#define FUSB_POWER_PWR1 (1 << 1) -#define FUSB_POWER_PWR0 1 - -/* Reset register */ -#define FUSB_RESET 0x0C -#define FUSB_RESET_PD_RESET (1 << 1) -#define FUSB_RESET_SW_RES 1 - -/* OCPreg register */ -#define FUSB_OCPREG 0x0D -#define FUSB_OCPREG_OCP_RANGE (1 << 3) -#define FUSB_OCPREG_OCP_CUR_SHIFT 0 -#define FUSB_OCPREG_OCP_CUR (0x7 << FUSB_OCPREG_OCP_CUR_SHIFT) - -/* Maska register */ -#define FUSB_MASKA 0x0E -#define FUSB_MASKA_M_OCP_TEMP (1 << 7) -#define FUSB_MASKA_M_TOGDONE (1 << 6) -#define FUSB_MASKA_M_SOFTFAIL (1 << 5) -#define FUSB_MASKA_M_RETRYFAIL (1 << 4) -#define FUSB_MASKA_M_HARDSENT (1 << 3) -#define FUSB_MASKA_M_TXSENT (1 << 2) -#define FUSB_MASKA_M_SOFTRST (1 << 1) -#define FUSB_MASKA_M_HARDRST 1 - -/* Maskb register */ -#define FUSB_MASKB 0x0F -#define FUSB_MASKB_M_GCRCSENT 1 - -/* Control4 register */ -#define FUSB_CONTROL4 0x10 -#define FUSB_CONTROL4_TOG_EXIT_AUD 1 - -/* Status0a register */ -#define FUSB_STATUS0A 0x3C -#define FUSB_STATUS0A_SOFTFAIL (1 << 5) -#define FUSB_STATUS0A_RETRYFAIL (1 << 4) -#define FUSB_STATUS0A_POWER3 (1 << 3) -#define FUSB_STATUS0A_POWER2 (1 << 2) -#define FUSB_STATUS0A_SOFTRST (1 << 1) -#define FUSB_STATUS0A_HARDRST 1 - -/* Status1a register */ -#define FUSB_STATUS1A 0x3D -#define FUSB_STATUS1A_TOGSS_SHIFT 3 -#define FUSB_STATUS1A_TOGSS (0x7 << FUSB_STATUS1A_TOGSS_SHIFT) -#define FUSB_STATUS1A_RXSOP2DB (1 << 2) -#define FUSB_STATUS1A_RXSOP1DB (1 << 1) -#define FUSB_STATUS1A_RXSOP 1 - -/* Interrupta register */ -#define FUSB_INTERRUPTA 0x3E -#define FUSB_INTERRUPTA_I_OCP_TEMP (1 << 7) -#define FUSB_INTERRUPTA_I_TOGDONE (1 << 6) -#define FUSB_INTERRUPTA_I_SOFTFAIL (1 << 5) -#define FUSB_INTERRUPTA_I_RETRYFAIL (1 << 4) -#define FUSB_INTERRUPTA_I_HARDSENT (1 << 3) -#define FUSB_INTERRUPTA_I_TXSENT (1 << 2) -#define FUSB_INTERRUPTA_I_SOFTRST (1 << 1) -#define FUSB_INTERRUPTA_I_HARDRST 1 - -/* Interruptb register */ -#define FUSB_INTERRUPTB 0x3F -#define FUSB_INTERRUPTB_I_GCRCSENT 1 - -/* Status0 register */ -#define FUSB_STATUS0 0x40 -#define FUSB_STATUS0_VBUSOK (1 << 7) -#define FUSB_STATUS0_ACTIVITY (1 << 6) -#define FUSB_STATUS0_COMP (1 << 5) -#define FUSB_STATUS0_CRC_CHK (1 << 4) -#define FUSB_STATUS0_ALERT (1 << 3) -#define FUSB_STATUS0_WAKE (1 << 2) -#define FUSB_STATUS0_BC_LVL_SHIFT 0 -#define FUSB_STATUS0_BC_LVL (0x3 << FUSB_STATUS0_BC_LVL_SHIFT) - -/* Status1 register */ -#define FUSB_STATUS1 0x41 -#define FUSB_STATUS1_RXSOP2 (1 << 7) -#define FUSB_STATUS1_RXSOP1 (1 << 6) -#define FUSB_STATUS1_RX_EMPTY (1 << 5) -#define FUSB_STATUS1_RX_FULL (1 << 4) -#define FUSB_STATUS1_TX_EMPTY (1 << 3) -#define FUSB_STATUS1_TX_FULL (1 << 2) -#define FUSB_STATUS1_OVRTEMP (1 << 1) -#define FUSB_STATUS1_OCP 1 - -/* Interrupt register */ -#define FUSB_INTERRUPT 0x42 -#define FUSB_INTERRUPT_I_VBUSOK (1 << 7) -#define FUSB_INTERRUPT_I_ACTIVITY (1 << 6) -#define FUSB_INTERRUPT_I_COMP_CHNG (1 << 5) -#define FUSB_INTERRUPT_I_CRC_CHK (1 << 4) -#define FUSB_INTERRUPT_I_ALERT (1 << 3) -#define FUSB_INTERRUPT_I_WAKE (1 << 2) -#define FUSB_INTERRUPT_I_COLLISION (1 << 1) -#define FUSB_INTERRUPT_I_BC_LVL 1 - -/* FIFOs register */ -#define FUSB_FIFOS 0x43 - -#define FUSB_FIFO_TX_TXON 0xA1 -#define FUSB_FIFO_TX_SOP1 0x12 -#define FUSB_FIFO_TX_SOP2 0x13 -#define FUSB_FIFO_TX_SOP3 0x1B -#define FUSB_FIFO_TX_RESET1 0x15 -#define FUSB_FIFO_TX_RESET2 0x16 -#define FUSB_FIFO_TX_PACKSYM 0x80 -#define FUSB_FIFO_TX_JAM_CRC 0xFF -#define FUSB_FIFO_TX_EOP 0x14 -#define FUSB_FIFO_TX_TXOFF 0xFE - -#define FUSB_FIFO_RX_TOKEN_BITS 0xE0 -#define FUSB_FIFO_RX_SOP 0xE0 -#define FUSB_FIFO_RX_SOP1 0xC0 -#define FUSB_FIFO_RX_SOP2 0xA0 -#define FUSB_FIFO_RX_SOP1DB 0x80 -#define FUSB_FIFO_RX_SOP2DB 0x60 - -/* - * FUSB status union - * - * Provides a nicer structure than just an array of uint8_t for working with - * the FUSB302B status and interrupt flags. - */ -union fusb_status { - uint8_t bytes[7]; - struct { - uint8_t status0a; - uint8_t status1a; - uint8_t interrupta; - uint8_t interruptb; - uint8_t status0; - uint8_t status1; - uint8_t interrupt; - }; -}; - -/* FUSB functions */ - -/* - * Send a USB Power Delivery message to the FUSB302B - */ -void fusb_send_message(const union pd_msg *msg); -bool fusb_rx_pending(); -/* - * Read a USB Power Delivery message from the FUSB302B - */ -uint8_t fusb_read_message(union pd_msg *msg); - -/* - * Tell the FUSB302B to send a hard reset signal - */ -void fusb_send_hardrst(); - -/* - * Read the FUSB302B status and interrupt flags into *status - */ -bool fusb_get_status(union fusb_status *status); - -/* - * Read the FUSB302B BC_LVL as an enum fusb_typec_current - */ -enum fusb_typec_current fusb_get_typec_current(); - -/* - * Initialization routine for the FUSB302B - */ -bool fusb_setup(); - -/* - * Reset the FUSB302B - */ -void fusb_reset(); - -bool fusb_read_id(); - -#endif /* PDB_FUSB302B_H */ diff --git a/source/Core/Drivers/FUSB302/fusb_user.h b/source/Core/Drivers/FUSB302/fusb_user.h deleted file mode 100644 index 55a27ebf..00000000 --- a/source/Core/Drivers/FUSB302/fusb_user.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * PD Buddy Firmware Library - USB Power Delivery for everyone - * Copyright 2017-2018 Clayton G. Hobbs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PDB_FUSB_USER_H -#define PDB_FUSB_USER_H - -#include <stdint.h> -/* - * Read multiple bytes from the FUSB302B - * - * cfg: The FUSB302B to communicate with - * addr: The memory address from which to read - * size: The number of bytes to read - * buf: The buffer into which data will be read - */ -bool fusb_read_buf(uint8_t addr, uint8_t size, uint8_t *buf); -/* - * Write multiple bytes to the FUSB302B - * - * cfg: The FUSB302B to communicate with - * addr: The memory address to which we will write - * size: The number of bytes to write - * buf: The buffer to write - */ -bool fusb_write_buf(uint8_t addr, uint8_t size, const uint8_t *buf); -// Used to poll for the device existing on the I2C bus. This should return non-zero if the device is responding on the bus -bool fusb302_detect(); -// Once this is called IRQ's should be enabled and routed to the IRQ handler thread -void setupFUSBIRQ(); -// This should return true if the IRQ line for the FUSB302 is still held low -bool getFUS302IRQLow(); - -#endif /* PDB_FUSB302B_H */ diff --git a/source/Core/Drivers/FUSB302/fusbpd.cpp b/source/Core/Drivers/FUSB302/fusbpd.cpp deleted file mode 100644 index 18920c03..00000000 --- a/source/Core/Drivers/FUSB302/fusbpd.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/*
- * fusbpd.cpp
- *
- * Created on: 13 Jun 2020
- * Author: Ralim
- */
-#include "configuration.h"
-#ifdef POW_PD
-#include "BSP.h"
-#include "I2CBB.hpp"
-#include "fusb302b.h"
-#include "int_n.h"
-#include "policy_engine.h"
-
-#include <fusbpd.h>
-#include <pd.h>
-
-void fusb302_start_processing() {
- /* Initialize the FUSB302B */
- if (fusb_setup()) {
- PolicyEngine::init();
- InterruptHandler::init();
- }
-}
-#endif
diff --git a/source/Core/Drivers/FUSB302/fusbpd.h b/source/Core/Drivers/FUSB302/fusbpd.h deleted file mode 100644 index 1f3a80fb..00000000 --- a/source/Core/Drivers/FUSB302/fusbpd.h +++ /dev/null @@ -1,15 +0,0 @@ -/*
- * fusbpd.h
- *
- * Created on: 13 Jun 2020
- * Author: Ralim
- */
-
-#ifndef DRIVERS_FUSB302_FUSBPD_H_
-#define DRIVERS_FUSB302_FUSBPD_H_
-// Wrapper for all of the FUSB302 PD work
-extern struct pdb_config pdb_config_data;
-#include <stdint.h>
-
-void fusb302_start_processing();
-#endif /* DRIVERS_FUSB302_FUSBPD_H_ */
diff --git a/source/Core/Drivers/FUSB302/int_n.cpp b/source/Core/Drivers/FUSB302/int_n.cpp deleted file mode 100644 index 7c00b651..00000000 --- a/source/Core/Drivers/FUSB302/int_n.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - * PD Buddy Firmware Library - USB Power Delivery for everyone - * Copyright 2017-2018 Clayton G. Hobbs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "int_n.h" -#include "Defines.h" -#include "fusb302b.h" -#include "fusb_user.h" -#include "fusbpd.h" -#include "policy_engine.h" -#include "task.h" -#include <pd.h> -#include <string.h> - -volatile osThreadId InterruptHandler::TaskHandle = NULL; -uint32_t InterruptHandler::TaskBuffer[InterruptHandler::TaskStackSize]; -osStaticThreadDef_t InterruptHandler::TaskControlBlock; -union pd_msg InterruptHandler::tempMessage; - -void InterruptHandler::init() { - TaskHandle = NULL; - osThreadStaticDef(intTask, Thread, PDB_PRIO_PRL_INT_N, 0, TaskStackSize, TaskBuffer, &TaskControlBlock); - TaskHandle = osThreadCreate(osThread(intTask), NULL); -} -volatile uint32_t msgCounter = 0; -volatile uint32_t msgCounter1 = 0; -void InterruptHandler::readPendingMessage() { - memset(&tempMessage, 0, sizeof(tempMessage)); - while (fusb_rx_pending()) { - msgCounter++; - /* Read the message */ - if (fusb_read_message(&tempMessage) == 0) { - /* If it's a Soft_Reset, go to the soft reset state */ - if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_SOFT_RESET && PD_NUMOBJ_GET(&tempMessage) == 0) { - /* TX transitions to its reset state */ - PolicyEngine::notify(PolicyEngine::Notifications::PDB_EVT_PE_RESET); - } else { - /* Tell PolicyEngine to discard the message being transmitted */ - PolicyEngine::notify(PolicyEngine::Notifications::PDB_EVT_TX_DISCARD); - - /* Pass the message to the policy engine. */ - PolicyEngine::handleMessage(&tempMessage); - } - } else { - msgCounter1++; - } - } -} - -void InterruptHandler::Thread(const void *arg) { - (void)arg; - union fusb_status status; - for (;;) { - // If the irq is low continue, otherwise wait for irq or timeout - if (!getFUS302IRQLow()) { - xTaskNotifyWait(0x00, 0x0F, NULL, TICKS_SECOND * 30); - } - /* Read the FUSB302B status and interrupt registers */ - if (fusb_get_status(&status)) { - - /* If the I_GCRCSENT flag is set, tell the Protocol RX thread */ - // This means a message was received with a good CRC - if (status.interruptb & FUSB_INTERRUPTB_I_GCRCSENT) { - readPendingMessage(); - } - - /* If the I_TXSENT or I_RETRYFAIL flag is set, tell the Protocol TX - * thread */ - if (status.interrupta & FUSB_INTERRUPTA_I_TXSENT) { - PolicyEngine::notify(PolicyEngine::Notifications::PDB_EVT_TX_I_TXSENT); - } - if (status.interrupta & FUSB_INTERRUPTA_I_RETRYFAIL) { - PolicyEngine::notify(PolicyEngine::Notifications::PDB_EVT_TX_I_RETRYFAIL); - } - - /* If the I_OCP_TEMP and OVRTEMP flags are set, tell the Policy - * Engine thread */ - if ((status.interrupta & FUSB_INTERRUPTA_I_OCP_TEMP) && (status.status1 & FUSB_STATUS1_OVRTEMP)) { - PolicyEngine::notify(PolicyEngine::Notifications::PDB_EVT_PE_I_OVRTEMP); - } - } - } -} -void InterruptHandler::irqCallback() { - if (TaskHandle != NULL) { - BaseType_t taskWoke = pdFALSE; - xTaskNotifyFromISR(TaskHandle, 0x01, eNotifyAction::eSetBits, &taskWoke); - portYIELD_FROM_ISR(taskWoke); - } -} diff --git a/source/Core/Drivers/FUSB302/int_n.h b/source/Core/Drivers/FUSB302/int_n.h deleted file mode 100644 index ed18b50d..00000000 --- a/source/Core/Drivers/FUSB302/int_n.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * PD Buddy Firmware Library - USB Power Delivery for everyone - * Copyright 2017-2018 Clayton G. Hobbs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PDB_INT_N_OLD_H -#define PDB_INT_N_OLD_H - -#include <pd.h> - -class InterruptHandler { -public: - // Creates the thread to handle the Interrupt pin - static void init(); - - static void irqCallback(); - -private: - static void Thread(const void *arg); - static volatile osThreadId TaskHandle; - static const size_t TaskStackSize = 1536 / 3; - static uint32_t TaskBuffer[TaskStackSize]; - static osStaticThreadDef_t TaskControlBlock; - /* - * Hard Reset machine states - */ - enum hardrst_state { PRLHRResetLayer, PRLHRIndicateHardReset, PRLHRRequestHardReset, PRLHRWaitPHY, PRLHRHardResetRequested, PRLHRWaitPE, PRLHRComplete }; - static enum hardrst_state hardrst_reset_layer(); - static enum hardrst_state hardrst_indicate_hard_reset(); - static enum hardrst_state hardrst_request_hard_reset(); - static enum hardrst_state hardrst_wait_phy(); - static enum hardrst_state hardrst_hard_reset_requested(); - static enum hardrst_state hardrst_wait_pe(); - static enum hardrst_state hardrst_complete(); - // Mesage rx - static void readPendingMessage(); - static union pd_msg tempMessage; -}; - -#endif /* PDB_INT_N_OLD_H */ diff --git a/source/Core/Drivers/FUSB302/pd.h b/source/Core/Drivers/FUSB302/pd.h deleted file mode 100644 index bdf3fa36..00000000 --- a/source/Core/Drivers/FUSB302/pd.h +++ /dev/null @@ -1,388 +0,0 @@ -/* - * PD Buddy Firmware Library - USB Power Delivery for everyone - * Copyright 2017-2018 Clayton G. Hobbs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PDB_PD_H -#define PDB_PD_H - -#include "FreeRTOS.h" -#include "cmsis_os.h" -#include "pdb_conf.h" -#include "pdb_msg.h" -#include <stdint.h> -/* - * Macros for working with USB Power Delivery messages. - * - * This file is mostly written from the PD Rev. 2.0 spec, but the header is - * written from the Rev. 3.0 spec. - */ - -/* - * PD Header - */ -#define PD_HDR_MSGTYPE_SHIFT 0 -#define PD_HDR_MSGTYPE (0x1F << PD_HDR_MSGTYPE_SHIFT) -#define PD_HDR_DATAROLE_SHIFT 5 -#define PD_HDR_DATAROLE (0x1 << PD_HDR_DATAROLE_SHIFT) -#define PD_HDR_SPECREV_SHIFT 6 -#define PD_HDR_SPECREV (0x3 << PD_HDR_SPECREV_SHIFT) -#define PD_HDR_POWERROLE_SHIFT 8 -#define PD_HDR_POWERROLE (1 << PD_HDR_POWERROLE_SHIFT) -#define PD_HDR_MESSAGEID_SHIFT 9 -#define PD_HDR_MESSAGEID (0x7 << PD_HDR_MESSAGEID_SHIFT) -#define PD_HDR_NUMOBJ_SHIFT 12 -#define PD_HDR_NUMOBJ (0x7 << PD_HDR_NUMOBJ_SHIFT) -#define PD_HDR_EXT (1 << 15) - -/* Message types */ -#define PD_MSGTYPE_GET(msg) (((msg)->hdr & PD_HDR_MSGTYPE) >> PD_HDR_MSGTYPE_SHIFT) -/* Control Message */ -#define PD_MSGTYPE_GOODCRC 0x01 -#define PD_MSGTYPE_GOTOMIN 0x02 -#define PD_MSGTYPE_ACCEPT 0x03 -#define PD_MSGTYPE_REJECT 0x04 -#define PD_MSGTYPE_PING 0x05 -#define PD_MSGTYPE_PS_RDY 0x06 -#define PD_MSGTYPE_GET_SOURCE_CAP 0x07 -#define PD_MSGTYPE_GET_SINK_CAP 0x08 -#define PD_MSGTYPE_DR_SWAP 0x09 -#define PD_MSGTYPE_PR_SWAP 0x0A -#define PD_MSGTYPE_VCONN_SWAP 0x0B -#define PD_MSGTYPE_WAIT 0x0C -#define PD_MSGTYPE_SOFT_RESET 0x0D -#define PD_MSGTYPE_NOT_SUPPORTED 0x10 -#define PD_MSGTYPE_GET_SOURCE_CAP_EXTENDED 0x11 -#define PD_MSGTYPE_GET_STATUS 0x12 -#define PD_MSGTYPE_FR_SWAP 0x13 -#define PD_MSGTYPE_GET_PPS_STATUS 0x14 -#define PD_MSGTYPE_GET_COUNTRY_CODES 0x15 -/* Data Message */ -#define PD_MSGTYPE_SOURCE_CAPABILITIES 0x01 -#define PD_MSGTYPE_REQUEST 0x02 -#define PD_MSGTYPE_BIST 0x03 -#define PD_MSGTYPE_SINK_CAPABILITIES 0x04 -#define PD_MSGTYPE_BATTERY_STATUS 0x05 -#define PD_MSGTYPE_ALERT 0x06 -#define PD_MSGTYPE_GET_COUNTRY_INFO 0x07 -#define PD_MSGTYPE_VENDOR_DEFINED 0x0F -/* Extended Message */ -#define PD_MSGTYPE_SOURCE_CAPABILITIES_EXTENDED 0x01 -#define PD_MSGTYPE_STATUS 0x02 -#define PD_MSGTYPE_GET_BATTERY_CAP 0x03 -#define PD_MSGTYPE_GET_BATTERY_STATUS 0x04 -#define PD_MSGTYPE_BATTERY_CAPABILITIES 0x05 -#define PD_MSGTYPE_GET_MANUFACTURER_INFO 0x06 -#define PD_MSGTYPE_MANUFACTURER_INFO 0x07 -#define PD_MSGTYPE_SECURITY_REQUEST 0x08 -#define PD_MSGTYPE_SECURITY_RESPONSE 0x09 -#define PD_MSGTYPE_FIRMWARE_UPDATE_REQUEST 0x0A -#define PD_MSGTYPE_FIRMWARE_UPDATE_RESPONSE 0x0B -#define PD_MSGTYPE_PPS_STATUS 0x0C -#define PD_MSGTYPE_COUNTRY_INFO 0x0D -#define PD_MSGTYPE_COUNTRY_CODES 0x0E - -/* Data roles */ -#define PD_DATAROLE_UFP (0x0 << PD_HDR_DATAROLE_SHIFT) -#define PD_DATAROLE_DFP (0x1 << PD_HDR_DATAROLE_SHIFT) - -/* Specification revisions */ -#define PD_SPECREV_1_0 (0x0 << PD_HDR_SPECREV_SHIFT) -#define PD_SPECREV_2_0 (0x1 << PD_HDR_SPECREV_SHIFT) -#define PD_SPECREV_3_0 (0x2 << PD_HDR_SPECREV_SHIFT) - -/* Port power roles */ -#define PD_POWERROLE_SINK (0x0 << PD_HDR_POWERROLE_SHIFT) -#define PD_POWERROLE_SOURCE (0x1 << PD_HDR_POWERROLE_SHIFT) - -/* Message ID */ -#define PD_MESSAGEID_GET(msg) (((msg)->hdr & PD_HDR_MESSAGEID) >> PD_HDR_MESSAGEID_SHIFT) - -/* Number of data objects */ -#define PD_NUMOBJ(n) (((n) << PD_HDR_NUMOBJ_SHIFT) & PD_HDR_NUMOBJ) -#define PD_NUMOBJ_GET(msg) (((msg)->hdr & PD_HDR_NUMOBJ) >> PD_HDR_NUMOBJ_SHIFT) - -/* - * PD Extended Message Header - */ -#define PD_EXTHDR_DATA_SIZE_SHIFT 0 -#define PD_EXTHDR_DATA_SIZE (0x1FF << PD_EXTHDR_DATA_SIZE_SHIFT) -#define PD_EXTHDR_REQUEST_CHUNK_SHIFT 10 -#define PD_EXTHDR_REQUEST_CHUNK (1 << PD_EXTHDR_REQUEST_CHUNK_SHIFT) -#define PD_EXTHDR_CHUNK_NUMBER_SHIFT 11 -#define PD_EXTHDR_CHUNK_NUMBER (0xF << PD_EXTHDR_CHUNK_NUMBER_SHIFT) -#define PD_EXTHDR_CHUNKED_SHIFT 15 -#define PD_EXTHDR_CHUNKED (1 << PD_EXTHDR_CHUNKED_SHIFT) - -/* Data size */ -#define PD_DATA_SIZE(n) (((n) << PD_EXTHDR_DATA_SIZE_SHIFT) & PD_EXTHDR_DATA_SIZE) -#define PD_DATA_SIZE_GET(msg) (((msg)->exthdr & PD_EXTHDR_DATA_SIZE) >> PD_EXTHDR_DATA_SIZE_SHIFT) - -/* Chunk number */ -#define PD_CHUNK_NUMBER(n) (((n) << PD_EXTHDR_CHUNK_NUMBER_SHIFT) & PD_EXTHDR_CHUNK_NUMBER) -#define PD_CHUNK_NUMBER_GET(msg) (((msg)->exthdr & PD_EXTHDR_CHUNK_NUMBER) >> PD_EXTHDR_CHUNK_NUMBER_SHIFT) - -/* - * PD Power Data Object - */ -#define PD_PDO_TYPE_SHIFT 30 -#define PD_PDO_TYPE (0x3 << PD_PDO_TYPE_SHIFT) - -/* PDO types */ -#define PD_PDO_TYPE_FIXED ((unsigned)(0x0 << PD_PDO_TYPE_SHIFT)) -#define PD_PDO_TYPE_BATTERY ((unsigned)(0x1 << PD_PDO_TYPE_SHIFT)) -#define PD_PDO_TYPE_VARIABLE ((unsigned)(0x2 << PD_PDO_TYPE_SHIFT)) -#define PD_PDO_TYPE_AUGMENTED ((unsigned)(0x3 << PD_PDO_TYPE_SHIFT)) - -#define PD_APDO_TYPE_SHIFT 28 -#define PD_APDO_TYPE (0x3 << PD_APDO_TYPE_SHIFT) - -/* APDO types */ -#define PD_APDO_TYPE_PPS (0x0 << PD_APDO_TYPE_SHIFT) - -/* PD Source Fixed PDO */ -#define PD_PDO_SRC_FIXED_DUAL_ROLE_PWR_SHIFT 29 -#define PD_PDO_SRC_FIXED_DUAL_ROLE_PWR (1 << PD_PDO_SRC_FIXED_DUAL_ROLE_PWR_SHIFT) -#define PD_PDO_SRC_FIXED_USB_SUSPEND_SHIFT 28 -#define PD_PDO_SRC_FIXED_USB_SUSPEND (1 << PD_PDO_SRC_FIXED_USB_SUSPEND_SHIFT) -#define PD_PDO_SRC_FIXED_UNCONSTRAINED_SHIFT 27 -#define PD_PDO_SRC_FIXED_UNCONSTRAINED (1 << PD_PDO_SRC_FIXED_UNCONSTRAINED_SHIFT) -#define PD_PDO_SRC_FIXED_USB_COMMS_SHIFT 26 -#define PD_PDO_SRC_FIXED_USB_COMMS (1 << PD_PDO_SRC_FIXED_USB_COMMS_SHIFT) -#define PD_PDO_SRC_FIXED_DUAL_ROLE_DATA_SHIFT 25 -#define PD_PDO_SRC_FIXED_DUAL_ROLE_DATA (1 << PD_PDO_SRC_FIXED_DUAL_ROLE_DATA_SHIFT) -#define PD_PDO_SRC_FIXED_UNCHUNKED_EXT_MSG_SHIFT 24 -#define PD_PDO_SRC_FIXED_UNCHUNKED_EXT_MSG (1 << PD_PDO_SRC_FIXED_UNCHUNKED_EXT_MSG_SHIFT) -#define PD_PDO_SRC_FIXED_PEAK_CURRENT_SHIFT 20 -#define PD_PDO_SRC_FIXED_PEAK_CURRENT (0x3 << PD_PDO_SRC_FIXED_PEAK_CURRENT_SHIFT) -#define PD_PDO_SRC_FIXED_VOLTAGE_SHIFT 10 -#define PD_PDO_SRC_FIXED_VOLTAGE (0x3FF << PD_PDO_SRC_FIXED_VOLTAGE_SHIFT) -#define PD_PDO_SRC_FIXED_CURRENT_SHIFT 0 -#define PD_PDO_SRC_FIXED_CURRENT (0x3FF << PD_PDO_SRC_FIXED_CURRENT_SHIFT) - -/* PD Source Fixed PDO current */ -#define PD_PDO_SRC_FIXED_CURRENT_GET(pdo) (((pdo)&PD_PDO_SRC_FIXED_CURRENT) >> PD_PDO_SRC_FIXED_CURRENT_SHIFT) - -/* PD Source Fixed PDO voltage */ -#define PD_PDO_SRC_FIXED_VOLTAGE_GET(pdo) (((pdo)&PD_PDO_SRC_FIXED_VOLTAGE) >> PD_PDO_SRC_FIXED_VOLTAGE_SHIFT) - -/* PD Programmable Power Supply APDO */ -#define PD_APDO_PPS_MAX_VOLTAGE_SHIFT 17 -#define PD_APDO_PPS_MAX_VOLTAGE (0xFF << PD_APDO_PPS_MAX_VOLTAGE_SHIFT) -#define PD_APDO_PPS_MIN_VOLTAGE_SHIFT 8 -#define PD_APDO_PPS_MIN_VOLTAGE (0xFF << PD_APDO_PPS_MIN_VOLTAGE_SHIFT) -#define PD_APDO_PPS_CURRENT_SHIFT 0 -#define PD_APDO_PPS_CURRENT (0x7F << PD_APDO_PPS_CURRENT_SHIFT) - -/* PD Programmable Power Supply APDO voltages */ -#define PD_APDO_PPS_MAX_VOLTAGE_GET(pdo) (((pdo)&PD_APDO_PPS_MAX_VOLTAGE) >> PD_APDO_PPS_MAX_VOLTAGE_SHIFT) -#define PD_APDO_PPS_MIN_VOLTAGE_GET(pdo) (((pdo)&PD_APDO_PPS_MIN_VOLTAGE) >> PD_APDO_PPS_MIN_VOLTAGE_SHIFT) - -#define PD_APDO_PPS_MAX_VOLTAGE_SET(v) (((v) << PD_APDO_PPS_MAX_VOLTAGE_SHIFT) & PD_APDO_PPS_MAX_VOLTAGE) -#define PD_APDO_PPS_MIN_VOLTAGE_SET(v) (((v) << PD_APDO_PPS_MIN_VOLTAGE_SHIFT) & PD_APDO_PPS_MIN_VOLTAGE) - -/* PD Programmable Power Supply APDO current */ -#define PD_APDO_PPS_CURRENT_GET(pdo) ((uint8_t)(((pdo)&PD_APDO_PPS_CURRENT) >> PD_APDO_PPS_CURRENT_SHIFT)) - -#define PD_APDO_PPS_CURRENT_SET(i) (((i) << PD_APDO_PPS_CURRENT_SHIFT) & PD_APDO_PPS_CURRENT) - -/* PD Sink Fixed PDO */ -#define PD_PDO_SNK_FIXED_DUAL_ROLE_PWR_SHIFT 29 -#define PD_PDO_SNK_FIXED_DUAL_ROLE_PWR (1 << PD_PDO_SNK_FIXED_DUAL_ROLE_PWR_SHIFT) -#define PD_PDO_SNK_FIXED_HIGHER_CAP_SHIFT 28 -#define PD_PDO_SNK_FIXED_HIGHER_CAP (1 << PD_PDO_SNK_FIXED_HIGHER_CAP_SHIFT) -#define PD_PDO_SNK_FIXED_UNCONSTRAINED_SHIFT 27 -#define PD_PDO_SNK_FIXED_UNCONSTRAINED (1 << PD_PDO_SNK_FIXED_UNCONSTRAINED_SHIFT) -#define PD_PDO_SNK_FIXED_USB_COMMS_SHIFT 26 -#define PD_PDO_SNK_FIXED_USB_COMMS (1 << PD_PDO_SNK_FIXED_USB_COMMS_SHIFT) -#define PD_PDO_SNK_FIXED_DUAL_ROLE_DATA_SHIFT 25 -#define PD_PDO_SNK_FIXED_DUAL_ROLE_DATA (1 << PD_PDO_SNK_FIXED_DUAL_ROLE_DATA_SHIFT) -#define PD_PDO_SNK_FIXED_VOLTAGE_SHIFT 10 -#define PD_PDO_SNK_FIXED_VOLTAGE (0x3FF << PD_PDO_SNK_FIXED_VOLTAGE_SHIFT) -#define PD_PDO_SNK_FIXED_CURRENT_SHIFT 0 -#define PD_PDO_SNK_FIXED_CURRENT (0x3FF << PD_PDO_SNK_FIXED_CURRENT_SHIFT) - -/* PD Sink Fixed PDO current */ -#define PD_PDO_SNK_FIXED_CURRENT_SET(i) (((i) << PD_PDO_SNK_FIXED_CURRENT_SHIFT) & PD_PDO_SNK_FIXED_CURRENT) - -/* PD Sink Fixed PDO voltage */ -#define PD_PDO_SNK_FIXED_VOLTAGE_SET(v) (((v) << PD_PDO_SNK_FIXED_VOLTAGE_SHIFT) & PD_PDO_SNK_FIXED_VOLTAGE) - -/* - * PD Request Data Object - */ -#define PD_RDO_OBJPOS_SHIFT 28 -#define PD_RDO_OBJPOS (0x7 << PD_RDO_OBJPOS_SHIFT) -#define PD_RDO_GIVEBACK_SHIFT 27 -#define PD_RDO_GIVEBACK (1 << PD_RDO_GIVEBACK_SHIFT) -#define PD_RDO_CAP_MISMATCH_SHIFT 26 -#define PD_RDO_CAP_MISMATCH (1 << PD_RDO_CAP_MISMATCH_SHIFT) -#define PD_RDO_USB_COMMS_SHIFT 25 -#define PD_RDO_USB_COMMS (1 << PD_RDO_USB_COMMS_SHIFT) -#define PD_RDO_NO_USB_SUSPEND_SHIFT 24 -#define PD_RDO_NO_USB_SUSPEND (1 << PD_RDO_NO_USB_SUSPEND_SHIFT) -#define PD_RDO_UNCHUNKED_EXT_MSG_SHIFT 23 -#define PD_RDO_UNCHUNKED_EXT_MSG (1 << PD_RDO_UNCHUNKED_EXT_MSG_SHIFT) - -#define PD_RDO_OBJPOS_SET(i) (((i) << PD_RDO_OBJPOS_SHIFT) & PD_RDO_OBJPOS) -#define PD_RDO_OBJPOS_GET(msg) (((msg)->obj[0] & PD_RDO_OBJPOS) >> PD_RDO_OBJPOS_SHIFT) - -/* Fixed and Variable RDO, no GiveBack support */ -#define PD_RDO_FV_CURRENT_SHIFT 10 -#define PD_RDO_FV_CURRENT (0x3FF << PD_RDO_FV_CURRENT_SHIFT) -#define PD_RDO_FV_MAX_CURRENT_SHIFT 0 -#define PD_RDO_FV_MAX_CURRENT (0x3FF << PD_RDO_FV_MAX_CURRENT_SHIFT) - -#define PD_RDO_FV_CURRENT_SET(i) (((i) << PD_RDO_FV_CURRENT_SHIFT) & PD_RDO_FV_CURRENT) -#define PD_RDO_FV_MAX_CURRENT_SET(i) (((i) << PD_RDO_FV_MAX_CURRENT_SHIFT) & PD_RDO_FV_MAX_CURRENT) - -/* Fixed and Variable RDO with GiveBack support */ -#define PD_RDO_FV_MIN_CURRENT_SHIFT 0 -#define PD_RDO_FV_MIN_CURRENT (0x3FF << PD_RDO_FV_MIN_CURRENT_SHIFT) - -#define PD_RDO_FV_MIN_CURRENT_SET(i) (((i) << PD_RDO_FV_MIN_CURRENT_SHIFT) & PD_RDO_FV_MIN_CURRENT) - -/* TODO: Battery RDOs */ - -/* Programmable RDO */ -#define PD_RDO_PROG_VOLTAGE_SHIFT 9 -#define PD_RDO_PROG_VOLTAGE (0x7FF << PD_RDO_PROG_VOLTAGE_SHIFT) -#define PD_RDO_PROG_CURRENT_SHIFT 0 -#define PD_RDO_PROG_CURRENT (0x7F << PD_RDO_PROG_CURRENT_SHIFT) - -#define PD_RDO_PROG_VOLTAGE_SET(i) (((i) << PD_RDO_PROG_VOLTAGE_SHIFT) & PD_RDO_PROG_VOLTAGE) -#define PD_RDO_PROG_CURRENT_SET(i) (((i) << PD_RDO_PROG_CURRENT_SHIFT) & PD_RDO_PROG_CURRENT) - -/* - * Time values - * - * Where a range is specified, the middle of the range (rounded down to the - * nearest millisecond) is used. - */ -#define PD_T_CHUNKING_NOT_SUPPORTED (TICKS_SECOND / 2) -#define PD_T_HARD_RESET_COMPLETE (1 * TICKS_SECOND) -#define PD_T_PS_TRANSITION (5 * TICKS_SECOND) -#define PD_T_SENDER_RESPONSE (27 * TICKS_100MS) -#define PD_T_SINK_REQUEST (1 * TICKS_SECOND) -#define PD_T_TYPEC_SINK_WAIT_CAP (1 * TICKS_SECOND) -#define PD_T_PD_DEBOUNCE (2 * TICKS_SECOND) - -/* - * Counter maximums - */ -#define PD_N_HARD_RESET_COUNT 2 - -/* - * Value parameters - */ -#define PD_MAX_EXT_MSG_LEN 260 -#define PD_MAX_EXT_MSG_CHUNK_LEN 26 -#define PD_MAX_EXT_MSG_LEGACY_LEN 26 - -/* - * Unit conversions - * - * V: volt - * CV: centivolt - * MV: millivolt - * PRV: Programmable RDO voltage unit (20 mV) - * PDV: Power Delivery voltage unit (50 mV) - * PAV: PPS APDO voltage unit (100 mV) - * - * A: ampere - * CA: centiampere - * MA: milliampere - * PDI: Power Delivery current unit (10 mA) - * PAI: PPS APDO current unit (50 mA) - * - * W: watt - * CW: centiwatt - * MW: milliwatt - * - * O: ohm - * CO: centiohm - * MO: milliohm - */ -#define PD_MV2PRV(mv) ((mv) / 20) -#define PD_MV2PDV(mv) ((mv) / 50) -#define PD_MV2PAV(mv) ((mv) / 100) -#define PD_PRV2MV(prv) ((prv)*20) -#define PD_PDV2MV(pdv) ((pdv)*50) -#define PD_PAV2MV(pav) ((pav)*100) - -#define PD_MA2CA(ma) (((ma) + 10 - 1) / 10) -#define PD_MA2PDI(ma) (((ma) + 10 - 1) / 10) -#define PD_MA2PAI(ma) (((ma) + 50 - 1) / 50) -#define PD_CA2PAI(ca) (((ca) + 5 - 1) / 5) -#define PD_PDI2MA(pdi) ((pdi)*10) -#define PD_PAI2MA(pai) ((pai)*50) -#define PD_PAI2CA(pai) ((pai)*5) - -#define PD_MW2CW(mw) ((mw) / 10) - -#define PD_MO2CO(mo) ((mo) / 10) - -/* Get portions of a voltage in more normal units */ -#define PD_MV_V(mv) ((mv) / 1000) -#define PD_MV_MV(mv) ((mv) % 1000) - -#define PD_PDV_V(pdv) ((pdv) / 20) -#define PD_PDV_CV(pdv) (5 * ((pdv) % 20)) - -#define PD_PAV_V(pav) ((pav) / 10) -#define PD_PAV_CV(pav) (10 * ((pav) % 10)) - -/* Get portions of a PD current in more normal units */ -#define PD_PDI_A(pdi) ((pdi) / 100) -#define PD_PDI_CA(pdi) ((pdi) % 100) - -#define PD_PAI_A(pai) ((pai) / 20) -#define PD_PAI_CA(pai) (5 * ((pai) % 20)) - -/* Get portions of a power in more normal units */ -#define PD_CW_W(cw) ((cw) / 100) -#define PD_CW_CW(cw) ((cw) % 100) - -/* Get portions of a resistance in more normal units */ -#define PD_CO_O(co) ((co) / 100) -#define PD_CO_CO(co) ((co) % 100) - -/* - * Unit constants - */ -#define PD_MV_MIN 0 -#define PD_MV_MAX 21000 -#define PD_PDV_MIN PD_MV2PDV(PD_MV_MIN) -#define PD_PDV_MAX PD_MV2PDV(PD_MV_MAX) - -#define PD_MA_MIN 0 -#define PD_MA_MAX 5000 -#define PD_CA_MIN PD_MA2CA(PD_MA_MIN) -#define PD_CA_MAX PD_MA2CA(PD_MA_MAX) -#define PD_PDI_MIN PD_MA2PDI(PD_MA_MIN) -#define PD_PDI_MAX PD_MA2PDI(PD_MA_MAX) - -#define PD_MW_MIN 0 -#define PD_MW_MAX 100000 - -#define PD_MO_MIN 500 -#define PD_MO_MAX 655350 - -/* - * FUSB Type-C Current level enum - */ -enum fusb_typec_current { fusb_tcc_none = 0, fusb_tcc_default = 1, fusb_tcc_1_5 = 2, fusb_sink_tx_ng = 2, fusb_tcc_3_0 = 3, fusb_sink_tx_ok = 3 }; - -#endif /* PDB_PD_H */ diff --git a/source/Core/Drivers/FUSB302/pdb_conf.h b/source/Core/Drivers/FUSB302/pdb_conf.h deleted file mode 100644 index 7e50295f..00000000 --- a/source/Core/Drivers/FUSB302/pdb_conf.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * PD Buddy Firmware Library - USB Power Delivery for everyone - * Copyright 2017-2018 Clayton G. Hobbs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PDB_CONF_H -#define PDB_CONF_H - -/* Number of messages in the message pool */ -#define PDB_MSG_POOL_SIZE 8 - -#define EVENT_MASK(x) (1 << x) - -/* PD Buddy thread priorities */ -#define PDB_PRIO_PE (osPriorityAboveNormal) -#define PDB_PRIO_PRL (osPriorityAboveNormal) -#define PDB_PRIO_PRL_INT_N (osPriorityAboveNormal) - -#endif /* PDB_CONF_H */ diff --git a/source/Core/Drivers/FUSB302/pdb_msg.h b/source/Core/Drivers/FUSB302/pdb_msg.h deleted file mode 100644 index 21bcc1a0..00000000 --- a/source/Core/Drivers/FUSB302/pdb_msg.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * PD Buddy Firmware Library - USB Power Delivery for everyone - * Copyright 2017-2018 Clayton G. Hobbs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PDB_MSG_H -#define PDB_MSG_H - -#include <stdint.h> - -/* - * PD message union - * - * This can be safely read from or written to in any form without any - * transformations because everything in the system is little-endian. - * - * Two bytes of padding are required at the start to prevent problems due to - * alignment. Specifically, without the padding, &obj[0] != &bytes[2], making - * the statement in the previous paragraph invalid. - */ -union pd_msg { - struct { - uint8_t _pad1[2]; - uint8_t bytes[30]; - } __attribute__((packed)); - struct { - uint8_t _pad2[2]; - uint16_t hdr; - union { - uint32_t obj[7]; - struct { - uint16_t exthdr; - uint8_t data[26]; - }; - }; - } __attribute__((packed)); -}; - -#endif /* PDB_MSG_H */ diff --git a/source/Core/Drivers/FUSB302/policy_engine.cpp b/source/Core/Drivers/FUSB302/policy_engine.cpp deleted file mode 100644 index 989913cc..00000000 --- a/source/Core/Drivers/FUSB302/policy_engine.cpp +++ /dev/null @@ -1,686 +0,0 @@ -/* - * PD Buddy Firmware Library - USB Power Delivery for everyone - * Copyright 2017-2018 Clayton G. Hobbs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "policy_engine.h" -#include "Defines.h" -#include "fusb302b.h" -#include "int_n.h" -#include <pd.h> -#include <stdbool.h> - -bool PolicyEngine::pdNegotiationComplete; -int PolicyEngine::current_voltage_mv; -int PolicyEngine::_requested_voltage; -bool PolicyEngine::_unconstrained_power; -uint16_t PolicyEngine::hdr_template; -bool PolicyEngine::_explicit_contract; -int8_t PolicyEngine::_hard_reset_counter; -uint8_t PolicyEngine::_pps_index; -osThreadId PolicyEngine::TaskHandle = NULL; -uint32_t PolicyEngine::TaskBuffer[PolicyEngine::TaskStackSize]; -osStaticThreadDef_t PolicyEngine::TaskControlBlock; -union pd_msg PolicyEngine::tempMessage; -union pd_msg PolicyEngine::_last_dpm_request; -PolicyEngine::policy_engine_state PolicyEngine::state = PESinkStartup; -StaticQueue_t PolicyEngine::xStaticQueue; -uint8_t PolicyEngine::ucQueueStorageArea[PDB_MSG_POOL_SIZE * sizeof(union pd_msg)]; -QueueHandle_t PolicyEngine::messagesWaiting = NULL; -EventGroupHandle_t PolicyEngine::xEventGroupHandle = NULL; -StaticEventGroup_t PolicyEngine::xCreatedEventGroup; -bool PolicyEngine::PPSTimerEnabled = false; -TickType_t PolicyEngine::PPSTimeLastEvent = 0; -uint8_t PolicyEngine::_tx_messageidcounter = 0; - -void PolicyEngine::init() { - messagesWaiting = xQueueCreateStatic(PDB_MSG_POOL_SIZE, sizeof(union pd_msg), ucQueueStorageArea, &xStaticQueue); - // Create static thread at PDB_PRIO_PE priority - osThreadStaticDef(PolEng, pe_task, PDB_PRIO_PE, 0, TaskStackSize, TaskBuffer, &TaskControlBlock); - TaskHandle = osThreadCreate(osThread(PolEng), NULL); - xEventGroupHandle = xEventGroupCreateStatic(&xCreatedEventGroup); -} - -void PolicyEngine::notify(PolicyEngine::Notifications notification) { - EventBits_t val = (EventBits_t)notification; - if (xEventGroupHandle != NULL) { - xEventGroupSetBits(xEventGroupHandle, val); - } -} - -void PolicyEngine::pe_task(const void *arg) { - (void)arg; - // Internal thread loop - hdr_template = PD_DATAROLE_UFP | PD_POWERROLE_SINK; - /* Initialize the old_tcc_match */ - /* Initialize the pps_index */ - _pps_index = 0xFF; - - for (;;) { - // Loop based on state - switch (state) { - - case PESinkStartup: - state = pe_sink_startup(); - break; - case PESinkDiscovery: - state = pe_sink_discovery(); - break; - case PESinkWaitCap: - state = pe_sink_wait_cap(); - break; - case PESinkEvalCap: - state = pe_sink_eval_cap(); - break; - case PESinkSelectCap: - state = pe_sink_select_cap(); - break; - case PESinkTransitionSink: - state = pe_sink_transition_sink(); - break; - case PESinkReady: - state = pe_sink_ready(); - break; - case PESinkGetSourceCap: - state = pe_sink_get_source_cap(); - break; - case PESinkGiveSinkCap: - state = pe_sink_give_sink_cap(); - break; - case PESinkHardReset: - state = pe_sink_hard_reset(); - break; - case PESinkTransitionDefault: - state = pe_sink_transition_default(); - break; - case PESinkSoftReset: - state = pe_sink_soft_reset(); - break; - case PESinkSendSoftReset: - state = pe_sink_send_soft_reset(); - break; - case PESinkSendNotSupported: - state = pe_sink_send_not_supported(); - break; - case PESinkChunkReceived: - state = pe_sink_chunk_received(); - break; - case PESinkSourceUnresponsive: - state = pe_sink_source_unresponsive(); - break; - case PESinkNotSupportedReceived: - state = pe_sink_not_supported_received(); - break; - default: - state = PESinkStartup; - break; - } - } -} - -PolicyEngine::policy_engine_state PolicyEngine::pe_sink_startup() { - /* We don't have an explicit contract currently */ - _explicit_contract = false; - PPSTimerEnabled = false; - // If desired could send an alert that PD is starting - - /* No need to reset the protocol layer here. There are two ways into this - * state: startup and exiting hard reset. On startup, the protocol layer - * is reset by the startup procedure. When exiting hard reset, the - * protocol layer is reset by the hard reset state machine. Since it's - * already done somewhere else, there's no need to do it again here. */ - - return PESinkDiscovery; -} - -PolicyEngine::policy_engine_state PolicyEngine::pe_sink_discovery() { - /* Wait for VBUS. Since it's our only power source, we already know that - * we have it, so just move on. */ - - return PESinkWaitCap; -} - -PolicyEngine::policy_engine_state PolicyEngine::pe_sink_wait_cap() { - /* Fetch a message from the protocol layer */ - EventBits_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_MSG_RX | (uint32_t)Notifications::PDB_EVT_PE_I_OVRTEMP | (uint32_t)Notifications::PDB_EVT_PE_RESET, - // Wait for cap timeout - PD_T_TYPEC_SINK_WAIT_CAP); - - /* If we timed out waiting for Source_Capabilities, send a hard reset */ - if (evt == 0) { - return PESinkHardReset; - } - /* If we got reset signaling, transition to default */ - if (evt & (uint32_t)Notifications::PDB_EVT_PE_RESET) { - return PESinkWaitCap; - } - /* If we're too hot, we shouldn't negotiate power yet */ - if (evt & (uint32_t)Notifications::PDB_EVT_PE_I_OVRTEMP) { - return PESinkWaitCap; - } - - /* If we got a message */ - if (evt & (uint32_t)Notifications::PDB_EVT_PE_MSG_RX) { - /* Get the message */ - while (readMessage()) { - /* If we got a Source_Capabilities message, read it. */ - if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_SOURCE_CAPABILITIES && PD_NUMOBJ_GET(&tempMessage) > 0) { - /* First, determine what PD revision we're using */ - if ((hdr_template & PD_HDR_SPECREV) == PD_SPECREV_1_0) { - /* If the other end is using at least version 3.0, we'll - * use version 3.0. */ - if ((tempMessage.hdr & PD_HDR_SPECREV) >= PD_SPECREV_3_0) { - hdr_template |= PD_SPECREV_3_0; - /* Otherwise, use 2.0. Don't worry about the 1.0 case - * because we don't have hardware for PD 1.0 signaling. */ - } else { - hdr_template |= PD_SPECREV_2_0; - } - } - return PESinkEvalCap; - } - } - return PESinkWaitCap; // wait for more messages? - } - - /* If we failed to get a message, wait longer */ - return PESinkWaitCap; -} - -PolicyEngine::policy_engine_state PolicyEngine::pe_sink_eval_cap() { - /* If we have a Source_Capabilities message, remember the index of the - * first PPS APDO so we can check if the request is for a PPS APDO in - * PE_SNK_Select_Cap. */ - /* Start by assuming we won't find a PPS APDO (set the index greater - * than the maximum possible) */ - _pps_index = 0xFF; - /* New capabilities also means we can't be making a request from the - * same PPS APDO */ - /* Search for the first PPS APDO */ - for (int i = 0; i < PD_NUMOBJ_GET(&tempMessage); i++) { - if ((tempMessage.obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_AUGMENTED && (tempMessage.obj[i] & PD_APDO_TYPE) == PD_APDO_TYPE_PPS) { - _pps_index = i + 1; - break; - } - } - - /* Ask the DPM what to request */ - if (pdbs_dpm_evaluate_capability(&tempMessage, &_last_dpm_request)) { - /* If we're using PD 3.0 */ - if ((hdr_template & PD_HDR_SPECREV) == PD_SPECREV_3_0) { - /* If the request was for a PPS APDO, start time callbacks if not started */ - if (PD_RDO_OBJPOS_GET(&_last_dpm_request) >= _pps_index) { - PPSTimerEnabled = true; - } else { - PPSTimerEnabled = false; - } - } - return PESinkSelectCap; - } - - return PESinkWaitCap; -} - -PolicyEngine::policy_engine_state PolicyEngine::pe_sink_select_cap() { - - /* Transmit the request */ - waitForEvent((uint32_t)Notifications::PDB_EVT_PE_ALL, 0); // clear pending - EventBits_t evt = pushMessage(&_last_dpm_request); - /* If we got reset signaling, transition to default */ - if (evt & (uint32_t)Notifications::PDB_EVT_PE_RESET || evt == 0) { - return PESinkTransitionDefault; - } - /* If the message transmission failed, send a hard reset */ - if ((evt & (uint32_t)Notifications::PDB_EVT_PE_TX_ERR) == (uint32_t)Notifications::PDB_EVT_PE_TX_ERR) { - return PESinkHardReset; - } - - /* Wait for a response */ - evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_MSG_RX | (uint32_t)Notifications::PDB_EVT_PE_RESET, PD_T_SENDER_RESPONSE); - /* If we got reset signaling, transition to default */ - if (evt & (uint32_t)Notifications::PDB_EVT_PE_RESET) { - return PESinkTransitionDefault; - } - /* If we didn't get a response before the timeout, send a hard reset */ - if (evt == 0) { - return PESinkSoftReset; - } - - /* Get the response message */ - if (messageWaiting()) { - readMessage(); - /* If the source accepted our request, wait for the new power */ - if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_ACCEPT && PD_NUMOBJ_GET(&tempMessage) == 0) { - return PESinkTransitionSink; - /* If the message was a Soft_Reset, do the soft reset procedure */ - } else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_SOFT_RESET && PD_NUMOBJ_GET(&tempMessage) == 0) { - return PESinkSoftReset; - /* If the message was Wait or Reject */ - } else if ((PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_REJECT || PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_WAIT) && PD_NUMOBJ_GET(&tempMessage) == 0) { - /* If we don't have an explicit contract, wait for capabilities */ - if (!_explicit_contract) { - return PESinkWaitCap; - /* If we do have an explicit contract, go to the ready state */ - } else { - return PESinkReady; - } - } else { - return PESinkSoftReset; - } - } - return PESinkHardReset; -} - -PolicyEngine::policy_engine_state PolicyEngine::pe_sink_transition_sink() { - /* Wait for the PS_RDY message */ - EventBits_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_MSG_RX | (uint32_t)Notifications::PDB_EVT_PE_RESET, PD_T_PS_TRANSITION); - /* If we got reset signaling, transition to default */ - if (evt & (uint32_t)Notifications::PDB_EVT_PE_RESET) { - return PESinkTransitionDefault; - } - - /* If we received a message, read it */ - while (messageWaiting()) { - readMessage(); - /* If we got a PS_RDY, handle it */ - if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_PS_RDY && PD_NUMOBJ_GET(&tempMessage) == 0) { - /* We just finished negotiating an explicit contract */ - _explicit_contract = true; - - /* Negotiation finished */ - pdbs_dpm_transition_requested(); - - return PESinkReady; - /* If there was a protocol error, send a hard reset */ - } - } - return PESinkSoftReset; -} - -PolicyEngine::policy_engine_state PolicyEngine::pe_sink_ready() { - EventBits_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_ALL); - /* If SinkPPSPeriodicTimer ran out, send a new request */ - if (evt & (uint32_t)Notifications::PDB_EVT_PE_PPS_REQUEST) { - return PESinkSelectCap; - } - /* If we got reset signaling, transition to default */ - if (evt & (uint32_t)Notifications::PDB_EVT_PE_RESET) { - return PESinkTransitionDefault; - } - - /* If we overheated, send a hard reset */ - if (evt & (uint32_t)Notifications::PDB_EVT_PE_I_OVRTEMP) { - return PESinkHardReset; - } - /* If the DPM wants us to, send a Get_Source_Cap message */ - if (evt & (uint32_t)Notifications::PDB_EVT_PE_GET_SOURCE_CAP) { - return PESinkGetSourceCap; - } - /* If the DPM wants new power, let it figure out what power it wants - * exactly. This isn't exactly the transition from the spec (that would be - * SelectCap, not EvalCap), but this works better with the particular - * design of this firmware. */ - if (evt & (uint32_t)Notifications::PDB_EVT_PE_NEW_POWER) { - /* Tell the protocol layer we're starting an AMS */ - return PESinkEvalCap; - } - - /* If we received a message */ - if (evt & (uint32_t)Notifications::PDB_EVT_PE_MSG_RX) { - if (messageWaiting()) { - readMessage(); - /* Ignore vendor-defined messages */ - if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_VENDOR_DEFINED && PD_NUMOBJ_GET(&tempMessage) > 0) { - return PESinkReady; - /* Ignore Ping messages */ - } else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_PING && PD_NUMOBJ_GET(&tempMessage) == 0) { - return PESinkReady; - /* DR_Swap messages are not supported */ - } else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_DR_SWAP && PD_NUMOBJ_GET(&tempMessage) == 0) { - return PESinkSendNotSupported; - /* Get_Source_Cap messages are not supported */ - } else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_GET_SOURCE_CAP && PD_NUMOBJ_GET(&tempMessage) == 0) { - return PESinkSendNotSupported; - /* PR_Swap messages are not supported */ - } else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_PR_SWAP && PD_NUMOBJ_GET(&tempMessage) == 0) { - return PESinkSendNotSupported; - /* VCONN_Swap messages are not supported */ - } else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_VCONN_SWAP && PD_NUMOBJ_GET(&tempMessage) == 0) { - return PESinkSendNotSupported; - /* Request messages are not supported */ - } else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_REQUEST && PD_NUMOBJ_GET(&tempMessage) > 0) { - return PESinkSendNotSupported; - /* Sink_Capabilities messages are not supported */ - } else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_SINK_CAPABILITIES && PD_NUMOBJ_GET(&tempMessage) > 0) { - return PESinkSendNotSupported; - /* Handle GotoMin messages */ - } else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_GOTOMIN && PD_NUMOBJ_GET(&tempMessage) == 0) { - return PESinkSendNotSupported; - /* Evaluate new Source_Capabilities */ - } else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_SOURCE_CAPABILITIES && PD_NUMOBJ_GET(&tempMessage) > 0) { - return PESinkEvalCap; - /* Give sink capabilities when asked */ - } else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_GET_SINK_CAP && PD_NUMOBJ_GET(&tempMessage) == 0) { - return PESinkGiveSinkCap; - /* If the message was a Soft_Reset, do the soft reset procedure */ - } else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_SOFT_RESET && PD_NUMOBJ_GET(&tempMessage) == 0) { - return PESinkSoftReset; - /* PD 3.0 messges */ - } else if ((hdr_template & PD_HDR_SPECREV) == PD_SPECREV_3_0) { - /* If the message is a multi-chunk extended message, let it - * time out. */ - if ((tempMessage.hdr & PD_HDR_EXT) && (PD_DATA_SIZE_GET(&tempMessage) > PD_MAX_EXT_MSG_LEGACY_LEN)) { - - return PESinkChunkReceived; - /* Tell the DPM a message we sent got a response of - * Not_Supported. */ - } else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_NOT_SUPPORTED && PD_NUMOBJ_GET(&tempMessage) == 0) { - - return PESinkNotSupportedReceived; - /* If we got an unknown message, send a soft reset */ - } else { - - return PESinkSendSoftReset; - } - } - } - } - - return PESinkReady; -} - -PolicyEngine::policy_engine_state PolicyEngine::pe_sink_get_source_cap() { - /* Get a message object */ - union pd_msg *get_source_cap = &tempMessage; - /* Make a Get_Source_Cap message */ - get_source_cap->hdr = hdr_template | PD_MSGTYPE_GET_SOURCE_CAP | PD_NUMOBJ(0); - /* Transmit the Get_Source_Cap */ - EventBits_t evt = pushMessage(get_source_cap); - /* Free the sent message */ - /* If we got reset signaling, transition to default */ - if (evt & (uint32_t)Notifications::PDB_EVT_PE_RESET) { - return PESinkTransitionDefault; - } - /* If the message transmission failed, send a hard reset */ - if ((evt & (uint32_t)Notifications::PDB_EVT_PE_TX_DONE) == 0) { - return PESinkHardReset; - } - - return PESinkReady; -} - -PolicyEngine::policy_engine_state PolicyEngine::pe_sink_give_sink_cap() { - /* Get a message object */ - union pd_msg *snk_cap = &tempMessage; - /* Get our capabilities from the DPM */ - pdbs_dpm_get_sink_capability(snk_cap); - - /* Transmit our capabilities */ - EventBits_t evt = pushMessage(snk_cap); - - /* Free the Sink_Capabilities message */ - - /* If we got reset signaling, transition to default */ - if (evt & (uint32_t)Notifications::PDB_EVT_PE_RESET) { - return PESinkTransitionDefault; - } - /* If the message transmission failed, send a hard reset */ - if ((evt & (uint32_t)Notifications::PDB_EVT_PE_TX_DONE) == 0) { - return PESinkHardReset; - } - - return PESinkReady; -} - -PolicyEngine::policy_engine_state PolicyEngine::pe_sink_hard_reset() { - /* If we've already sent the maximum number of hard resets, assume the - * source is unresponsive. */ - if (_hard_reset_counter > PD_N_HARD_RESET_COUNT) { - return PESinkSourceUnresponsive; - } - // So, we could send a hardreset here; however that will cause a power cycle on the PSU end.. Which will then reset this MCU - // So therefore we went get anywhere :) - /* Increment HardResetCounter */ - _hard_reset_counter++; - - return PESinkTransitionDefault; -} - -PolicyEngine::policy_engine_state PolicyEngine::pe_sink_transition_default() { - _explicit_contract = false; - - /* Tell the DPM to transition to default power */ - pdbs_dpm_transition_default(); - - /* There is no local hardware to reset. */ - /* Since we never change our data role from UFP, there is no reason to set - * it here. */ - - return PESinkStartup; -} - -PolicyEngine::policy_engine_state PolicyEngine::pe_sink_soft_reset() { - /* No need to explicitly reset the protocol layer here. It resets itself - * when a Soft_Reset message is received. */ - - /* Get a message object */ - union pd_msg accept; - /* Make an Accept message */ - accept.hdr = hdr_template | PD_MSGTYPE_ACCEPT | PD_NUMOBJ(0); - /* Transmit the Accept */ - EventBits_t evt = pushMessage(&accept); - /* Free the sent message */ - - /* If we got reset signaling, transition to default */ - if (evt & (uint32_t)Notifications::PDB_EVT_PE_RESET) { - return PESinkTransitionDefault; - } - /* If the message transmission failed, send a hard reset */ - if ((evt & (uint32_t)Notifications::PDB_EVT_PE_TX_DONE) == 0) { - return PESinkHardReset; - } - - return PESinkWaitCap; -} - -PolicyEngine::policy_engine_state PolicyEngine::pe_sink_send_soft_reset() { - /* No need to explicitly reset the protocol layer here. It resets itself - * just before a Soft_Reset message is transmitted. */ - - /* Get a message object */ - union pd_msg *softrst = &tempMessage; - /* Make a Soft_Reset message */ - softrst->hdr = hdr_template | PD_MSGTYPE_SOFT_RESET | PD_NUMOBJ(0); - /* Transmit the soft reset */ - EventBits_t evt = pushMessage(softrst); - /* If we got reset signaling, transition to default */ - if (evt & (uint32_t)Notifications::PDB_EVT_PE_RESET) { - return PESinkTransitionDefault; - } - /* If the message transmission failed, send a hard reset */ - if ((evt & (uint32_t)Notifications::PDB_EVT_PE_TX_DONE) == 0) { - return PESinkHardReset; - } - - /* Wait for a response */ - evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_MSG_RX | (uint32_t)Notifications::PDB_EVT_PE_RESET, PD_T_SENDER_RESPONSE); - /* If we got reset signaling, transition to default */ - if (evt & (uint32_t)Notifications::PDB_EVT_PE_RESET) { - return PESinkTransitionDefault; - } - /* If we didn't get a response before the timeout, send a hard reset */ - if (evt == 0) { - return PESinkHardReset; - } - - /* Get the response message */ - if (messageWaiting()) { - readMessage(); - /* If the source accepted our soft reset, wait for capabilities. */ - if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_ACCEPT && PD_NUMOBJ_GET(&tempMessage) == 0) { - - return PESinkWaitCap; - /* If the message was a Soft_Reset, do the soft reset procedure */ - } else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_SOFT_RESET && PD_NUMOBJ_GET(&tempMessage) == 0) { - - return PESinkSoftReset; - /* Otherwise, send a hard reset */ - } else { - - return PESinkHardReset; - } - } - return PESinkHardReset; -} - -PolicyEngine::policy_engine_state PolicyEngine::pe_sink_send_not_supported() { - /* Get a message object */ - - if ((hdr_template & PD_HDR_SPECREV) == PD_SPECREV_2_0) { - /* Make a Reject message */ - tempMessage.hdr = hdr_template | PD_MSGTYPE_REJECT | PD_NUMOBJ(0); - } else if ((hdr_template & PD_HDR_SPECREV) == PD_SPECREV_3_0) { - /* Make a Not_Supported message */ - tempMessage.hdr = hdr_template | PD_MSGTYPE_NOT_SUPPORTED | PD_NUMOBJ(0); - } - - /* Transmit the message */ - EventBits_t evt = pushMessage(&tempMessage); - - /* If we got reset signaling, transition to default */ - if (evt & (uint32_t)Notifications::PDB_EVT_PE_RESET) { - return PESinkTransitionDefault; - } - /* If the message transmission failed, send a soft reset */ - if ((evt & (uint32_t)Notifications::PDB_EVT_PE_TX_DONE) == 0) { - return PESinkSendSoftReset; - } - - return PESinkReady; -} - -PolicyEngine::policy_engine_state PolicyEngine::pe_sink_chunk_received() { - - /* Wait for tChunkingNotSupported */ - EventBits_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_RESET, PD_T_CHUNKING_NOT_SUPPORTED); - /* If we got reset signaling, transition to default */ - if (evt & (uint32_t)Notifications::PDB_EVT_PE_RESET) { - return PESinkTransitionDefault; - } - - return PESinkSendNotSupported; -} - -PolicyEngine::policy_engine_state PolicyEngine::pe_sink_not_supported_received() { - /* Inform the Device Policy Manager that we received a Not_Supported - * message. */ - - return PESinkReady; -} - -PolicyEngine::policy_engine_state PolicyEngine::pe_sink_source_unresponsive() { - // Sit and chill, as PD is not working - osDelay(PD_T_PD_DEBOUNCE); - - return PESinkSourceUnresponsive; -} - -EventBits_t PolicyEngine::waitForEvent(uint32_t mask, TickType_t ticksToWait) { return xEventGroupWaitBits(xEventGroupHandle, mask, mask, pdFALSE, ticksToWait); } - -bool PolicyEngine::isPD3_0() { return (hdr_template & PD_HDR_SPECREV) == PD_SPECREV_3_0; } - -void PolicyEngine::handleMessage(union pd_msg *msg) { - xQueueSend(messagesWaiting, msg, 100); - notify(PolicyEngine::Notifications::PDB_EVT_PE_MSG_RX); -} - -void PolicyEngine::PPSTimerCallback() { - if (PPSTimerEnabled && state == policy_engine_state::PESinkReady) { - // I believe even once per second is totally fine, but leaning on faster since everything seems cool with faster - // Have seen everything from 10ms to 1 second :D - if ((xTaskGetTickCount() - PPSTimeLastEvent) > (TICKS_SECOND)) { - // Send a new PPS message - PolicyEngine::notify(Notifications::PDB_EVT_PE_PPS_REQUEST); - PPSTimeLastEvent = xTaskGetTickCount(); - } - } -} - -bool PolicyEngine::NegotiationTimeoutReached(uint8_t timeout) { - if (timeout == 0) { - return false; - } - - if (xTaskGetTickCount() > (TICKS_100MS * timeout)) { - state = PESinkSourceUnresponsive; - return true; - } - - return false; -} - -EventBits_t PolicyEngine::pushMessage(union pd_msg *msg) { - if (PD_MSGTYPE_GET(msg) == PD_MSGTYPE_SOFT_RESET && PD_NUMOBJ_GET(msg) == 0) { - /* Clear MessageIDCounter */ - _tx_messageidcounter = 0; - return (EventBits_t)Notifications::PDB_EVT_PE_TX_DONE; - } - msg->hdr &= ~PD_HDR_MESSAGEID; - msg->hdr |= (_tx_messageidcounter % 8) << PD_HDR_MESSAGEID_SHIFT; - - /* PD 3.0 collision avoidance */ - if (PolicyEngine::isPD3_0()) { - /* If we're starting an AMS, wait for permission to transmit */ - // while (fusb_get_typec_current() != fusb_sink_tx_ok) { - // vTaskDelay(TICKS_10MS); - // } - } - /* Send the message to the PHY */ - fusb_send_message(msg); - /* Waiting for response*/ - EventBits_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_RESET | (uint32_t)Notifications::PDB_EVT_TX_DISCARD | (uint32_t)Notifications::PDB_EVT_TX_I_TXSENT - | (uint32_t)Notifications::PDB_EVT_TX_I_RETRYFAIL); - - if ((uint32_t)evt & (uint32_t)Notifications::PDB_EVT_TX_DISCARD) { - // increment the counter - _tx_messageidcounter = (_tx_messageidcounter + 1) % 8; - return (EventBits_t)Notifications::PDB_EVT_PE_TX_ERR; // - } - - /* If the message was sent successfully */ - if ((uint32_t)evt & (uint32_t)Notifications::PDB_EVT_TX_I_TXSENT) { - union pd_msg goodcrc; - - /* Read the GoodCRC */ - fusb_read_message(&goodcrc); - - /* Check that the message is correct */ - if (PD_MSGTYPE_GET(&goodcrc) == PD_MSGTYPE_GOODCRC && PD_NUMOBJ_GET(&goodcrc) == 0 && PD_MESSAGEID_GET(&goodcrc) == _tx_messageidcounter) { - /* Increment MessageIDCounter */ - _tx_messageidcounter = (_tx_messageidcounter + 1) % 8; - - return (EventBits_t)Notifications::PDB_EVT_PE_TX_DONE; - } else { - return (EventBits_t)Notifications::PDB_EVT_PE_TX_ERR; - } - } - /* If the message failed to be sent */ - if ((uint32_t)evt & (uint32_t)Notifications::PDB_EVT_TX_I_RETRYFAIL) { - return (EventBits_t)Notifications::PDB_EVT_PE_TX_ERR; - } - - /* Silence the compiler warning */ - return (EventBits_t)Notifications::PDB_EVT_PE_TX_ERR; -} diff --git a/source/Core/Drivers/FUSB302/policy_engine.h b/source/Core/Drivers/FUSB302/policy_engine.h deleted file mode 100644 index 8cd89611..00000000 --- a/source/Core/Drivers/FUSB302/policy_engine.h +++ /dev/null @@ -1,215 +0,0 @@ -/* - * PD Buddy Firmware Library - USB Power Delivery for everyone - * Copyright 2017-2018 Clayton G. Hobbs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PDB_POLICY_ENGINE_H -#define PDB_POLICY_ENGINE_H - -#include <pd.h> - -/* - * Events for the Policy Engine thread, used internally + sent by user code - * - */ - -class PolicyEngine { -public: - // Sets up internal state and registers the thread - static void init(); - // Push an incoming message to the Policy Engine - static void handleMessage(union pd_msg *msg); - // Returns true if headers indicate PD3.0 compliant - static bool isPD3_0(); - static bool setupCompleteOrTimedOut(uint8_t timeout) { - if (pdNegotiationComplete) - return true; - if (PolicyEngine::NegotiationTimeoutReached(timeout)) - return true; - if (state == policy_engine_state::PESinkSourceUnresponsive) - return true; - if (state == policy_engine_state::PESinkReady) - return true; - return false; - } - // Has pd negotiation completed - static bool pdHasNegotiated() { - if (state == policy_engine_state::PESinkSourceUnresponsive) - return false; - return true; - } - // Call this periodically, at least once every second - static void PPSTimerCallback(); - - static bool NegotiationTimeoutReached(uint8_t timeout); - - enum class Notifications { - PDB_EVT_PE_RESET = EVENT_MASK(0), - PDB_EVT_PE_MSG_RX = EVENT_MASK(1), - PDB_EVT_PE_TX_DONE = EVENT_MASK(2), - PDB_EVT_PE_TX_ERR = EVENT_MASK(3), - PDB_EVT_PE_HARD_SENT = EVENT_MASK(4), - PDB_EVT_PE_I_OVRTEMP = EVENT_MASK(5), - PDB_EVT_PE_PPS_REQUEST = EVENT_MASK(6), - PDB_EVT_PE_GET_SOURCE_CAP = EVENT_MASK(7), - PDB_EVT_PE_NEW_POWER = EVENT_MASK(8), - PDB_EVT_TX_I_TXSENT = EVENT_MASK(9), - PDB_EVT_TX_I_RETRYFAIL = EVENT_MASK(10), - PDB_EVT_TX_DISCARD = EVENT_MASK(11), - PDB_EVT_PE_ALL = (EVENT_MASK(12) - 1), - }; - // Send a notification - static void notify(Notifications notification); - // Debugging allows looking at state - static uint32_t getState() { return (uint32_t)state; } - -private: - static bool pdNegotiationComplete; - static int current_voltage_mv; // The current voltage PD is expecting - static int _requested_voltage; // The voltage the unit wanted to requests - static bool _unconstrained_power; // If the source is unconstrained - /* PD message header template */ - static uint16_t hdr_template; - /* Whether or not we have an explicit contract */ - static bool _explicit_contract; - /* The number of hard resets we've sent */ - static int8_t _hard_reset_counter; - /* The index of the first PPS APDO */ - static uint8_t _pps_index; - - static void pe_task(const void *arg); - static EventBits_t pushMessage(union pd_msg *msg); - static uint8_t _tx_messageidcounter; - enum policy_engine_state { - PESinkStartup, // 0 - PESinkDiscovery, // 1 - PESinkWaitCap, // 2 - PESinkEvalCap, // 3 - PESinkSelectCap, // 4 - PESinkTransitionSink, // 5 - PESinkReady, // 6 - PESinkGetSourceCap, // 7 - PESinkGiveSinkCap, // 8 - PESinkHardReset, // 9 - PESinkTransitionDefault, // 10 - PESinkSoftReset, // 11 - PESinkSendSoftReset, // 12 - PESinkSendNotSupported, // 13 - PESinkChunkReceived, // 14 - PESinkNotSupportedReceived, // 15 - PESinkSourceUnresponsive // 16 - - }; - static enum policy_engine_state pe_sink_startup(); - static enum policy_engine_state pe_sink_discovery(); - static enum policy_engine_state pe_sink_wait_cap(); - static enum policy_engine_state pe_sink_eval_cap(); - static enum policy_engine_state pe_sink_select_cap(); - static enum policy_engine_state pe_sink_transition_sink(); - static enum policy_engine_state pe_sink_ready(); - static enum policy_engine_state pe_sink_get_source_cap(); - static enum policy_engine_state pe_sink_give_sink_cap(); - static enum policy_engine_state pe_sink_hard_reset(); - static enum policy_engine_state pe_sink_transition_default(); - static enum policy_engine_state pe_sink_soft_reset(); - static enum policy_engine_state pe_sink_send_soft_reset(); - static enum policy_engine_state pe_sink_send_not_supported(); - static enum policy_engine_state pe_sink_chunk_received(); - static enum policy_engine_state pe_sink_not_supported_received(); - static enum policy_engine_state pe_sink_source_unresponsive(); - static EventGroupHandle_t xEventGroupHandle; - static StaticEventGroup_t xCreatedEventGroup; - static EventBits_t waitForEvent(uint32_t mask, TickType_t ticksToWait = portMAX_DELAY); - // Task resources - static osThreadId TaskHandle; - static const size_t TaskStackSize = 2048 / 4; - static uint32_t TaskBuffer[TaskStackSize]; - static osStaticThreadDef_t TaskControlBlock; - static union pd_msg tempMessage; - static union pd_msg _last_dpm_request; - static policy_engine_state state; - // queue of up to PDB_MSG_POOL_SIZE messages to send - static StaticQueue_t xStaticQueue; - /* The array to use as the queue's storage area. This must be at least - uxQueueLength * uxItemSize bytes. */ - static uint8_t ucQueueStorageArea[PDB_MSG_POOL_SIZE * sizeof(union pd_msg)]; - static QueueHandle_t messagesWaiting; - static bool messageWaiting(); - // Read a pending message into the temp message - static bool readMessage(); - static bool PPSTimerEnabled; - static TickType_t PPSTimeLastEvent; - - // These callbacks are called to implement the logic for the iron to select the desired voltage - - /* - * Create a Request message based on the given Source_Capabilities message. If - * capabilities is NULL, the last non-null Source_Capabilities message passes - * is used. If none has been provided, the behavior is undefined. - * - * Returns true if sufficient power is available, false otherwise. - */ - static bool pdbs_dpm_evaluate_capability(const union pd_msg *capabilities, union pd_msg *request); - - /* - * Create a Sink_Capabilities message for our current capabilities. - */ - static void pdbs_dpm_get_sink_capability(union pd_msg *cap); - - /* - * Return whether or not GiveBack support is enabled. - */ - static bool pdbs_dpm_giveback_enabled(); - - /* - * Evaluate whether or not the currently offered Type-C Current can fulfill our - * power needs. - * - * Returns true if sufficient power is available, false otherwise. - */ - static bool pdbs_dpm_evaluate_typec_current(enum fusb_typec_current tcc); - - /* - * Indicate that power negotiations are starting. - */ - static void pdbs_dpm_pd_start(); - - /* - * Transition the sink to default power. - */ - static void pdbs_dpm_transition_default(); - - /* - * Transition to the requested minimum current. - */ - static void pdbs_dpm_transition_min(); - - /* - * Transition to Sink Standby if necessary. - */ - static void pdbs_dpm_transition_standby(); - - /* - * Transition to the requested power level - */ - static void pdbs_dpm_transition_requested(); - - /* - * Transition to the Type-C Current power level - */ - static void pdbs_dpm_transition_typec(); -}; - -#endif /* PDB_POLICY_ENGINE_H */ diff --git a/source/Core/Drivers/FUSB302/policy_engine_user.cpp b/source/Core/Drivers/FUSB302/policy_engine_user.cpp deleted file mode 100644 index b97584aa..00000000 --- a/source/Core/Drivers/FUSB302/policy_engine_user.cpp +++ /dev/null @@ -1,250 +0,0 @@ -/*
- * policy_engine_user.cpp
- *
- * Created on: 14 Jun 2020
- * Author: Ralim
- */
-#include "BSP_PD.h"
-#include "configuration.h"
-#include "main.hpp"
-#include "pd.h"
-#include "policy_engine.h"
-
-/* The current draw when the output is disabled */
-#define DPM_MIN_CURRENT PD_MA2PDI(100)
-/*
- * Find the index of the first PDO from capabilities in the voltage range,
- * using the desired order.
- *
- * If there is no such PDO, returns -1 instead.
- */
-static int8_t dpm_get_range_fixed_pdo_index(const union pd_msg *caps) {
- /* Get the number of PDOs */
- uint8_t numobj = PD_NUMOBJ_GET(caps);
-
- /* Get ready to iterate over the PDOs */
- int8_t i;
- int8_t step;
- i = numobj - 1;
- step = -1;
- uint16_t current = 100; // in centiamps
- uint16_t voltagemin = 8000;
- uint16_t voltagemax = 10000;
- /* Look at the PDOs to see if one falls in our voltage range. */
- while (0 <= i && i < numobj) {
- /* If we have a fixed PDO, its V is within our range, and its I is at
- * least our desired I */
- uint16_t v = PD_PDO_SRC_FIXED_VOLTAGE_GET(caps->obj[i]);
- if ((caps->obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_FIXED) {
- if (PD_PDO_SRC_FIXED_CURRENT_GET(caps->obj[i]) >= current) {
- if (v >= PD_MV2PDV(voltagemin) && v <= PD_MV2PDV(voltagemax)) {
- return i;
- }
- }
- }
- i += step;
- }
- return -1;
-}
-bool PolicyEngine::pdbs_dpm_evaluate_capability(const union pd_msg *capabilities, union pd_msg *request) {
-
- /* Get the number of PDOs */
- uint8_t numobj = PD_NUMOBJ_GET(capabilities);
-
- /* Get whether or not the power supply is constrained */
- _unconstrained_power = capabilities->obj[0] & PD_PDO_SRC_FIXED_UNCONSTRAINED;
-
- /* Make sure we have configuration */
- /* Look at the PDOs to see if one matches our desires */
- // Look against USB_PD_Desired_Levels to select in order of preference
- uint8_t bestIndex = 0xFF;
- int bestIndexVoltage = 0;
- int bestIndexCurrent = 0;
- bool bestIsPPS = false;
- powerSupplyWattageLimit = 0;
- for (uint8_t i = 0; i < numobj; i++) {
- /* If we have a fixed PDO, its V equals our desired V, and its I is
- * at least our desired I */
- if ((capabilities->obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_FIXED) {
- // This is a fixed PDO entry
- // Evaluate if it can produve sufficient current based on the tipResistance (ohms*10)
- // V=I*R -> V/I => minimum resistance, if our tip resistance is >= this then we can use this supply
-
- int voltage_mv = PD_PDV2MV(PD_PDO_SRC_FIXED_VOLTAGE_GET(capabilities->obj[i])); // voltage in mV units
- int current_a_x100 = PD_PDO_SRC_FIXED_CURRENT_GET(capabilities->obj[i]); // current in 10mA units
- int min_resistance_ohmsx10 = voltage_mv / current_a_x100;
- if (voltage_mv <= (USB_PD_VMAX * 1000)) {
-#ifdef MODEL_HAS_DCDC
- // If this device has step down DC/DC inductor to smooth out current spikes
- // We can instead ignore resistance and go for max voltage we can accept
- if (voltage_mv <= (USB_PD_VMAX * 1000)) {
- min_resistance_ohmsx10 = tipResistance;
- }
-#endif
- // Fudge of 0.5 ohms to round up a little to account for other losses
- if (min_resistance_ohmsx10 <= (tipResistance + 5)) {
- // This is a valid power source we can select as
- if (voltage_mv > bestIndexVoltage || bestIndex == 0xFF) {
- // Higher voltage and valid, select this instead
- bestIndex = i;
- bestIndexVoltage = voltage_mv;
- bestIndexCurrent = current_a_x100;
- bestIsPPS = false;
-#ifdef MODEL_HAS_DCDC
- // set limiter for wattage
- powerSupplyWattageLimit = ((voltage_mv * current_a_x100) / 100 / 1000);
-#endif
- }
- }
- }
- } else if ((capabilities->obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_AUGMENTED && (capabilities->obj[i] & PD_APDO_TYPE) == PD_APDO_TYPE_PPS) {
- // If this is a PPS slot, calculate the max voltage in the PPS range that can we be used and maintain
- uint16_t max_voltage = PD_PAV2MV(PD_APDO_PPS_MAX_VOLTAGE_GET(capabilities->obj[i]));
- // uint16_t min_voltage = PD_PAV2MV(PD_APDO_PPS_MIN_VOLTAGE_GET(capabilities->obj[i]));
- uint16_t max_current = PD_PAI2CA(PD_APDO_PPS_CURRENT_GET(capabilities->obj[i])); // max current in 10mA units
- // Using the current and tip resistance, calculate the ideal max voltage
- // if this is range, then we will work with this voltage
- // if this is not in range; then max_voltage can be safely selected
- int ideal_voltage_mv = (tipResistance * max_current);
- if (ideal_voltage_mv > max_voltage) {
- ideal_voltage_mv = max_voltage; // constrain
- }
- if (ideal_voltage_mv > (USB_PD_VMAX * 1000)) {
- ideal_voltage_mv = (USB_PD_VMAX * 1000); // constrain to model max
- }
- if (ideal_voltage_mv > bestIndexVoltage || bestIndex == 0xFF) {
- bestIndex = i;
- bestIndexVoltage = ideal_voltage_mv;
- bestIndexCurrent = max_current;
- bestIsPPS = true;
-#ifdef MODEL_HAS_DCDC
- // set limiter for wattage
- powerSupplyWattageLimit = ((ideal_voltage_mv * max_current) / 100 / 1000);
-#endif
- }
- }
- }
- if (bestIndex != 0xFF) {
- /* We got what we wanted, so build a request for that */
- request->hdr = hdr_template | PD_MSGTYPE_REQUEST | PD_NUMOBJ(1);
- if (bestIsPPS) {
- request->obj[0] = PD_RDO_PROG_CURRENT_SET(PD_CA2PAI(bestIndexCurrent)) | PD_RDO_PROG_VOLTAGE_SET(PD_MV2PRV(bestIndexVoltage)) | PD_RDO_NO_USB_SUSPEND | PD_RDO_OBJPOS_SET(bestIndex + 1);
- } else {
- request->obj[0] = PD_RDO_FV_MAX_CURRENT_SET(bestIndexCurrent) | PD_RDO_FV_CURRENT_SET(bestIndexCurrent) | PD_RDO_NO_USB_SUSPEND | PD_RDO_OBJPOS_SET(bestIndex + 1);
- }
- // We dont do usb
- // request->obj[0] |= PD_RDO_USB_COMMS;
-
- /* Update requested voltage */
- _requested_voltage = bestIndexVoltage;
-
- } else {
- /* Nothing matched (or no configuration), so get 5 V at low current */
- request->hdr = hdr_template | PD_MSGTYPE_REQUEST | PD_NUMOBJ(1);
- request->obj[0] = PD_RDO_FV_MAX_CURRENT_SET(DPM_MIN_CURRENT) | PD_RDO_FV_CURRENT_SET(DPM_MIN_CURRENT) | PD_RDO_NO_USB_SUSPEND | PD_RDO_OBJPOS_SET(1);
- /* If the output is enabled and we got here, it must be a capability mismatch. */
- if (pdNegotiationComplete) {
- request->obj[0] |= PD_RDO_CAP_MISMATCH;
- }
- // We dont do usb
- // request->obj[0] |= PD_RDO_USB_COMMS;
-
- /* Update requested voltage */
- _requested_voltage = 5000;
- }
- // Even if we didnt match, we return true as we would still like to handshake on 5V at the minimum
- return true;
-}
-
-void PolicyEngine::pdbs_dpm_get_sink_capability(union pd_msg *cap) {
- /* Keep track of how many PDOs we've added */
- int numobj = 0;
-
- /* If we have no configuration or want something other than 5 V, add a PDO
- * for vSafe5V */
- /* Minimum current, 5 V, and higher capability. */
- cap->obj[numobj++] = PD_PDO_TYPE_FIXED | PD_PDO_SNK_FIXED_VOLTAGE_SET(PD_MV2PDV(5000)) | PD_PDO_SNK_FIXED_CURRENT_SET(DPM_MIN_CURRENT);
-
- /* Get the current we want */
- uint16_t voltage = USB_PD_VMAX * 1000; // in mv
- if (_requested_voltage != 5000) {
- voltage = _requested_voltage;
- }
- uint16_t current = (voltage) / tipResistance; // In centi-amps
-
- /* Add a PDO for the desired power. */
- cap->obj[numobj++] = PD_PDO_TYPE_FIXED | PD_PDO_SNK_FIXED_VOLTAGE_SET(PD_MV2PDV(voltage)) | PD_PDO_SNK_FIXED_CURRENT_SET(current);
-
- /* Get the PDO from the voltage range */
- int8_t i = dpm_get_range_fixed_pdo_index(cap);
-
- /* If it's vSafe5V, set our vSafe5V's current to what we want */
- if (i == 0) {
- cap->obj[0] &= ~PD_PDO_SNK_FIXED_CURRENT;
- cap->obj[0] |= PD_PDO_SNK_FIXED_CURRENT_SET(current);
- } else {
- /* If we want more than 5 V, set the Higher Capability flag */
- if (PD_MV2PDV(voltage) != PD_MV2PDV(5000)) {
- cap->obj[0] |= PD_PDO_SNK_FIXED_HIGHER_CAP;
- }
-
- /* If the range PDO is a different voltage than the preferred
- * voltage, add it to the array. */
- if (i > 0 && PD_PDO_SRC_FIXED_VOLTAGE_GET(cap->obj[i]) != PD_MV2PDV(voltage)) {
- cap->obj[numobj++] = PD_PDO_TYPE_FIXED | PD_PDO_SNK_FIXED_VOLTAGE_SET(PD_PDO_SRC_FIXED_VOLTAGE_GET(cap->obj[i])) | PD_PDO_SNK_FIXED_CURRENT_SET(PD_PDO_SRC_FIXED_CURRENT_GET(cap->obj[i]));
- }
-
- /* If we have three PDOs at this point, make sure the last two are
- * sorted by voltage. */
- if (numobj == 3 && (cap->obj[1] & PD_PDO_SNK_FIXED_VOLTAGE) > (cap->obj[2] & PD_PDO_SNK_FIXED_VOLTAGE)) {
- cap->obj[1] ^= cap->obj[2];
- cap->obj[2] ^= cap->obj[1];
- cap->obj[1] ^= cap->obj[2];
- }
- /* If we're using PD 3.0, add a PPS APDO for our desired voltage */
- if ((hdr_template & PD_HDR_SPECREV) >= PD_SPECREV_3_0) {
- cap->obj[numobj++]
- = PD_PDO_TYPE_AUGMENTED | PD_APDO_TYPE_PPS | PD_APDO_PPS_MAX_VOLTAGE_SET(PD_MV2PAV(voltage)) | PD_APDO_PPS_MIN_VOLTAGE_SET(PD_MV2PAV(voltage)) | PD_APDO_PPS_CURRENT_SET(PD_CA2PAI(current));
- }
- }
-
- /* Set the unconstrained power flag. */
- if (_unconstrained_power) {
- cap->obj[0] |= PD_PDO_SNK_FIXED_UNCONSTRAINED;
- }
- /* Set the USB communications capable flag. */
- cap->obj[0] |= PD_PDO_SNK_FIXED_USB_COMMS;
-
- /* Set the Sink_Capabilities message header */
- cap->hdr = hdr_template | PD_MSGTYPE_SINK_CAPABILITIES | PD_NUMOBJ(numobj);
-}
-
-bool PolicyEngine::pdbs_dpm_evaluate_typec_current(enum fusb_typec_current tcc) {
- (void)tcc;
- // This is for evaluating 5V static current advertised by resistors
- /* We don't control the voltage anymore; it will always be 5 V. */
- current_voltage_mv = _requested_voltage = 5000;
- // For the soldering iron we accept this as a fallback, but it sucks
- pdNegotiationComplete = false;
- return true;
-}
-
-void PolicyEngine::pdbs_dpm_transition_default() {
-
- /* Pretend we requested 5 V */
- current_voltage_mv = 5000;
- /* Turn the output off */
- pdNegotiationComplete = false;
-}
-
-void PolicyEngine::pdbs_dpm_transition_requested() { pdNegotiationComplete = true; }
-
-bool PolicyEngine::messageWaiting() { return uxQueueMessagesWaiting(messagesWaiting) > 0; }
-
-bool PolicyEngine::readMessage() { return xQueueReceive(messagesWaiting, &tempMessage, 0) == pdTRUE; }
-
-void PolicyEngine::pdbs_dpm_transition_typec() {
- // This means PD failed, so we either have a dump 5V only type C or a QC charger
- // For now; treat this as failed neg
- pdNegotiationComplete = false;
-}
diff --git a/source/Core/Drivers/OLED.cpp b/source/Core/Drivers/OLED.cpp index 8340610c..260af607 100644 --- a/source/Core/Drivers/OLED.cpp +++ b/source/Core/Drivers/OLED.cpp @@ -121,7 +121,7 @@ void OLED::initialize() { for (int tries = 0; tries < 10; tries++) { if (I2C_CLASS::writeRegistersBulk(DEVICEADDR_OLED, OLED_Setup_Array, sizeof(OLED_Setup_Array) / sizeof(OLED_Setup_Array[0]))) { - return; + tries = 11; } } setDisplayState(DisplayState::ON); diff --git a/source/Core/Drivers/USBPD.cpp b/source/Core/Drivers/USBPD.cpp new file mode 100644 index 00000000..c2d7abef --- /dev/null +++ b/source/Core/Drivers/USBPD.cpp @@ -0,0 +1,236 @@ +#include "USBPD.h" +#include "configuration.h" +#if POW_PD + +#include "BSP_PD.h" +#include "FreeRTOS.h" +#include "fusb302b.h" +#include "main.hpp" +#include "pd.h" +#include "policy_engine.h" + +#ifndef USB_PD_VMAX +#error Max PD Voltage must be defined +#endif +#ifndef TIP_RESISTANCE +#error Tip resistance must be defined +#endif + +void ms_delay(uint32_t delayms) { + // Convert ms -> ticks + TickType_t ticks = delayms / portTICK_PERIOD_MS; + + vTaskDelay(ticks ? ticks : 1); /* Minimum delay = 1 tick */ +} +uint32_t get_ms_timestamp() { + // Convert ticks -> ms + return xTaskGetTickCount() * portTICK_PERIOD_MS; +} +bool pdbs_dpm_evaluate_capability(const pd_msg *capabilities, pd_msg *request); +void pdbs_dpm_get_sink_capability(pd_msg *cap, const bool isPD3); +FUSB302 fusb((0x22 << 1), fusb_read_buf, fusb_write_buf, ms_delay); // Create FUSB driver +PolicyEngine pe(fusb, get_ms_timestamp, ms_delay, pdbs_dpm_get_sink_capability, pdbs_dpm_evaluate_capability); +int USBPowerDelivery::detectionState = 0; +uint16_t requested_voltage_mv = 0; + +/* The current draw when the output is disabled */ +#define DPM_MIN_CURRENT PD_MA2PDI(100) + +// Start processing +bool USBPowerDelivery::start() { + if (fusbPresent() && fusb.fusb_setup()) { + setupFUSBIRQ(); + return true; + } + return false; +} +void USBPowerDelivery::IRQOccured() { pe.IRQOccured(); } +bool USBPowerDelivery::negotiationHasWorked() { return pe.pdHasNegotiated(); } +uint8_t USBPowerDelivery::getStateNumber() { return pe.currentStateCode(true); } +void USBPowerDelivery::step() { + while (pe.thread()) {} +} + +void USBPowerDelivery::PPSTimerCallback() { pe.PPSTimerCallback(); } +bool USBPowerDelivery::negotiationComplete() { + if (!fusbPresent()) { + return true; + } + return pe.setupCompleteOrTimedOut(getSettingValue(SettingsOptions::PDNegTimeout)); +} +bool USBPowerDelivery::fusbPresent() { + if (detectionState == 0) { + if (fusb.fusb_read_id()) { + detectionState = 1; + } + } + return detectionState == 1; +} + +bool pdbs_dpm_evaluate_capability(const pd_msg *capabilities, pd_msg *request) { + + /* Get the number of PDOs */ + uint8_t numobj = PD_NUMOBJ_GET(capabilities); + + /* Make sure we have configuration */ + /* Look at the PDOs to see if one matches our desires */ + // Look against USB_PD_Desired_Levels to select in order of preference + uint8_t bestIndex = 0xFF; + int bestIndexVoltage = 0; + int bestIndexCurrent = 0; + bool bestIsPPS = false; + powerSupplyWattageLimit = 0; + for (uint8_t i = 0; i < numobj; i++) { + /* If we have a fixed PDO, its V equals our desired V, and its I is + * at least our desired I */ + if ((capabilities->obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_FIXED) { + // This is a fixed PDO entry + // Evaluate if it can produve sufficient current based on the TIP_RESISTANCE (ohms*10) + // V=I*R -> V/I => minimum resistance, if our tip resistance is >= this then we can use this supply + + int voltage_mv = PD_PDV2MV(PD_PDO_SRC_FIXED_VOLTAGE_GET(capabilities->obj[i])); // voltage in mV units + int current_a_x100 = PD_PDO_SRC_FIXED_CURRENT_GET(capabilities->obj[i]); // current in 10mA units + int min_resistance_ohmsx10 = voltage_mv / current_a_x100; + if (voltage_mv <= (USB_PD_VMAX * 1000)) { +#ifdef MODEL_HAS_DCDC + // If this device has step down DC/DC inductor to smooth out current spikes + // We can instead ignore resistance and go for max voltage we can accept + min_resistance_ohmsx10 = TIP_RESISTANCE; +#endif + // Fudge of 0.5 ohms to round up a little to account for other losses + if (min_resistance_ohmsx10 <= (TIP_RESISTANCE + 5)) { + // This is a valid power source we can select as + if ((voltage_mv > bestIndexVoltage) || bestIndex == 0xFF) { + // Higher voltage and valid, select this instead + bestIndex = i; + bestIndexVoltage = voltage_mv; + bestIndexCurrent = current_a_x100; + bestIsPPS = false; +#ifdef MODEL_HAS_DCDC + // set limiter for wattage + powerSupplyWattageLimit = ((voltage_mv * current_a_x100) / 100 / 1000); +#endif + } + } + } + } else if ((capabilities->obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_AUGMENTED && (capabilities->obj[i] & PD_APDO_TYPE) == PD_APDO_TYPE_PPS) { + // If this is a PPS slot, calculate the max voltage in the PPS range that can we be used and maintain + uint16_t max_voltage = PD_PAV2MV(PD_APDO_PPS_MAX_VOLTAGE_GET(capabilities->obj[i])); + // uint16_t min_voltage = PD_PAV2MV(PD_APDO_PPS_MIN_VOLTAGE_GET(capabilities->obj[i])); + uint16_t max_current = PD_PAI2CA(PD_APDO_PPS_CURRENT_GET(capabilities->obj[i])); // max current in 10mA units + // Using the current and tip resistance, calculate the ideal max voltage + // if this is range, then we will work with this voltage + // if this is not in range; then max_voltage can be safely selected + int ideal_voltage_mv = (TIP_RESISTANCE * max_current); + if (ideal_voltage_mv > max_voltage) { + ideal_voltage_mv = max_voltage; // constrain + } + if (ideal_voltage_mv > (USB_PD_VMAX * 1000)) { + ideal_voltage_mv = (USB_PD_VMAX * 1000); // constrain to model max + } + if (ideal_voltage_mv > bestIndexVoltage || bestIndex == 0xFF) { + bestIndex = i; + bestIndexVoltage = ideal_voltage_mv; + bestIndexCurrent = max_current; + bestIsPPS = true; +#ifdef MODEL_HAS_DCDC + // set limiter for wattage + powerSupplyWattageLimit = ((ideal_voltage_mv * max_current) / 100 / 1000); +#endif + } + } + } + + if (bestIndex != 0xFF) { + /* We got what we wanted, so build a request for that */ + request->hdr = PD_MSGTYPE_REQUEST | PD_NUMOBJ(1); + if (bestIsPPS) { + request->obj[0] = PD_RDO_PROG_CURRENT_SET(PD_CA2PAI(bestIndexCurrent)) | PD_RDO_PROG_VOLTAGE_SET(PD_MV2PRV(bestIndexVoltage)) | PD_RDO_NO_USB_SUSPEND | PD_RDO_OBJPOS_SET(bestIndex + 1); + } else { + request->obj[0] = PD_RDO_FV_MAX_CURRENT_SET(bestIndexCurrent) | PD_RDO_FV_CURRENT_SET(bestIndexCurrent) | PD_RDO_NO_USB_SUSPEND | PD_RDO_OBJPOS_SET(bestIndex + 1); + } + // We dont do usb + // request->obj[0] |= PD_RDO_USB_COMMS; + + /* Update requested voltage */ + requested_voltage_mv = bestIndexVoltage; + + } else { + /* Nothing matched (or no configuration), so get 5 V at low current */ + request->hdr = PD_MSGTYPE_REQUEST | PD_NUMOBJ(1); + request->obj[0] = PD_RDO_FV_MAX_CURRENT_SET(DPM_MIN_CURRENT) | PD_RDO_FV_CURRENT_SET(DPM_MIN_CURRENT) | PD_RDO_NO_USB_SUSPEND | PD_RDO_OBJPOS_SET(1); + // We dont do usb + // request->obj[0] |= PD_RDO_USB_COMMS; + + /* Update requested voltage */ + requested_voltage_mv = 5000; + } + // Even if we didnt match, we return true as we would still like to handshake on 5V at the minimum + return true; +} + +void pdbs_dpm_get_sink_capability(pd_msg *cap, const bool isPD3) { + /* Keep track of how many PDOs we've added */ + // int numobj = 0; + + // /* If we have no configuration or want something other than 5 V, add a PDO + // * for vSafe5V */ + // /* Minimum current, 5 V, and higher capability. */ + // cap->obj[numobj++] = PD_PDO_TYPE_FIXED | PD_PDO_SNK_FIXED_VOLTAGE_SET(PD_MV2PDV(5000)) | PD_PDO_SNK_FIXED_CURRENT_SET(DPM_MIN_CURRENT); + + // /* Get the current we want */ + // uint16_t voltage = USB_PD_VMAX * 1000; // in mv + // if (requested_voltage_mv != 5000) { + // voltage = requested_voltage_mv; + // } + // uint16_t current = (voltage) / TIP_RESISTANCE; // In centi-amps + + // /* Add a PDO for the desired power. */ + // cap->obj[numobj++] = PD_PDO_TYPE_FIXED | PD_PDO_SNK_FIXED_VOLTAGE_SET(PD_MV2PDV(voltage)) | PD_PDO_SNK_FIXED_CURRENT_SET(current); + + // /* Get the PDO from the voltage range */ + // int8_t i = dpm_get_range_fixed_pdo_index(cap); + + // /* If it's vSafe5V, set our vSafe5V's current to what we want */ + // if (i == 0) { + // cap->obj[0] &= ~PD_PDO_SNK_FIXED_CURRENT; + // cap->obj[0] |= PD_PDO_SNK_FIXED_CURRENT_SET(current); + // } else { + // /* If we want more than 5 V, set the Higher Capability flag */ + // if (PD_MV2PDV(voltage) != PD_MV2PDV(5000)) { + // cap->obj[0] |= PD_PDO_SNK_FIXED_HIGHER_CAP; + // } + + // /* If the range PDO is a different voltage than the preferred + // * voltage, add it to the array. */ + // if (i > 0 && PD_PDO_SRC_FIXED_VOLTAGE_GET(cap->obj[i]) != PD_MV2PDV(voltage)) { + // cap->obj[numobj++] = PD_PDO_TYPE_FIXED | PD_PDO_SNK_FIXED_VOLTAGE_SET(PD_PDO_SRC_FIXED_VOLTAGE_GET(cap->obj[i])) | PD_PDO_SNK_FIXED_CURRENT_SET(PD_PDO_SRC_FIXED_CURRENT_GET(cap->obj[i])); + // } + + // /* If we have three PDOs at this point, make sure the last two are + // * sorted by voltage. */ + // if (numobj == 3 && (cap->obj[1] & PD_PDO_SNK_FIXED_VOLTAGE) > (cap->obj[2] & PD_PDO_SNK_FIXED_VOLTAGE)) { + // cap->obj[1] ^= cap->obj[2]; + // cap->obj[2] ^= cap->obj[1]; + // cap->obj[1] ^= cap->obj[2]; + // } + // /* If we're using PD 3.0, add a PPS APDO for our desired voltage */ + // if ((hdr_template & PD_HDR_SPECREV) >= PD_SPECREV_3_0) { + // cap->obj[numobj++] + // = PD_PDO_TYPE_AUGMENTED | PD_APDO_TYPE_PPS | PD_APDO_PPS_MAX_VOLTAGE_SET(PD_MV2PAV(voltage)) | PD_APDO_PPS_MIN_VOLTAGE_SET(PD_MV2PAV(voltage)) | + // PD_APDO_PPS_CURRENT_SET(PD_CA2PAI(current)); + // } + // } + + // /* Set the unconstrained power flag. */ + // if (_unconstrained_power) { + // cap->obj[0] |= PD_PDO_SNK_FIXED_UNCONSTRAINED; + // } + // /* Set the USB communications capable flag. */ + // cap->obj[0] |= PD_PDO_SNK_FIXED_USB_COMMS; + + // /* Set the Sink_Capabilities message header */ + // cap->hdr = hdr_template | PD_MSGTYPE_SINK_CAPABILITIES | PD_NUMOBJ(numobj); +} + +#endif
\ No newline at end of file diff --git a/source/Core/Drivers/USBPD.h b/source/Core/Drivers/USBPD.h new file mode 100644 index 00000000..bd41297b --- /dev/null +++ b/source/Core/Drivers/USBPD.h @@ -0,0 +1,29 @@ + +#ifndef DRIVERS_USBPD_H_ +#define DRIVERS_USBPD_H_ +#include "configuration.h" +#include <stdbool.h> +#include <stdint.h> + +#ifdef __cplusplus +#if POW_PD +class USBPowerDelivery { +public: + static bool start(); // Start the PD stack + static bool negotiationComplete(); // Has negotiation completed to a voltage > 5v + static bool negotiationInProgress(); // Is negotiation ongoing + static bool fusbPresent(); // Is the FUSB302 present on the bus + static void PPSTimerCallback(); // PPS Timer + static void IRQOccured(); // Thread callback that an irq occured + static void step(); // Iterate the step machine + static bool negotiationHasWorked(); // + static uint8_t getStateNumber(); // + +private: + // + static int detectionState; +}; +#endif + +#endif +#endif
\ No newline at end of file diff --git a/source/Core/Drivers/usb-pd b/source/Core/Drivers/usb-pd new file mode 160000 +Subproject a9ea9e9917ebd0f685a3ae630819aa015993e2e diff --git a/source/Core/Src/gui.cpp b/source/Core/Src/gui.cpp index 86864033..e0fa1a86 100644 --- a/source/Core/Src/gui.cpp +++ b/source/Core/Src/gui.cpp @@ -23,7 +23,7 @@ static void settings_displayInputMinVRange(void); #ifdef POW_QC static void settings_displayQCInputV(void); #endif -#ifdef POW_PD +#if POW_PD static void settings_displayPDNegTimeout(void); #endif #ifndef NO_SLEEP_MODE @@ -159,7 +159,7 @@ const menuitem powerMenu[] = { #ifdef POW_QC {SETTINGS_DESC(SettingsItemIndex::QCMaxVoltage), nullptr, settings_displayQCInputV, nullptr, SettingsOptions::QCIdealVoltage}, /*Voltage input*/ #endif -#ifdef POW_PD +#if POW_PD {SETTINGS_DESC(SettingsItemIndex::PDNegTimeout), nullptr, settings_displayPDNegTimeout, nullptr, SettingsOptions::PDNegTimeout}, /*PD timeout setup*/ #endif {0, nullptr, nullptr, nullptr, SettingsOptions::SettingsOptionsLength} // end of menu marker. DO NOT REMOVE @@ -336,7 +336,7 @@ static void settings_displayQCInputV(void) { #endif -#ifdef POW_PD +#if POW_PD static void settings_displayPDNegTimeout(void) { printShortDescription(SettingsItemIndex::PDNegTimeout, 5); diff --git a/source/Core/Src/main.cpp b/source/Core/Src/main.cpp index e2e891cc..a7317d61 100644 --- a/source/Core/Src/main.cpp +++ b/source/Core/Src/main.cpp @@ -48,7 +48,7 @@ int main(void) { osThreadStaticDef(PIDTask, startPIDTask, osPriorityRealtime, 0, PIDTaskStackSize, PIDTaskBuffer, &PIDTaskControlBlock); PIDTaskHandle = osThreadCreate(osThread(PIDTask), NULL); - /* definition and creation of POWTask - Power management for QC */ + /* definition and creation of POWTask - Power management for QC / PD */ osThreadStaticDef(POWTask, startPOWTask, osPriorityAboveNormal, 0, POWTaskStackSize, POWTaskBuffer, &POWTaskControlBlock); POWTaskHandle = osThreadCreate(osThread(POWTask), NULL); diff --git a/source/Core/Src/power.cpp b/source/Core/Src/power.cpp index d6665bd0..e7037882 100644 --- a/source/Core/Src/power.cpp +++ b/source/Core/Src/power.cpp @@ -49,7 +49,7 @@ uint32_t availableW10(uint8_t sample) { // R = R*10 // P therefore is in V^2*100/R*10 = W*10. uint32_t v = getInputVoltageX10(getSettingValue(SettingsOptions::VoltageDiv), sample); // 100 = 10v - uint32_t availableWattsX10 = (v * v) / tipResistance; + uint32_t availableWattsX10 = (v * v) / TIP_RESISTANCE; // However, 100% duty cycle is not possible as there is a dead time while the ADC takes a reading // Therefore need to scale available milliwats by this diff --git a/source/Core/Threads/GUIThread.cpp b/source/Core/Threads/GUIThread.cpp index ad8a7040..ad1ab694 100644 --- a/source/Core/Threads/GUIThread.cpp +++ b/source/Core/Threads/GUIThread.cpp @@ -22,8 +22,8 @@ extern "C" { #include <gui.hpp> #include <history.hpp> #include <power.hpp> -#ifdef POW_PD -#include "policy_engine.h" +#if POW_PD +#include "USBPD.h" #endif // File local variables extern uint32_t currentTempTargetDegC; @@ -724,10 +724,10 @@ void showDebugMenu(void) { } else { // We are not powered via DC, so want to display the appropriate state for PD or QC bool poweredbyPD = false; -#ifdef POW_PD - if (usb_pd_detect()) { +#if POW_PD + if (USBPowerDelivery::fusbPresent()) { // We are PD capable - if (PolicyEngine::pdHasNegotiated()) { + if (USBPowerDelivery::negotiationComplete()) { // We are powered via PD poweredbyPD = true; } @@ -782,9 +782,9 @@ void showWarnings() { warnUser(translatedString(Tr->NoAccelerometerMessage), 10 * TICKS_SECOND); } } -#ifdef POW_PD +#if POW_PD // We expect pd to be present - if (!usb_pd_detect()) { + if (!USBPowerDelivery::fusbPresent()) { if (getSettingValue(SettingsOptions::PDMissingWarningCounter) < 2) { nextSettingValue(SettingsOptions::PDMissingWarningCounter); saveSettings(); diff --git a/source/Core/Threads/MOVThread.cpp b/source/Core/Threads/MOVThread.cpp index 86c538f5..1e62a2b7 100644 --- a/source/Core/Threads/MOVThread.cpp +++ b/source/Core/Threads/MOVThread.cpp @@ -30,44 +30,49 @@ TickType_t lastMovementTime = 0; void detectAccelerometerVersion() {
DetectedAccelerometerVersion = AccelType::Scanning;
+#ifdef ACCEL_SC7
+ if (SC7A20::detect()) {
+ // Setup the SC7A20 Accelerometer
+ if (SC7A20::initalize()) {
+ DetectedAccelerometerVersion = AccelType::SC7;
+ return;
+ }
+ }
+#endif
#ifdef ACCEL_MMA
if (MMA8652FC::detect()) {
if (MMA8652FC::initalize()) {
DetectedAccelerometerVersion = AccelType::MMA;
+ return;
}
- } else
+ }
#endif
#ifdef ACCEL_LIS
- if (LIS2DH12::detect()) {
+ if (LIS2DH12::detect()) {
// Setup the ST Accelerometer
if (LIS2DH12::initalize()) {
DetectedAccelerometerVersion = AccelType::LIS;
+ return;
}
- } else
+ }
#endif
#ifdef ACCEL_BMA
- if (BMA223::detect()) {
+ if (BMA223::detect()) {
// Setup the BMA223 Accelerometer
if (BMA223::initalize()) {
DetectedAccelerometerVersion = AccelType::BMA;
+ return;
}
- } else
+ }
#endif
#ifdef ACCEL_MSA
- if (MSA301::detect()) {
+ if (MSA301::detect()) {
// Setup the MSA301 Accelerometer
if (MSA301::initalize()) {
DetectedAccelerometerVersion = AccelType::MSA;
+ return;
}
- } else
-#endif
-#ifdef ACCEL_SC7
- if (SC7A20::detect()) {
- // Setup the SC7A20 Accelerometer
- if (SC7A20::initalize()) {
- DetectedAccelerometerVersion = AccelType::SC7;
- }
- } else
+ }
#endif
{
// disable imu sensitivity
diff --git a/source/Core/Threads/POWThread.cpp b/source/Core/Threads/POWThread.cpp index edb5d3c7..d604742d 100644 --- a/source/Core/Threads/POWThread.cpp +++ b/source/Core/Threads/POWThread.cpp @@ -9,29 +9,51 @@ #include "FreeRTOS.h"
#include "QC3.h"
#include "Settings.h"
+#include "USBPD.h"
#include "cmsis_os.h"
-#include "fusbpd.h"
+#include "configuration.h"
#include "main.hpp"
#include "stdlib.h"
#include "task.h"
-// Small worker thread to handle power (mostly QC) related steps
+// Small worker thread to handle power (PD + QC) related steps
void startPOWTask(void const *argument __unused) {
- // You have to run this once we are willing to answer PD messages
- // Setting up too early can mean that we miss the ~20ms window to respond on some chargers
-#ifdef POW_PD
- if (usb_pd_detect() == true) {
- // Spawn all of the USB-C processors
- fusb302_start_processing();
- }
-#endif
- vTaskDelay(TICKS_100MS);
// Init any other misc sensors
postRToSInit();
+ // You have to run this once we are willing to answer PD messages
+ // Setting up too early can mean that we miss the ~20ms window to respond on some chargers
+#if POW_PD
+ USBPowerDelivery::start();
+ // Crank the handle at boot until we are stable and waiting for IRQ
+ USBPowerDelivery::step();
+
+#endif
+ BaseType_t res;
for (;;) {
+ res = pdFALSE;
+ // While the interrupt is low, dont delay
+ /*This is due to a possible race condition, where:
+ * IRQ fires
+ * We read interrupt register but dont see the Good CRC
+ * Then Good CRC is set while reading it out (racing on I2C read)
+ * Then we would sleep as nothing to do, but 100ms> 20ms power supply typical timeout
+ */
+ if (!getFUS302IRQLow()) {
+ res = xTaskNotifyWait(0x0, 0xFFFFFF, NULL, TICKS_100MS);
+ }
+
+#if POW_PD
+
+ if (res != pdFALSE || getFUS302IRQLow()) {
+ USBPowerDelivery::IRQOccured();
+ }
+ USBPowerDelivery::step();
+ USBPowerDelivery::PPSTimerCallback();
+#else
+ (void)res;
+#endif
power_check();
- osDelay(TICKS_100MS); // Slow down update rate
}
}
diff --git a/source/Makefile b/source/Makefile index e3337762..dfae3739 100644 --- a/source/Makefile +++ b/source/Makefile @@ -59,7 +59,6 @@ BSP_INC_DIR = ./Core/BSP THREADS_INC_DIR = ./Core/Threads
PINE_INC_DIR = ./Core/BSP/Pine64
PINE_VENDOR_INC_DIR = ./Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include
-PINE_BOARD_INC_DIR = ./Core/BSP/Pine64/Vendor/SoC/gd32vf103/Board/pinecil/Include
PINE_VENDOR_USB_INC_DIR = ./Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Include/Usb
PINE_NMSIS_INC_DIR = ./Core/BSP/Pine64/Vendor/NMSIS/Core/Include
PINE_FREERTOS_PORT_INC_DIR = ./Core/BSP/Pine64/Vendor/OS/FreeRTOS/Source/portable/GCC
@@ -67,12 +66,14 @@ SOURCE_THREADS_DIR = ./Core/Threads SOURCE_CORE_DIR = ./Core/Src
SOURCE_BRIEFLZ_DIR = ./Core/brieflz
SOURCE_DRIVERS_DIR = ./Core/Drivers
-INC_PD_DRIVERS_DIR = ./Core/Drivers/FUSB302
+INC_PD_DRIVERS_DIR = ./Core/Drivers/usb-pd/include
+PD_DRIVER_TESTS_DIR = ./Core/Drivers/usb-pd/tests
+PD_DRIVER_DIR = ./Core/Drivers/usb-pd
SOURCE_MIDDLEWARES_DIR = ./Middlewares
# Find-all's used for formatting
-ALL_INCLUDES = $(shell find ./Core -path $(BRIEFLZ_INC_DIR) -prune -false -o \( -type f \( -name '*.h' -o -name '*.hpp' \) \) )
+ALL_INCLUDES = $(shell find ./Core -type d \( -path $(BRIEFLZ_INC_DIR) -o -path $(PD_DRIVER_DIR) \) -prune -false -o \( -type f \( -name '*.h' -o -name '*.hpp' \) \) )
-ALL_SOURCE = $(shell find ./Core -path $(SOURCE_BRIEFLZ_DIR) -prune -false -o \( -type f \( -name '*.c' -o -name '*.cpp' \) \) )
+ALL_SOURCE = $(shell find ./Core -type d \( -path $(SOURCE_BRIEFLZ_DIR) -o -path $(PD_DRIVER_DIR) \) -prune -false -o \( -type f \( -name '*.c' -o -name '*.cpp' \) \) )
# Device dependent settings
ifeq ($(model),$(filter $(model),$(ALL_MINIWARE_MODELS)))
@@ -138,7 +139,6 @@ ifeq ($(model),$(ALL_PINE_MODELS)) $(info Building for Pine64 )
DEVICE_INCLUDES = -I$(PINE_INC_DIR) \
-I$(PINE_VENDOR_INC_DIR) \
--I$(PINE_BOARD_INC_DIR) \
-I$(PINE_VENDOR_USB_INC_DIR) \
-I$(PINE_NMSIS_INC_DIR) \
-I$(PINE_FREERTOS_PORT_INC_DIR)
@@ -178,9 +178,10 @@ $(shell find $(SOURCE_DRIVERS_DIR) -type f -name '*.c') \ $(shell find $(DEVICE_BSP_DIR) -type f -name '*.c') \
$(shell find $(SOURCE_MIDDLEWARES_DIR) -type f -name '*.c') \
$(SOURCE_BRIEFLZ_DIR)/depack.c
+# We exclude the USB-PD stack tests $(PD_DRIVER_TESTS_DIR)
SOURCE_CPP := $(shell find $(SOURCE_THREADS_DIR) -type f -name '*.cpp') \
$(shell find $(SOURCE_CORE_DIR) -type f -name '*.cpp') \
-$(shell find $(SOURCE_DRIVERS_DIR) -type f -name '*.cpp') \
+$(shell find $(SOURCE_DRIVERS_DIR) -path $(PD_DRIVER_TESTS_DIR) -prune -false -o -type f -name '*.cpp') \
$(shell find $(DEVICE_BSP_DIR) -type f -name '*.cpp') \
$(shell find $(SOURCE_MIDDLEWARES_DIR) -type f -name '*.cpp')
# output folder
|