Add SPDX identifier

pull/8725/head
c_jin 2018-11-21 11:38:53 +08:00
parent 5a15f810a6
commit 62e34ecb38
27 changed files with 5130 additions and 5053 deletions

View File

@ -1,72 +1,74 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* 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 MBED_PERIPHERALPINS_H
#define MBED_PERIPHERALPINS_H
#include "pinmap.h"
#include "PeripheralNames.h"
extern const int GD_GPIO_REMAP[];
extern const int GD_GPIO_MODE[];
extern const int GD_GPIO_SPEED[];
/* ADC */
#ifdef DEVICE_ANALOGIN
extern const PinMap PinMap_ADC[];
#endif
/* DAC */
#ifdef DEVICE_ANALOGOUT
extern const PinMap PinMap_DAC[];
#endif
/* I2C */
#if DEVICE_I2C
extern const PinMap PinMap_I2C_SDA[];
extern const PinMap PinMap_I2C_SCL[];
#endif
/* PWM */
#if DEVICE_PWMOUT
extern const PinMap PinMap_PWM[];
#endif
/* SERIAL */
#ifdef DEVICE_SERIAL
extern const PinMap PinMap_UART_TX[];
extern const PinMap PinMap_UART_RX[];
#ifdef DEVICE_SERIAL_FC
extern const PinMap PinMap_UART_RTS[];
extern const PinMap PinMap_UART_CTS[];
#endif
#endif
/* SPI */
#ifdef DEVICE_SPI
extern const PinMap PinMap_SPI_MOSI[];
extern const PinMap PinMap_SPI_MISO[];
extern const PinMap PinMap_SPI_SCLK[];
extern const PinMap PinMap_SPI_SSEL[];
#endif
/* CAN */
#ifdef DEVICE_CAN
extern const PinMap PinMap_CAN_RD[];
extern const PinMap PinMap_CAN_TD[];
#endif
#endif
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 MBED_PERIPHERALPINS_H
#define MBED_PERIPHERALPINS_H
#include "pinmap.h"
#include "PeripheralNames.h"
extern const int GD_GPIO_REMAP[];
extern const int GD_GPIO_MODE[];
extern const int GD_GPIO_SPEED[];
/* ADC */
#ifdef DEVICE_ANALOGIN
extern const PinMap PinMap_ADC[];
#endif
/* DAC */
#ifdef DEVICE_ANALOGOUT
extern const PinMap PinMap_DAC[];
#endif
/* I2C */
#if DEVICE_I2C
extern const PinMap PinMap_I2C_SDA[];
extern const PinMap PinMap_I2C_SCL[];
#endif
/* PWM */
#if DEVICE_PWMOUT
extern const PinMap PinMap_PWM[];
#endif
/* SERIAL */
#ifdef DEVICE_SERIAL
extern const PinMap PinMap_UART_TX[];
extern const PinMap PinMap_UART_RX[];
#ifdef DEVICE_SERIAL_FC
extern const PinMap PinMap_UART_RTS[];
extern const PinMap PinMap_UART_CTS[];
#endif
#endif
/* SPI */
#ifdef DEVICE_SPI
extern const PinMap PinMap_SPI_MOSI[];
extern const PinMap PinMap_SPI_MISO[];
extern const PinMap PinMap_SPI_SCLK[];
extern const PinMap PinMap_SPI_SSEL[];
#endif
/* CAN */
#ifdef DEVICE_CAN
extern const PinMap PinMap_CAN_RD[];
extern const PinMap PinMap_CAN_TD[];
#endif
#endif

View File

@ -1,34 +1,36 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* 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 MBED_PORTNAMES_H
#define MBED_PORTNAMES_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
PORTA = 0,
PORTB = 1,
PORTC = 2,
PORTD = 3,
PORTE = 4,
} PortName;
#ifdef __cplusplus
}
#endif
#endif
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 MBED_PORTNAMES_H
#define MBED_PORTNAMES_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
PORTA = 0,
PORTB = 1,
PORTC = 2,
PORTD = 3,
PORTE = 4,
} PortName;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,83 +1,85 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* 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 MBED_PERIPHERALNAMES_H
#define MBED_PERIPHERALNAMES_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
ADC_0 = (int)ADC0,
ADC_1 = (int)ADC1
} ADCName;
typedef enum {
DAC_0 = (int)DAC0,
DAC_1 = (int)DAC1,
} DACName;
typedef enum {
UART_0 = (int)USART0,
UART_1 = (int)USART1,
UART_2 = (int)USART2,
UART_3 = (int)UART3,
UART_4 = (int)UART4
} UARTName;
#define STDIO_UART_TX PORTA_9
#define STDIO_UART_RX PORTA_10
#define STDIO_UART UART_0
typedef enum {
SPI_0 = (int)SPI0,
SPI_1 = (int)SPI1,
SPI_2 = (int)SPI2
} SPIName;
typedef enum {
I2C_0 = (int)I2C0,
I2C_1 = (int)I2C1
} I2CName;
typedef enum {
PWM_0 = (int)TIMER0,
PWM_1 = (int)TIMER1,
PWM_2 = (int)TIMER2,
PWM_3 = (int)TIMER3,
PWM_4 = (int)TIMER4,
PWM_5 = (int)TIMER7,
PWM_6 = (int)TIMER8,
PWM_7 = (int)TIMER9,
PWM_8 = (int)TIMER10,
PWM_9 = (int)TIMER11,
PWM_10 = (int)TIMER12,
PWM_11 = (int)TIMER13
} PWMName;
typedef enum {
CAN_0 = (int)CAN0,
CAN_1 = (int)CAN1
} CANName;
#ifdef __cplusplus
}
#endif
#endif
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 MBED_PERIPHERALNAMES_H
#define MBED_PERIPHERALNAMES_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
ADC_0 = (int)ADC0,
ADC_1 = (int)ADC1
} ADCName;
typedef enum {
DAC_0 = (int)DAC0,
DAC_1 = (int)DAC1,
} DACName;
typedef enum {
UART_0 = (int)USART0,
UART_1 = (int)USART1,
UART_2 = (int)USART2,
UART_3 = (int)UART3,
UART_4 = (int)UART4
} UARTName;
#define STDIO_UART_TX PORTA_9
#define STDIO_UART_RX PORTA_10
#define STDIO_UART UART_0
typedef enum {
SPI_0 = (int)SPI0,
SPI_1 = (int)SPI1,
SPI_2 = (int)SPI2
} SPIName;
typedef enum {
I2C_0 = (int)I2C0,
I2C_1 = (int)I2C1
} I2CName;
typedef enum {
PWM_0 = (int)TIMER0,
PWM_1 = (int)TIMER1,
PWM_2 = (int)TIMER2,
PWM_3 = (int)TIMER3,
PWM_4 = (int)TIMER4,
PWM_5 = (int)TIMER7,
PWM_6 = (int)TIMER8,
PWM_7 = (int)TIMER9,
PWM_8 = (int)TIMER10,
PWM_9 = (int)TIMER11,
PWM_10 = (int)TIMER12,
PWM_11 = (int)TIMER13
} PWMName;
typedef enum {
CAN_0 = (int)CAN0,
CAN_1 = (int)CAN1
} CANName;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,356 +1,358 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* 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 "PeripheralPins.h"
/* void pin_function(PinName pin, int function);
configure the speed, mode,and remap function of pins
the parameter function contains the configuration information,show as below
bit 0:2 gpio mode
bit 3:8 remap
bit 9:10 gpio speed
bit 11:15 adc /timer channel
*/
const int GD_GPIO_REMAP[] = {
0x00000000,
GPIO_SPI0_REMAP, /* 1 */
GPIO_I2C0_REMAP, /* 2 */
GPIO_USART0_REMAP, /* 3 */
GPIO_USART1_REMAP, /* 4 */
GPIO_USART2_PARTIAL_REMAP, /* 5 */
GPIO_USART2_FULL_REMAP, /* 6 */
GPIO_TIMER0_PARTIAL_REMAP, /* 7 */
GPIO_TIMER0_FULL_REMAP, /* 8 */
GPIO_TIMER1_PARTIAL_REMAP0, /* 9 */
GPIO_TIMER1_PARTIAL_REMAP1, /* 10 */
GPIO_TIMER1_FULL_REMAP, /* 11 */
GPIO_TIMER2_PARTIAL_REMAP, /* 12 */
GPIO_TIMER2_FULL_REMAP, /* 13 */
GPIO_TIMER3_REMAP, /* 14 */
GPIO_PD01_REMAP, /* 15 */
#if (defined(GD32F30X_HD) || defined(GD32F30X_XD))
GPIO_CAN_PARTIAL_REMAP, /* 16 */
GPIO_CAN_FULL_REMAP, /* 17 */
#else
0,
0,
#endif
#if (defined(GD32F30X_CL) || defined(GD32F30X_HD))
GPIO_TIMER4CH3_IREMAP, /* 18 */
#else
0,
#endif
#if (defined(GD32F30X_HD) || defined(GD32F30X_XD))
GPIO_ADC0_ETRGINS_REMAP, /* 19 */
GPIO_ADC0_ETRGREG_REMAP, /* 20 */
GPIO_ADC1_ETRGINS_REMAP, /* 21 */
GPIO_ADC1_ETRGREG_REMAP, /* 22 */
#else
0,
0,
0,
0,
#endif
GPIO_SWJ_NONJTRST_REMAP, /* 23 */
GPIO_SWJ_SWDPENABLE_REMAP, /* 24 */
GPIO_SWJ_DISABLE_REMAP, /* 25 */
#if (defined(GD32F30X_CL))
GPIO_CAN0_PARTIAL_REMAP, /* 26 */
GPIO_CAN0_FULL_REMAP, /* 27 */
GPIO_ENET_REMAP, /* 28 */
GPIO_CAN1_REMAP, /* 29 */
GPIO_SPI2_REMAP, /* 30 */
GPIO_TIMER1ITR0_REMAP, /* 31 */
GPIO_PTP_PPS_REMAP, /* 32 */
#else
0,
0,
0,
0,
0,
0,
0,
#endif
GPIO_TIMER8_REMAP, /* 33 */
GPIO_TIMER9_REMAP, /* 34 */
GPIO_TIMER10_REMAP, /* 35 */
GPIO_TIMER12_REMAP, /* 36 */
GPIO_TIMER13_REMAP, /* 37 */
GPIO_EXMC_NADV_REMAP, /* 38 */
GPIO_CTC_REMAP0, /* 39 */
GPIO_CTC_REMAP1, /* 40 */
#if (defined(GD32F30X_CL))
GPIO_ENET_PHY_MII, /* 41 */
GPIO_ENET_PHY_RMII, /* 42 */
#else
0,
0,
#endif
};
/* GPIO MODE */
const int GD_GPIO_MODE[] = {
GPIO_MODE_AIN, /* 0 */
GPIO_MODE_IN_FLOATING, /* 1 */
GPIO_MODE_IPD, /* 2 */
GPIO_MODE_IPU, /* 3 */
GPIO_MODE_OUT_OD, /* 4 */
GPIO_MODE_OUT_PP, /* 5 */
GPIO_MODE_AF_OD, /* 6 */
GPIO_MODE_AF_PP, /* 7 */
};
/* GPIO SPEED */
const int GD_GPIO_SPEED[] = {
GPIO_OSPEED_50MHZ, /* 0 */
GPIO_OSPEED_10MHZ, /* 1 */
GPIO_OSPEED_2MHZ, /* 2 */
};
/* ADC PinMap */
const PinMap PinMap_ADC[] = {
{PORTA_0, ADC_0, 0 | (0 << 11)}, /* ADC0_IN0 */
{PORTA_1, ADC_0, 0 | (1 << 11)}, /* ADC0_IN1 */
{PORTA_2, ADC_0, 0 | (2 << 11)}, /* ADC0_IN2 */
{PORTA_3, ADC_0, 0 | (3 << 11)}, /* ADC0_IN3 */
{PORTA_4, ADC_0, 0 | (4 << 11)}, /* ADC0_IN4 */
{PORTA_5, ADC_0, 0 | (5 << 11)}, /* ADC0_IN5 */
{PORTA_6, ADC_0, 0 | (6 << 11)}, /* ADC0_IN6 */
{PORTA_7, ADC_0, 0 | (7 << 11)}, /* ADC0_IN7 */
{PORTB_0, ADC_0, 0 | (8 << 11)}, /* ADC0_IN8 */
{PORTB_1, ADC_0, 0 | (9 << 11)}, /* ADC0_IN9 */
{PORTC_0, ADC_0, 0 | (10 << 11)}, /* ADC0_IN10 */
{PORTC_1, ADC_0, 0 | (11 << 11)}, /* ADC0_IN11 */
{PORTC_2, ADC_0, 0 | (12 << 11)}, /* ADC0_IN12 */
{PORTC_3, ADC_0, 0 | (13 << 11)}, /* ADC0_IN13 */
{PORTC_4, ADC_0, 0 | (14 << 11)}, /* ADC0_IN14 */
{PORTC_5, ADC_0, 0 | (15 << 11)}, /* ADC0_IN15 */
{ADC_TEMP, ADC_0, 0 | (16 << 11)}, /* ADC0_IN16 */
{ADC_VREF, ADC_0, 0 | (17 << 11)}, /* ADC0_IN17 */
{PORTA_0_MUL0, ADC_1, 0 | (0 << 11)}, /* ADC1_IN0 */
{PORTA_1_MUL0, ADC_1, 0 | (1 << 11)}, /* ADC1_IN1 */
{PORTA_2_MUL0, ADC_1, 0 | (2 << 11)}, /* ADC1_IN2 */
{PORTA_3_MUL0, ADC_1, 0 | (3 << 11)}, /* ADC1_IN3 */
{PORTA_4_MUL0, ADC_1, 0 | (4 << 11)}, /* ADC1_IN4 */
{PORTA_5_MUL0, ADC_1, 0 | (5 << 11)}, /* ADC1_IN5 */
{PORTA_6_MUL0, ADC_1, 0 | (6 << 11)}, /* ADC1_IN6 */
{PORTA_7_MUL0, ADC_1, 0 | (7 << 11)}, /* ADC1_IN7 */
{PORTB_0_MUL0, ADC_1, 0 | (8 << 11)}, /* ADC1_IN8 */
{PORTB_1_MUL0, ADC_1, 0 | (9 << 11)}, /* ADC1_IN9 */
{PORTC_0_MUL0, ADC_1, 0 | (10 << 11)}, /* ADC1_IN10 */
{PORTC_1_MUL0, ADC_1, 0 | (11 << 11)}, /* ADC1_IN11 */
{PORTC_2_MUL0, ADC_1, 0 | (12 << 11)}, /* ADC1_IN12 */
{PORTC_3_MUL0, ADC_1, 0 | (13 << 11)}, /* ADC1_IN13 */
{PORTC_4_MUL0, ADC_1, 0 | (14 << 11)}, /* ADC1_IN14 */
{PORTC_5_MUL0, ADC_1, 0 | (15 << 11)}, /* ADC1_IN15 */
{NC, NC, 0}
};
/* DAC PinMap */
const PinMap PinMap_DAC[] = {
{PORTA_4, DAC_0, 0 | (0 << 11)}, /* DAC_OUT0 */
{PORTA_5, DAC_0, 0 | (1 << 11)}, /* DAC_OUT1 */
{NC, NC, 0}
};
/* I2C PinMap */
const PinMap PinMap_I2C_SDA[] = {
{PORTB_7, I2C_0, 6},
{PORTB_9, I2C_0, 6 | (2 << 3)}, /* GPIO_I2C0_REMAP */
{PORTB_11, I2C_1, 6},
{NC, NC, 0}
};
const PinMap PinMap_I2C_SCL[] = {
{PORTB_6, I2C_0, 6},
{PORTB_8, I2C_0, 6 | (2 << 3)}, /* GPIO_I2C0_REMAP */
{PORTB_10, I2C_1, 6},
{NC, NC, 0}
};
/* PWM PinMap */
const PinMap PinMap_PWM[] = {
{PORTA_8, PWM_0, 7 | (0 << 11)}, /* TIMER0_CH0 - Default */
{PORTA_9, PWM_0, 7 | (1 << 11)}, /* TIMER0_CH1 - Default */
{PORTA_10, PWM_0, 7 | (2 << 11)}, /* TIMER0_CH2 - Default */
{PORTA_11, PWM_0, 7 | (3 << 11)}, /* TIMER0_CH3 - Default */
{PORTE_9, PWM_0, 7 | (8 << 3) | (0 << 11)}, /* TIMER0_CH0 - GPIO_TIMER0_FULL_REMAP */
{PORTE_11, PWM_0, 7 | (8 << 3) | (1 << 11)}, /* TIMER0_CH1 - GPIO_TIMER0_FULL_REMAP */
{PORTE_13, PWM_0, 7 | (8 << 3) | (2 << 11)}, /* TIMER0_CH2 - GPIO_TIMER0_FULL_REMAP */
{PORTE_14, PWM_0, 7 | (8 << 3) | (3 << 11)}, /* TIMER0_CH3 - GPIO_TIMER0_FULL_REMAP */
{PORTA_0, PWM_1, 7 | (0 << 11)}, /* TIMER1_CH0_ETI - Default */
{PORTA_1, PWM_1, 7 | (1 << 11)}, /* TIMER1_CH1_ETI - Default */
{PORTA_2, PWM_1, 7 | (2 << 11)}, /* TIMER1_CH2_ETI - Default */
{PORTA_3, PWM_1, 7 | (3 << 11)}, /* TIMER1_CH3_ETI - Default */
{PORTA_15, PWM_1, 7 | (9 << 3) | (0 << 11)}, /* TIMER1_CH0_ETI- GPIO_TIMER1_PARTIAL_REMAP0 */
{PORTB_3, PWM_1, 7 | (9 << 3) | (1 << 11)}, /* TIMER1_CH1 - GPIO_TIMER1_PARTIAL_REMAP0 */
{PORTB_10, PWM_1, 7 | (10 << 3) | (2 << 11)}, /* TIMER1_CH2 - GPIO_TIMER1_PARTIAL_REMAP1 */
{PORTB_11, PWM_1, 7 | (10 << 3) | (3 << 11)}, /* TIMER1_CH3 - GPIO_TIMER1_PARTIAL_REMAP1 */
{PORTA_15, PWM_1, 7 | (11 << 3) | (0 << 11)}, /* TIMER1_CH0_ETI - GPIO_TIMER1_FULL_REMAP */
{PORTB_3, PWM_1, 7 | (11 << 3) | (1 << 11)}, /* TIMER1_CH1 - GPIO_TIMER1_FULL_REMAP */
{PORTB_10, PWM_1, 7 | (11 << 3) | (2 << 11)}, /* TIMER1_CH2 - GPIO_TIMER1_FULL_REMAP */
{PORTB_11, PWM_1, 7 | (11 << 3) | (3 << 11)}, /* TIMER1_CH3 - GPIO_TIMER1_FULL_REMAP */
{PORTA_6, PWM_2, 7 | (0 << 11)}, /* TIMER2_CH0 - Default */
{PORTA_7, PWM_2, 7 | (1 << 11)}, /* TIMER2_CH1 - Default */
{PORTB_0, PWM_2, 7 | (2 << 11)}, /* TIMER2_CH2 - Default */
{PORTB_1, PWM_2, 7 | (3 << 11)}, /* TIMER2_CH3 - Default */
{PORTB_4, PWM_2, 7 | (12 << 3) | (0 << 11)}, /* TIMER2_CH0 - GPIO_TIMER2_PARTIAL_REMAP */
{PORTB_5, PWM_2, 7 | (12 << 3) | (1 << 11)}, /* TIMER2_CH1 - GPIO_TIMER2_PARTIAL_REMAP */
{PORTC_6, PWM_2, 7 | (13 << 3) | (0 << 11)}, /* TIMER2_CH0 - GPIO_TIMER2_FULL_REMAP */
{PORTC_7, PWM_2, 7 | (13 << 3) | (1 << 11)}, /* TIMER2_CH1 - GPIO_TIMER2_FULL_REMAP */
{PORTC_8, PWM_2, 7 | (13 << 3) | (2 << 11)}, /* TIMER2_CH2 - GPIO_TIMER2_FULL_REMAP */
{PORTC_9, PWM_2, 7 | (13 << 3) | (3 << 11)}, /* TIMER2_CH3 - GPIO_TIMER2_FULL_REMAP */
{PORTB_6, PWM_3, 7 | (0 << 11)}, /* TIMER3_CH0 - Default */
{PORTB_7, PWM_3, 7 | (1 << 11)}, /* TIMER3_CH1 - Default */
{PORTB_8, PWM_3, 7 | (2 << 11)}, /* TIMER3_CH2 - Default */
{PORTB_9, PWM_3, 7 | (3 << 11)}, /* TIMER3_CH3 - Default */
{PORTD_12, PWM_3, 7 | (14 << 3) | (0 << 11)}, /* TIMER3_CH0 - GPIO_TIMER3_REMAP */
{PORTD_13, PWM_3, 7 | (14 << 3) | (1 << 11)}, /* TIMER3_CH1 - GPIO_TIMER3_REMAP */
{PORTD_14, PWM_3, 7 | (14 << 3) | (2 << 11)}, /* TIMER3_CH2 - GPIO_TIMER3_REMAP */
{PORTD_15, PWM_3, 7 | (14 << 3) | (3 << 11)}, /* TIMER3_CH3 - GPIO_TIMER3_REMAP */
{PORTA_0_MUL0, PWM_4, 7 | (0 << 11)}, /* TIMER4_CH0 - Default */
{PORTA_1_MUL0, PWM_4, 7 | (1 << 11)}, /* TIMER4_CH1 - Default */
{PORTA_2_MUL0, PWM_4, 7 | (2 << 11)}, /* TIMER4_CH2 - Default */
{PORTA_3_MUL0, PWM_4, 7 | (3 << 11)}, /* TIMER4_CH3 - Default */
{PORTC_6_MUL0, PWM_5, 7 | (0 << 11)}, /* TIMER7_CH0 - Default */
{PORTC_7_MUL0, PWM_5, 7 | (1 << 11)}, /* TIMER7_CH1 - Default */
{PORTC_8_MUL0, PWM_5, 7 | (2 << 11)}, /* TIMER7_CH2 - Default */
{PORTC_9_MUL0, PWM_5, 7 | (3 << 11)}, /* TIMER7_CH3 - Default */
{PORTA_2_MUL1, PWM_6, 7 | (0 << 11)}, /* TIMER8_CH0 - Default */
{PORTA_3_MUL1, PWM_6, 7 | (1 << 11)}, /* TIMER8_CH1 - Default */
{PORTE_5, PWM_6, 7 | (33 << 3) | (0 << 11)}, /* TIMER8_CH0 - GPIO_TIMER8_REMAP */
{PORTE_6, PWM_6, 7 | (33 << 3) | (1 << 11)}, /* TIMER8_CH1 - GPIO_TIMER8_REMAP */
{PORTB_8_MUL0, PWM_7, 7 | (0 << 11)}, /* TIMER9_CH0 - Default */
{PORTB_9_MUL0, PWM_8, 7 | (0 << 11)}, /* TIMER10_CH0 - Default */
{PORTB_14, PWM_9, 7 | (0 << 11)}, /* TIMER11_CH0 - Default */
{PORTB_15, PWM_9, 7 | (1 << 11)}, /* TIMER11_CH1 - Default */
{PORTA_6_MUL0, PWM_10, 7 | (0 << 11)}, /* TIMER12_CH0 - Default */
{PORTA_7_MUL0, PWM_11, 7 | (0 << 11)}, /* TIMER13_CH0 - Default */
{NC, NC, 0}
};
/* USART PinMap */
const PinMap PinMap_UART_TX[] = {
{PORTA_9, UART_0, 7},
{PORTB_6, UART_0, 7 | (3 << 3)}, /* GPIO_USART0_TX_REMAP */
{PORTA_2, UART_1, 7},
{PORTD_5, UART_1, 7 | (4 << 3)}, /* GPIO_USART1_TX_REMAP */
{PORTB_10, UART_2, 7},
{PORTC_10, UART_2, 7 | (5 << 3)}, /* GPIO_USART2_TX_PARTIAL_REMAP */
{PORTD_8, UART_2, 7 | (6 << 3)}, /* GPIO_USART2_TX_FULL_REMAP */
{PORTC_10, UART_3, 7},
{PORTC_12, UART_4, 7},
{NC, NC, 0}
};
const PinMap PinMap_UART_RX[] = {
{PORTA_10, UART_0, 1},
{PORTB_7, UART_0, 1 | (3 << 3)}, /* GPIO_USART0_RX_REMAP */
{PORTA_3, UART_1, 1},
{PORTD_6, UART_1, 1 | (4 << 3)}, /* GPIO_USART1_RX_REMAP */
{PORTB_11, UART_2, 1},
{PORTC_11, UART_2, 1 | (5 << 3)}, /* GPIO_USART2_RX_PARTIAL_REMAP */
{PORTD_9, UART_2, 1 | (6 << 3)}, /* PGPIO_USART2_RX_PARTIAL_REMAP */
{PORTC_11, UART_3, 1},
{PORTD_2, UART_4, 1},
{NC, NC, 0}
};
const PinMap PinMap_UART_RTS[] = {
{PORTA_12, UART_0, 7},
{PORTA_1, UART_1, 7},
{PORTD_4, UART_1, 7 | (4 << 3)}, /* GPIO_USART1_RTS_REMAP */
{PORTB_14, UART_2, 7},
{PORTD_12, UART_2, 7 | (6 << 3)}, /* GPIO_USART2_RTS_FULL_REMAP */
{NC, NC, 0}
};
const PinMap PinMap_UART_CTS[] = {
{PORTA_11, UART_0, 7},
{PORTA_0, UART_1, 7},
{PORTD_3, UART_1, 7 | (4 << 3)}, /* GPIO_USART1_CTS_REMAP */
{PORTB_13, UART_2, 7},
{PORTD_11, UART_2, 7 | (6 << 3)}, /* GPIO_USART2_CTS_FULL_REMAP */
{NC, NC, 0}
};
/* SPI PinMap */
const PinMap PinMap_SPI_MOSI[] = {
{PORTA_7, SPI_0, 7},
{PORTB_5, SPI_0, 7 | (1 << 3)}, /* GPIO_SPI0_REMAP */
{PORTB_15, SPI_1, 7},
{NC, NC, 0}
};
const PinMap PinMap_SPI_MISO[] = {
{PORTA_6, SPI_0, 1},
{PORTB_4, SPI_0, 7 | (1 << 3)}, /* GPIO_SPI0_REMAP */
{PORTB_14, SPI_1, 7},
{NC, NC, 0}
};
const PinMap PinMap_SPI_SCLK[] = {
{PORTA_5, SPI_0, 7},
{PORTB_3, SPI_0, 7 | (1 << 3)}, /* GPIO_SPI0_REMAP */
{PORTB_13, SPI_1, 7},
{NC, NC, 0}
};
const PinMap PinMap_SPI_SSEL[] = {
{PORTA_4, SPI_0, 7},
{PORTA_15, SPI_0, 7 | (1 << 3)}, /* GPIO_SPI0_REMAP */
{PORTB_12, SPI_1, 7},
{NC, NC, 0}
};
/* CAN PinMap */
const PinMap PinMap_CAN_RD[] = {
{PORTA_11, CAN_0, 3},
{PORTB_8, CAN_0, 3 | (26 << 3)}, /* GPIO_CAN0_PARTIAL_REMAP */
{PORTD_0, CAN_0, 3 | (27 << 3)}, /* GPIO_CAN0_FULL_REMAP */
{PORTB_12, CAN_1, 3},
{PORTB_5, CAN_1, 3 | (29 << 3)}, /* GPIO_CAN1_REMAP */
{NC, NC, 0}
};
const PinMap PinMap_CAN_TD[] = {
{PORTA_12, CAN_0, 7},
{PORTB_9, CAN_0, 7 | (26 << 3)}, /* GPIO_CAN0_PARTIAL_REMAP */
{PORTD_1, CAN_0, 7 | (27 << 3)}, /* GPIO_CAN0_FULL_REMAP */
{PORTB_13, CAN_1, 7},
{PORTB_6, CAN_1, 7 | (29 << 3)}, /* GPIO_CAN1_REMAP */
{NC, NC, 0}
};
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 "PeripheralPins.h"
/* void pin_function(PinName pin, int function);
configure the speed, mode,and remap function of pins
the parameter function contains the configuration information,show as below
bit 0:2 gpio mode
bit 3:8 remap
bit 9:10 gpio speed
bit 11:15 adc /timer channel
*/
const int GD_GPIO_REMAP[] = {
0x00000000,
GPIO_SPI0_REMAP, /* 1 */
GPIO_I2C0_REMAP, /* 2 */
GPIO_USART0_REMAP, /* 3 */
GPIO_USART1_REMAP, /* 4 */
GPIO_USART2_PARTIAL_REMAP, /* 5 */
GPIO_USART2_FULL_REMAP, /* 6 */
GPIO_TIMER0_PARTIAL_REMAP, /* 7 */
GPIO_TIMER0_FULL_REMAP, /* 8 */
GPIO_TIMER1_PARTIAL_REMAP0, /* 9 */
GPIO_TIMER1_PARTIAL_REMAP1, /* 10 */
GPIO_TIMER1_FULL_REMAP, /* 11 */
GPIO_TIMER2_PARTIAL_REMAP, /* 12 */
GPIO_TIMER2_FULL_REMAP, /* 13 */
GPIO_TIMER3_REMAP, /* 14 */
GPIO_PD01_REMAP, /* 15 */
#if (defined(GD32F30X_HD) || defined(GD32F30X_XD))
GPIO_CAN_PARTIAL_REMAP, /* 16 */
GPIO_CAN_FULL_REMAP, /* 17 */
#else
0,
0,
#endif
#if (defined(GD32F30X_CL) || defined(GD32F30X_HD))
GPIO_TIMER4CH3_IREMAP, /* 18 */
#else
0,
#endif
#if (defined(GD32F30X_HD) || defined(GD32F30X_XD))
GPIO_ADC0_ETRGINS_REMAP, /* 19 */
GPIO_ADC0_ETRGREG_REMAP, /* 20 */
GPIO_ADC1_ETRGINS_REMAP, /* 21 */
GPIO_ADC1_ETRGREG_REMAP, /* 22 */
#else
0,
0,
0,
0,
#endif
GPIO_SWJ_NONJTRST_REMAP, /* 23 */
GPIO_SWJ_SWDPENABLE_REMAP, /* 24 */
GPIO_SWJ_DISABLE_REMAP, /* 25 */
#if (defined(GD32F30X_CL))
GPIO_CAN0_PARTIAL_REMAP, /* 26 */
GPIO_CAN0_FULL_REMAP, /* 27 */
GPIO_ENET_REMAP, /* 28 */
GPIO_CAN1_REMAP, /* 29 */
GPIO_SPI2_REMAP, /* 30 */
GPIO_TIMER1ITR0_REMAP, /* 31 */
GPIO_PTP_PPS_REMAP, /* 32 */
#else
0,
0,
0,
0,
0,
0,
0,
#endif
GPIO_TIMER8_REMAP, /* 33 */
GPIO_TIMER9_REMAP, /* 34 */
GPIO_TIMER10_REMAP, /* 35 */
GPIO_TIMER12_REMAP, /* 36 */
GPIO_TIMER13_REMAP, /* 37 */
GPIO_EXMC_NADV_REMAP, /* 38 */
GPIO_CTC_REMAP0, /* 39 */
GPIO_CTC_REMAP1, /* 40 */
#if (defined(GD32F30X_CL))
GPIO_ENET_PHY_MII, /* 41 */
GPIO_ENET_PHY_RMII, /* 42 */
#else
0,
0,
#endif
};
/* GPIO MODE */
const int GD_GPIO_MODE[] = {
GPIO_MODE_AIN, /* 0 */
GPIO_MODE_IN_FLOATING, /* 1 */
GPIO_MODE_IPD, /* 2 */
GPIO_MODE_IPU, /* 3 */
GPIO_MODE_OUT_OD, /* 4 */
GPIO_MODE_OUT_PP, /* 5 */
GPIO_MODE_AF_OD, /* 6 */
GPIO_MODE_AF_PP, /* 7 */
};
/* GPIO SPEED */
const int GD_GPIO_SPEED[] = {
GPIO_OSPEED_50MHZ, /* 0 */
GPIO_OSPEED_10MHZ, /* 1 */
GPIO_OSPEED_2MHZ, /* 2 */
};
/* ADC PinMap */
const PinMap PinMap_ADC[] = {
{PORTA_0, ADC_0, 0 | (0 << 11)}, /* ADC0_IN0 */
{PORTA_1, ADC_0, 0 | (1 << 11)}, /* ADC0_IN1 */
{PORTA_2, ADC_0, 0 | (2 << 11)}, /* ADC0_IN2 */
{PORTA_3, ADC_0, 0 | (3 << 11)}, /* ADC0_IN3 */
{PORTA_4, ADC_0, 0 | (4 << 11)}, /* ADC0_IN4 */
{PORTA_5, ADC_0, 0 | (5 << 11)}, /* ADC0_IN5 */
{PORTA_6, ADC_0, 0 | (6 << 11)}, /* ADC0_IN6 */
{PORTA_7, ADC_0, 0 | (7 << 11)}, /* ADC0_IN7 */
{PORTB_0, ADC_0, 0 | (8 << 11)}, /* ADC0_IN8 */
{PORTB_1, ADC_0, 0 | (9 << 11)}, /* ADC0_IN9 */
{PORTC_0, ADC_0, 0 | (10 << 11)}, /* ADC0_IN10 */
{PORTC_1, ADC_0, 0 | (11 << 11)}, /* ADC0_IN11 */
{PORTC_2, ADC_0, 0 | (12 << 11)}, /* ADC0_IN12 */
{PORTC_3, ADC_0, 0 | (13 << 11)}, /* ADC0_IN13 */
{PORTC_4, ADC_0, 0 | (14 << 11)}, /* ADC0_IN14 */
{PORTC_5, ADC_0, 0 | (15 << 11)}, /* ADC0_IN15 */
{ADC_TEMP, ADC_0, 0 | (16 << 11)}, /* ADC0_IN16 */
{ADC_VREF, ADC_0, 0 | (17 << 11)}, /* ADC0_IN17 */
{PORTA_0_MUL0, ADC_1, 0 | (0 << 11)}, /* ADC1_IN0 */
{PORTA_1_MUL0, ADC_1, 0 | (1 << 11)}, /* ADC1_IN1 */
{PORTA_2_MUL0, ADC_1, 0 | (2 << 11)}, /* ADC1_IN2 */
{PORTA_3_MUL0, ADC_1, 0 | (3 << 11)}, /* ADC1_IN3 */
{PORTA_4_MUL0, ADC_1, 0 | (4 << 11)}, /* ADC1_IN4 */
{PORTA_5_MUL0, ADC_1, 0 | (5 << 11)}, /* ADC1_IN5 */
{PORTA_6_MUL0, ADC_1, 0 | (6 << 11)}, /* ADC1_IN6 */
{PORTA_7_MUL0, ADC_1, 0 | (7 << 11)}, /* ADC1_IN7 */
{PORTB_0_MUL0, ADC_1, 0 | (8 << 11)}, /* ADC1_IN8 */
{PORTB_1_MUL0, ADC_1, 0 | (9 << 11)}, /* ADC1_IN9 */
{PORTC_0_MUL0, ADC_1, 0 | (10 << 11)}, /* ADC1_IN10 */
{PORTC_1_MUL0, ADC_1, 0 | (11 << 11)}, /* ADC1_IN11 */
{PORTC_2_MUL0, ADC_1, 0 | (12 << 11)}, /* ADC1_IN12 */
{PORTC_3_MUL0, ADC_1, 0 | (13 << 11)}, /* ADC1_IN13 */
{PORTC_4_MUL0, ADC_1, 0 | (14 << 11)}, /* ADC1_IN14 */
{PORTC_5_MUL0, ADC_1, 0 | (15 << 11)}, /* ADC1_IN15 */
{NC, NC, 0}
};
/* DAC PinMap */
const PinMap PinMap_DAC[] = {
{PORTA_4, DAC_0, 0 | (0 << 11)}, /* DAC_OUT0 */
{PORTA_5, DAC_0, 0 | (1 << 11)}, /* DAC_OUT1 */
{NC, NC, 0}
};
/* I2C PinMap */
const PinMap PinMap_I2C_SDA[] = {
{PORTB_7, I2C_0, 6},
{PORTB_9, I2C_0, 6 | (2 << 3)}, /* GPIO_I2C0_REMAP */
{PORTB_11, I2C_1, 6},
{NC, NC, 0}
};
const PinMap PinMap_I2C_SCL[] = {
{PORTB_6, I2C_0, 6},
{PORTB_8, I2C_0, 6 | (2 << 3)}, /* GPIO_I2C0_REMAP */
{PORTB_10, I2C_1, 6},
{NC, NC, 0}
};
/* PWM PinMap */
const PinMap PinMap_PWM[] = {
{PORTA_8, PWM_0, 7 | (0 << 11)}, /* TIMER0_CH0 - Default */
{PORTA_9, PWM_0, 7 | (1 << 11)}, /* TIMER0_CH1 - Default */
{PORTA_10, PWM_0, 7 | (2 << 11)}, /* TIMER0_CH2 - Default */
{PORTA_11, PWM_0, 7 | (3 << 11)}, /* TIMER0_CH3 - Default */
{PORTE_9, PWM_0, 7 | (8 << 3) | (0 << 11)}, /* TIMER0_CH0 - GPIO_TIMER0_FULL_REMAP */
{PORTE_11, PWM_0, 7 | (8 << 3) | (1 << 11)}, /* TIMER0_CH1 - GPIO_TIMER0_FULL_REMAP */
{PORTE_13, PWM_0, 7 | (8 << 3) | (2 << 11)}, /* TIMER0_CH2 - GPIO_TIMER0_FULL_REMAP */
{PORTE_14, PWM_0, 7 | (8 << 3) | (3 << 11)}, /* TIMER0_CH3 - GPIO_TIMER0_FULL_REMAP */
{PORTA_0, PWM_1, 7 | (0 << 11)}, /* TIMER1_CH0_ETI - Default */
{PORTA_1, PWM_1, 7 | (1 << 11)}, /* TIMER1_CH1_ETI - Default */
{PORTA_2, PWM_1, 7 | (2 << 11)}, /* TIMER1_CH2_ETI - Default */
{PORTA_3, PWM_1, 7 | (3 << 11)}, /* TIMER1_CH3_ETI - Default */
{PORTA_15, PWM_1, 7 | (9 << 3) | (0 << 11)}, /* TIMER1_CH0_ETI- GPIO_TIMER1_PARTIAL_REMAP0 */
{PORTB_3, PWM_1, 7 | (9 << 3) | (1 << 11)}, /* TIMER1_CH1 - GPIO_TIMER1_PARTIAL_REMAP0 */
{PORTB_10, PWM_1, 7 | (10 << 3) | (2 << 11)}, /* TIMER1_CH2 - GPIO_TIMER1_PARTIAL_REMAP1 */
{PORTB_11, PWM_1, 7 | (10 << 3) | (3 << 11)}, /* TIMER1_CH3 - GPIO_TIMER1_PARTIAL_REMAP1 */
{PORTA_15, PWM_1, 7 | (11 << 3) | (0 << 11)}, /* TIMER1_CH0_ETI - GPIO_TIMER1_FULL_REMAP */
{PORTB_3, PWM_1, 7 | (11 << 3) | (1 << 11)}, /* TIMER1_CH1 - GPIO_TIMER1_FULL_REMAP */
{PORTB_10, PWM_1, 7 | (11 << 3) | (2 << 11)}, /* TIMER1_CH2 - GPIO_TIMER1_FULL_REMAP */
{PORTB_11, PWM_1, 7 | (11 << 3) | (3 << 11)}, /* TIMER1_CH3 - GPIO_TIMER1_FULL_REMAP */
{PORTA_6, PWM_2, 7 | (0 << 11)}, /* TIMER2_CH0 - Default */
{PORTA_7, PWM_2, 7 | (1 << 11)}, /* TIMER2_CH1 - Default */
{PORTB_0, PWM_2, 7 | (2 << 11)}, /* TIMER2_CH2 - Default */
{PORTB_1, PWM_2, 7 | (3 << 11)}, /* TIMER2_CH3 - Default */
{PORTB_4, PWM_2, 7 | (12 << 3) | (0 << 11)}, /* TIMER2_CH0 - GPIO_TIMER2_PARTIAL_REMAP */
{PORTB_5, PWM_2, 7 | (12 << 3) | (1 << 11)}, /* TIMER2_CH1 - GPIO_TIMER2_PARTIAL_REMAP */
{PORTC_6, PWM_2, 7 | (13 << 3) | (0 << 11)}, /* TIMER2_CH0 - GPIO_TIMER2_FULL_REMAP */
{PORTC_7, PWM_2, 7 | (13 << 3) | (1 << 11)}, /* TIMER2_CH1 - GPIO_TIMER2_FULL_REMAP */
{PORTC_8, PWM_2, 7 | (13 << 3) | (2 << 11)}, /* TIMER2_CH2 - GPIO_TIMER2_FULL_REMAP */
{PORTC_9, PWM_2, 7 | (13 << 3) | (3 << 11)}, /* TIMER2_CH3 - GPIO_TIMER2_FULL_REMAP */
{PORTB_6, PWM_3, 7 | (0 << 11)}, /* TIMER3_CH0 - Default */
{PORTB_7, PWM_3, 7 | (1 << 11)}, /* TIMER3_CH1 - Default */
{PORTB_8, PWM_3, 7 | (2 << 11)}, /* TIMER3_CH2 - Default */
{PORTB_9, PWM_3, 7 | (3 << 11)}, /* TIMER3_CH3 - Default */
{PORTD_12, PWM_3, 7 | (14 << 3) | (0 << 11)}, /* TIMER3_CH0 - GPIO_TIMER3_REMAP */
{PORTD_13, PWM_3, 7 | (14 << 3) | (1 << 11)}, /* TIMER3_CH1 - GPIO_TIMER3_REMAP */
{PORTD_14, PWM_3, 7 | (14 << 3) | (2 << 11)}, /* TIMER3_CH2 - GPIO_TIMER3_REMAP */
{PORTD_15, PWM_3, 7 | (14 << 3) | (3 << 11)}, /* TIMER3_CH3 - GPIO_TIMER3_REMAP */
{PORTA_0_MUL0, PWM_4, 7 | (0 << 11)}, /* TIMER4_CH0 - Default */
{PORTA_1_MUL0, PWM_4, 7 | (1 << 11)}, /* TIMER4_CH1 - Default */
{PORTA_2_MUL0, PWM_4, 7 | (2 << 11)}, /* TIMER4_CH2 - Default */
{PORTA_3_MUL0, PWM_4, 7 | (3 << 11)}, /* TIMER4_CH3 - Default */
{PORTC_6_MUL0, PWM_5, 7 | (0 << 11)}, /* TIMER7_CH0 - Default */
{PORTC_7_MUL0, PWM_5, 7 | (1 << 11)}, /* TIMER7_CH1 - Default */
{PORTC_8_MUL0, PWM_5, 7 | (2 << 11)}, /* TIMER7_CH2 - Default */
{PORTC_9_MUL0, PWM_5, 7 | (3 << 11)}, /* TIMER7_CH3 - Default */
{PORTA_2_MUL1, PWM_6, 7 | (0 << 11)}, /* TIMER8_CH0 - Default */
{PORTA_3_MUL1, PWM_6, 7 | (1 << 11)}, /* TIMER8_CH1 - Default */
{PORTE_5, PWM_6, 7 | (33 << 3) | (0 << 11)}, /* TIMER8_CH0 - GPIO_TIMER8_REMAP */
{PORTE_6, PWM_6, 7 | (33 << 3) | (1 << 11)}, /* TIMER8_CH1 - GPIO_TIMER8_REMAP */
{PORTB_8_MUL0, PWM_7, 7 | (0 << 11)}, /* TIMER9_CH0 - Default */
{PORTB_9_MUL0, PWM_8, 7 | (0 << 11)}, /* TIMER10_CH0 - Default */
{PORTB_14, PWM_9, 7 | (0 << 11)}, /* TIMER11_CH0 - Default */
{PORTB_15, PWM_9, 7 | (1 << 11)}, /* TIMER11_CH1 - Default */
{PORTA_6_MUL0, PWM_10, 7 | (0 << 11)}, /* TIMER12_CH0 - Default */
{PORTA_7_MUL0, PWM_11, 7 | (0 << 11)}, /* TIMER13_CH0 - Default */
{NC, NC, 0}
};
/* USART PinMap */
const PinMap PinMap_UART_TX[] = {
{PORTA_9, UART_0, 7},
{PORTB_6, UART_0, 7 | (3 << 3)}, /* GPIO_USART0_TX_REMAP */
{PORTA_2, UART_1, 7},
{PORTD_5, UART_1, 7 | (4 << 3)}, /* GPIO_USART1_TX_REMAP */
{PORTB_10, UART_2, 7},
{PORTC_10, UART_2, 7 | (5 << 3)}, /* GPIO_USART2_TX_PARTIAL_REMAP */
{PORTD_8, UART_2, 7 | (6 << 3)}, /* GPIO_USART2_TX_FULL_REMAP */
{PORTC_10, UART_3, 7},
{PORTC_12, UART_4, 7},
{NC, NC, 0}
};
const PinMap PinMap_UART_RX[] = {
{PORTA_10, UART_0, 1},
{PORTB_7, UART_0, 1 | (3 << 3)}, /* GPIO_USART0_RX_REMAP */
{PORTA_3, UART_1, 1},
{PORTD_6, UART_1, 1 | (4 << 3)}, /* GPIO_USART1_RX_REMAP */
{PORTB_11, UART_2, 1},
{PORTC_11, UART_2, 1 | (5 << 3)}, /* GPIO_USART2_RX_PARTIAL_REMAP */
{PORTD_9, UART_2, 1 | (6 << 3)}, /* PGPIO_USART2_RX_PARTIAL_REMAP */
{PORTC_11, UART_3, 1},
{PORTD_2, UART_4, 1},
{NC, NC, 0}
};
const PinMap PinMap_UART_RTS[] = {
{PORTA_12, UART_0, 7},
{PORTA_1, UART_1, 7},
{PORTD_4, UART_1, 7 | (4 << 3)}, /* GPIO_USART1_RTS_REMAP */
{PORTB_14, UART_2, 7},
{PORTD_12, UART_2, 7 | (6 << 3)}, /* GPIO_USART2_RTS_FULL_REMAP */
{NC, NC, 0}
};
const PinMap PinMap_UART_CTS[] = {
{PORTA_11, UART_0, 7},
{PORTA_0, UART_1, 7},
{PORTD_3, UART_1, 7 | (4 << 3)}, /* GPIO_USART1_CTS_REMAP */
{PORTB_13, UART_2, 7},
{PORTD_11, UART_2, 7 | (6 << 3)}, /* GPIO_USART2_CTS_FULL_REMAP */
{NC, NC, 0}
};
/* SPI PinMap */
const PinMap PinMap_SPI_MOSI[] = {
{PORTA_7, SPI_0, 7},
{PORTB_5, SPI_0, 7 | (1 << 3)}, /* GPIO_SPI0_REMAP */
{PORTB_15, SPI_1, 7},
{NC, NC, 0}
};
const PinMap PinMap_SPI_MISO[] = {
{PORTA_6, SPI_0, 1},
{PORTB_4, SPI_0, 7 | (1 << 3)}, /* GPIO_SPI0_REMAP */
{PORTB_14, SPI_1, 7},
{NC, NC, 0}
};
const PinMap PinMap_SPI_SCLK[] = {
{PORTA_5, SPI_0, 7},
{PORTB_3, SPI_0, 7 | (1 << 3)}, /* GPIO_SPI0_REMAP */
{PORTB_13, SPI_1, 7},
{NC, NC, 0}
};
const PinMap PinMap_SPI_SSEL[] = {
{PORTA_4, SPI_0, 7},
{PORTA_15, SPI_0, 7 | (1 << 3)}, /* GPIO_SPI0_REMAP */
{PORTB_12, SPI_1, 7},
{NC, NC, 0}
};
/* CAN PinMap */
const PinMap PinMap_CAN_RD[] = {
{PORTA_11, CAN_0, 3},
{PORTB_8, CAN_0, 3 | (26 << 3)}, /* GPIO_CAN0_PARTIAL_REMAP */
{PORTD_0, CAN_0, 3 | (27 << 3)}, /* GPIO_CAN0_FULL_REMAP */
{PORTB_12, CAN_1, 3},
{PORTB_5, CAN_1, 3 | (29 << 3)}, /* GPIO_CAN1_REMAP */
{NC, NC, 0}
};
const PinMap PinMap_CAN_TD[] = {
{PORTA_12, CAN_0, 7},
{PORTB_9, CAN_0, 7 | (26 << 3)}, /* GPIO_CAN0_PARTIAL_REMAP */
{PORTD_1, CAN_0, 7 | (27 << 3)}, /* GPIO_CAN0_FULL_REMAP */
{PORTB_13, CAN_1, 7},
{PORTB_6, CAN_1, 7 | (29 << 3)}, /* GPIO_CAN1_REMAP */
{NC, NC, 0}
};

View File

@ -1,237 +1,239 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* 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 MBED_PINNAMES_H
#define MBED_PINNAMES_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Multiplex GPIO flag*/
typedef enum {
MUL0 = 0x100,
MUL1 = 0x200,
MUL2 = 0x300,
MUL3 = 0x400
} MULx;
typedef enum {
PORTA_0 = 0x00,
PORTA_0_MUL0 = PORTA_0 | MUL0,
PORTA_1 = 0x01,
PORTA_1_MUL0 = PORTA_1 | MUL0,
PORTA_2 = 0x02,
PORTA_2_MUL0 = PORTA_2 | MUL0,
PORTA_2_MUL1 = PORTA_2 | MUL1,
PORTA_3 = 0x03,
PORTA_3_MUL0 = PORTA_3 | MUL0,
PORTA_3_MUL1 = PORTA_3 | MUL1,
PORTA_4 = 0x04,
PORTA_4_MUL0 = PORTA_4 | MUL0,
PORTA_5 = 0x05,
PORTA_5_MUL0 = PORTA_5 | MUL0,
PORTA_6 = 0x06,
PORTA_6_MUL0 = PORTA_6 | MUL0,
PORTA_7 = 0x07,
PORTA_7_MUL0 = PORTA_7 | MUL0,
PORTA_8 = 0x08,
PORTA_9 = 0x09,
PORTA_10 = 0x0A,
PORTA_11 = 0x0B,
PORTA_12 = 0x0C,
PORTA_13 = 0x0D,
PORTA_14 = 0x0E,
PORTA_15 = 0x0F,
PORTB_0 = 0x10,
PORTB_0_MUL0 = PORTB_0 | MUL0,
PORTB_1 = 0x11,
PORTB_1_MUL0 = PORTB_1 | MUL0,
PORTB_2 = 0x12,
PORTB_3 = 0x13,
PORTB_4 = 0x14,
PORTB_5 = 0x15,
PORTB_6 = 0x16,
PORTB_7 = 0x17,
PORTB_8 = 0x18,
PORTB_8_MUL0 = PORTB_8 | MUL0,
PORTB_9 = 0x19,
PORTB_9_MUL0 = PORTB_9 | MUL0,
PORTB_10 = 0x1A,
PORTB_11 = 0x1B,
PORTB_12 = 0x1C,
PORTB_13 = 0x1D,
PORTB_14 = 0x1E,
PORTB_15 = 0x1F,
PORTC_0 = 0x20,
PORTC_0_MUL0 = PORTC_0 | MUL0,
PORTC_1 = 0x21,
PORTC_1_MUL0 = PORTC_1 | MUL0,
PORTC_2 = 0x22,
PORTC_2_MUL0 = PORTC_2 | MUL0,
PORTC_3 = 0x23,
PORTC_3_MUL0 = PORTC_3 | MUL0,
PORTC_4 = 0x24,
PORTC_4_MUL0 = PORTC_4 | MUL0,
PORTC_5 = 0x25,
PORTC_5_MUL0 = PORTC_5 | MUL0,
PORTC_6 = 0x26,
PORTC_6_MUL0 = PORTC_6 | MUL0,
PORTC_7 = 0x27,
PORTC_7_MUL0 = PORTC_7 | MUL0,
PORTC_8 = 0x28,
PORTC_8_MUL0 = PORTC_8 | MUL0,
PORTC_9 = 0x29,
PORTC_9_MUL0 = PORTC_9 | MUL0,
PORTC_10 = 0x2A,
PORTC_11 = 0x2B,
PORTC_12 = 0x2C,
PORTC_13 = 0x2D,
PORTC_14 = 0x2E,
PORTC_15 = 0x2F,
PORTD_0 = 0x30,
PORTD_1 = 0x31,
PORTD_2 = 0x32,
PORTD_3 = 0x33,
PORTD_4 = 0x34,
PORTD_5 = 0x35,
PORTD_6 = 0x36,
PORTD_7 = 0x37,
PORTD_8 = 0x38,
PORTD_9 = 0x39,
PORTD_10 = 0x3A,
PORTD_11 = 0x3B,
PORTD_12 = 0x3C,
PORTD_13 = 0x3D,
PORTD_14 = 0x3E,
PORTD_15 = 0x3F,
PORTE_0 = 0x40,
PORTE_1 = 0x41,
PORTE_2 = 0x42,
PORTE_3 = 0x43,
PORTE_4 = 0x44,
PORTE_5 = 0x45,
PORTE_6 = 0x46,
PORTE_7 = 0x47,
PORTE_8 = 0x48,
PORTE_9 = 0x49,
PORTE_10 = 0x4A,
PORTE_11 = 0x4B,
PORTE_12 = 0x4C,
PORTE_13 = 0x4D,
PORTE_14 = 0x4E,
PORTE_15 = 0x4F,
/* ADC internal channels */
ADC_TEMP = 0xF0,
ADC_VREF = 0xF1,
/* Arduino connector namings */
A0 = PORTC_0,
A1 = PORTC_1,
A2 = PORTC_2,
A3 = PORTC_3,
A4 = PORTC_4,
A4_I2C_SDA = PORTC_11,
A4_I2C_SCL = PORTC_10,
A5 = PORTC_5,
D0 = PORTA_3,
D1 = PORTA_2,
D2 = PORTA_4,
D3 = PORTC_6,
D4 = PORTB_3,
D5 = PORTC_7,
D6 = PORTC_8,
D7 = PORTB_4,
D8 = PORTB_5,
D9 = PORTC_9,
D10 = PORTA_1,
D11 = PORTB_15,
D12 = PORTB_14,
D13 = PORTB_13,
D14 = PORTB_9,
D15 = PORTB_8,
LED1 = PORTE_0,
LED2 = PORTE_1,
LED3 = PORTE_6,
KEY2 = PORTA_0,
KEY3 = PORTB_1,
BUTTON1 = KEY2,
BUTTON2 = KEY3,
SERIAL_TX = PORTA_9,
SERIAL_RX = PORTA_10,
USBTX = PORTA_9,
USBRX = PORTA_10,
I2C_SCL = PORTB_6,
I2C_SDA = PORTB_7,
SPI_MOSI = PORTA_7,
SPI_MISO = PORTA_6,
SPI_SCK = PORTA_5,
SPI_CS = PORTE_3,
PWM_OUT = PORTA_7,
NC = (int)0xFFFFFFFF
} PinName;
/* BIT[7:4] port number (0=PORTA, 1=PORTB, 2=PORTC, 3=PORTD, 4=PORTE, 5=PORTF)
BIT[3:0] pin number */
#define GD_PORT_GET(X) (((uint32_t)(X) >> 4) & 0xF)
#define GD_PIN_GET(X) (((uint32_t)(X) & 0xF))
/* Get mode,speed,remap function,channel of GPIO pin */
#define GD_PIN_MODE_GET(X) (X & 0x07)
#define GD_PIN_SPEED_GET(X) ((X >> 9) & 0x03)
#define GD_PIN_REMAP_GET(X) ((X >> 3) & 0x3F)
#define GD_PIN_CHANNEL_GET(X) ((X >> 11) & 0x0F)
/* Defines GPIO pin direction */
typedef enum {
PIN_INPUT = 0,
PIN_OUTPUT
} PinDirection;
/* Defines mode types of GPIO pin */
typedef enum {
MODE_AIN = 0,
MODE_IN_FLOATING,
MODE_IPD,
MODE_IPU,
MODE_OUT_OD,
MODE_OUT_PP,
MODE_AF_OD,
MODE_AF_PP,
PullDefault = MODE_IN_FLOATING,
PullUp = MODE_IPU,
PullDown = MODE_IPD,
PullNone = 11
} PinMode;
#ifdef __cplusplus
}
#endif
#endif
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 MBED_PINNAMES_H
#define MBED_PINNAMES_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Multiplex GPIO flag*/
typedef enum {
MUL0 = 0x100,
MUL1 = 0x200,
MUL2 = 0x300,
MUL3 = 0x400
} MULx;
typedef enum {
PORTA_0 = 0x00,
PORTA_0_MUL0 = PORTA_0 | MUL0,
PORTA_1 = 0x01,
PORTA_1_MUL0 = PORTA_1 | MUL0,
PORTA_2 = 0x02,
PORTA_2_MUL0 = PORTA_2 | MUL0,
PORTA_2_MUL1 = PORTA_2 | MUL1,
PORTA_3 = 0x03,
PORTA_3_MUL0 = PORTA_3 | MUL0,
PORTA_3_MUL1 = PORTA_3 | MUL1,
PORTA_4 = 0x04,
PORTA_4_MUL0 = PORTA_4 | MUL0,
PORTA_5 = 0x05,
PORTA_5_MUL0 = PORTA_5 | MUL0,
PORTA_6 = 0x06,
PORTA_6_MUL0 = PORTA_6 | MUL0,
PORTA_7 = 0x07,
PORTA_7_MUL0 = PORTA_7 | MUL0,
PORTA_8 = 0x08,
PORTA_9 = 0x09,
PORTA_10 = 0x0A,
PORTA_11 = 0x0B,
PORTA_12 = 0x0C,
PORTA_13 = 0x0D,
PORTA_14 = 0x0E,
PORTA_15 = 0x0F,
PORTB_0 = 0x10,
PORTB_0_MUL0 = PORTB_0 | MUL0,
PORTB_1 = 0x11,
PORTB_1_MUL0 = PORTB_1 | MUL0,
PORTB_2 = 0x12,
PORTB_3 = 0x13,
PORTB_4 = 0x14,
PORTB_5 = 0x15,
PORTB_6 = 0x16,
PORTB_7 = 0x17,
PORTB_8 = 0x18,
PORTB_8_MUL0 = PORTB_8 | MUL0,
PORTB_9 = 0x19,
PORTB_9_MUL0 = PORTB_9 | MUL0,
PORTB_10 = 0x1A,
PORTB_11 = 0x1B,
PORTB_12 = 0x1C,
PORTB_13 = 0x1D,
PORTB_14 = 0x1E,
PORTB_15 = 0x1F,
PORTC_0 = 0x20,
PORTC_0_MUL0 = PORTC_0 | MUL0,
PORTC_1 = 0x21,
PORTC_1_MUL0 = PORTC_1 | MUL0,
PORTC_2 = 0x22,
PORTC_2_MUL0 = PORTC_2 | MUL0,
PORTC_3 = 0x23,
PORTC_3_MUL0 = PORTC_3 | MUL0,
PORTC_4 = 0x24,
PORTC_4_MUL0 = PORTC_4 | MUL0,
PORTC_5 = 0x25,
PORTC_5_MUL0 = PORTC_5 | MUL0,
PORTC_6 = 0x26,
PORTC_6_MUL0 = PORTC_6 | MUL0,
PORTC_7 = 0x27,
PORTC_7_MUL0 = PORTC_7 | MUL0,
PORTC_8 = 0x28,
PORTC_8_MUL0 = PORTC_8 | MUL0,
PORTC_9 = 0x29,
PORTC_9_MUL0 = PORTC_9 | MUL0,
PORTC_10 = 0x2A,
PORTC_11 = 0x2B,
PORTC_12 = 0x2C,
PORTC_13 = 0x2D,
PORTC_14 = 0x2E,
PORTC_15 = 0x2F,
PORTD_0 = 0x30,
PORTD_1 = 0x31,
PORTD_2 = 0x32,
PORTD_3 = 0x33,
PORTD_4 = 0x34,
PORTD_5 = 0x35,
PORTD_6 = 0x36,
PORTD_7 = 0x37,
PORTD_8 = 0x38,
PORTD_9 = 0x39,
PORTD_10 = 0x3A,
PORTD_11 = 0x3B,
PORTD_12 = 0x3C,
PORTD_13 = 0x3D,
PORTD_14 = 0x3E,
PORTD_15 = 0x3F,
PORTE_0 = 0x40,
PORTE_1 = 0x41,
PORTE_2 = 0x42,
PORTE_3 = 0x43,
PORTE_4 = 0x44,
PORTE_5 = 0x45,
PORTE_6 = 0x46,
PORTE_7 = 0x47,
PORTE_8 = 0x48,
PORTE_9 = 0x49,
PORTE_10 = 0x4A,
PORTE_11 = 0x4B,
PORTE_12 = 0x4C,
PORTE_13 = 0x4D,
PORTE_14 = 0x4E,
PORTE_15 = 0x4F,
/* ADC internal channels */
ADC_TEMP = 0xF0,
ADC_VREF = 0xF1,
/* Arduino connector namings */
A0 = PORTC_0,
A1 = PORTC_1,
A2 = PORTC_2,
A3 = PORTC_3,
A4 = PORTC_4,
A4_I2C_SDA = PORTC_11,
A4_I2C_SCL = PORTC_10,
A5 = PORTC_5,
D0 = PORTA_3,
D1 = PORTA_2,
D2 = PORTA_4,
D3 = PORTC_6,
D4 = PORTB_3,
D5 = PORTC_7,
D6 = PORTC_8,
D7 = PORTB_4,
D8 = PORTB_5,
D9 = PORTC_9,
D10 = PORTA_1,
D11 = PORTB_15,
D12 = PORTB_14,
D13 = PORTB_13,
D14 = PORTB_9,
D15 = PORTB_8,
LED1 = PORTE_0,
LED2 = PORTE_1,
LED3 = PORTE_6,
KEY2 = PORTA_0,
KEY3 = PORTB_1,
BUTTON1 = KEY2,
BUTTON2 = KEY3,
SERIAL_TX = PORTA_9,
SERIAL_RX = PORTA_10,
USBTX = PORTA_9,
USBRX = PORTA_10,
I2C_SCL = PORTB_6,
I2C_SDA = PORTB_7,
SPI_MOSI = PORTA_7,
SPI_MISO = PORTA_6,
SPI_SCK = PORTA_5,
SPI_CS = PORTE_3,
PWM_OUT = PORTA_7,
NC = (int)0xFFFFFFFF
} PinName;
/* BIT[7:4] port number (0=PORTA, 1=PORTB, 2=PORTC, 3=PORTD, 4=PORTE, 5=PORTF)
BIT[3:0] pin number */
#define GD_PORT_GET(X) (((uint32_t)(X) >> 4) & 0xF)
#define GD_PIN_GET(X) (((uint32_t)(X) & 0xF))
/* Get mode,speed,remap function,channel of GPIO pin */
#define GD_PIN_MODE_GET(X) (X & 0x07)
#define GD_PIN_SPEED_GET(X) ((X >> 9) & 0x03)
#define GD_PIN_REMAP_GET(X) ((X >> 3) & 0x3F)
#define GD_PIN_CHANNEL_GET(X) ((X >> 11) & 0x0F)
/* Defines GPIO pin direction */
typedef enum {
PIN_INPUT = 0,
PIN_OUTPUT
} PinDirection;
/* Defines mode types of GPIO pin */
typedef enum {
MODE_AIN = 0,
MODE_IN_FLOATING,
MODE_IPD,
MODE_IPU,
MODE_OUT_OD,
MODE_OUT_PP,
MODE_AF_OD,
MODE_AF_PP,
PullDefault = MODE_IN_FLOATING,
PullUp = MODE_IPU,
PullDown = MODE_IPD,
PullNone = 11
} PinMode;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,13 +1,38 @@
/* mbed Microcontroller Library - CMSIS
* Copyright (C) 2009-2018 ARM Limited. All rights reserved.
*
* A generic CMSIS include header, pulling in GD32F307VG specifics
*/
#ifndef MBED_CMSIS_H
#define MBED_CMSIS_H
#include "gd32f30x.h"
#include "cmsis_nvic.h"
#endif /* MBED_CMSIS_H */
/* mbed Microcontroller Library
* A generic CMSIS include header
Copyright (c) 2018, GigaDevice Semiconductor Inc. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
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 MBED_CMSIS_H
#define MBED_CMSIS_H
#include "gd32f30x.h"
#include "cmsis_nvic.h"
#endif /* MBED_CMSIS_H */

View File

@ -1,39 +1,41 @@
/* mbed Microcontroller Library
* CMSIS-style functionality to support dynamic vectors
*******************************************************************************
* Copyright (c) 2011 ARM Limited. All rights reserved.
* All rights reserved.
*
* 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 ARM Limited 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 MBED_CMSIS_NVIC_H
#define MBED_CMSIS_NVIC_H
#define NVIC_NUM_VECTORS (16 + 68) /* ARM CORE:16 Vectors; MCU Peripherals:68 Vectors */
#define NVIC_RAM_VECTOR_ADDRESS 0x20000000
#endif /* MBED_CMSIS_NVIC_H */
/* mbed Microcontroller Library
* CMSIS-style functionality to support dynamic vectors
*******************************************************************************
* Copyright (c) 2011 ARM Limited. All rights reserved.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 ARM Limited 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 MBED_CMSIS_NVIC_H
#define MBED_CMSIS_NVIC_H
#define NVIC_NUM_VECTORS (16 + 68) /* ARM CORE:16 Vectors; MCU Peripherals:68 Vectors */
#define NVIC_RAM_VECTOR_ADDRESS 0x20000000
#endif /* MBED_CMSIS_NVIC_H */

View File

@ -1,6 +1,8 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at

View File

@ -1,146 +1,148 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* 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 "mbed_assert.h"
#include "analogin_api.h"
#if DEVICE_ANALOGIN
#include "cmsis.h"
#include "pinmap.h"
#include "PeripheralPins.h"
#include "mbed_error.h"
#define DEV_ADC_ACCURACY_12BIT 0xFFF
#define DEV_ADC_PRECISION_12TO16(val) ((val << 4)| ((val >> 8) & (uint16_t)0x000F))
/** Initialize the analogin peripheral
*
* Configures the pin used by analogin.
* @param obj The analogin object to initialize
* @param pin The analogin pin name
*/
void analogin_init(analogin_t *obj, PinName pin)
{
uint32_t periph;
MBED_ASSERT(obj);
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
MBED_ASSERT(obj->adc != (ADCName)NC);
uint32_t function = pinmap_function(pin, PinMap_ADC);
MBED_ASSERT(function != (uint32_t)NC);
obj->channel = GD_PIN_CHANNEL_GET(function);
MBED_ASSERT(obj->channel <= ADC_CHANNEL_17);
obj->pin = pin;
if ((ADC_CHANNEL_17 == obj->channel) || (ADC_CHANNEL_16 == obj->channel)) {
/* no need to config port */
} else {
pinmap_pinout(pin, PinMap_ADC);
}
periph = obj->adc;
/* when pin >= ADC_TEMP, it indicates that the channel has no external pins */
if (pin < ADC_TEMP) {
pinmap_pinout(pin, PinMap_ADC);
}
/* ADC clock enable */
switch (periph) {
case ADC0:
rcu_periph_clock_enable(RCU_ADC0);
break;
case ADC1:
rcu_periph_clock_enable(RCU_ADC1);
break;
#ifndef GD32F30X_CL
case ADC2:
rcu_periph_clock_enable(RCU_ADC2);
break;
#endif /* GD32F30X_CL */
}
/* ADC clock cannot be greater than 42M */
rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV6);
/* ADC configuration */
adc_data_alignment_config(obj->adc, ADC_DATAALIGN_RIGHT);
adc_channel_length_config(obj->adc, ADC_REGULAR_CHANNEL, 1);
adc_special_function_config(obj->adc, ADC_SCAN_MODE, DISABLE);
adc_special_function_config(obj->adc, ADC_CONTINUOUS_MODE, DISABLE);
adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);
adc_external_trigger_source_config(obj->adc, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);
/* ADC enable */
adc_enable(obj->adc);
adc_calibration_enable(obj->adc);
}
/** Read the value from analogin pin, represented as an unsigned 16bit value
*
* @param obj The analogin object
* @return An unsigned 16bit value representing the current input voltage
*/
uint16_t analogin_read_u16(analogin_t *obj)
{
uint16_t reval;
adc_regular_channel_config(obj->adc, 0, obj->channel, ADC_SAMPLETIME_7POINT5);
adc_flag_clear(obj->adc, ADC_FLAG_EOC);
/* start Conversion */
adc_software_trigger_enable(obj->adc, ADC_REGULAR_CHANNEL);
while (SET != adc_flag_get(obj->adc, ADC_FLAG_EOC)) {
}
/* ADC actual accuracy is 12 bits */
reval = adc_regular_data_read(obj->adc);
reval = DEV_ADC_PRECISION_12TO16(reval);
return reval;
}
/** Read the input voltage, represented as a float in the range [0.0, 1.0]
*
* @param obj The analogin object
* @return A floating value representing the current input voltage
*/
float analogin_read(analogin_t *obj)
{
uint16_t reval;
adc_regular_channel_config(obj->adc, 0, obj->channel, ADC_SAMPLETIME_7POINT5);
adc_flag_clear(obj->adc, ADC_FLAG_EOC);
/* start Conversion */
adc_software_trigger_enable(obj->adc, ADC_REGULAR_CHANNEL);
/* wait for conversion to complete */
while (SET != adc_flag_get(obj->adc, ADC_FLAG_EOC)) {
}
/* ADC actual accuracy is 12 bits */
reval = adc_regular_data_read(obj->adc);
return (float)reval * (1.0f / (float)DEV_ADC_ACCURACY_12BIT);
}
#endif /* DEVICE_ANALOGIN */
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 "mbed_assert.h"
#include "analogin_api.h"
#if DEVICE_ANALOGIN
#include "cmsis.h"
#include "pinmap.h"
#include "PeripheralPins.h"
#include "mbed_error.h"
#define DEV_ADC_ACCURACY_12BIT 0xFFF
#define DEV_ADC_PRECISION_12TO16(val) ((val << 4)| ((val >> 8) & (uint16_t)0x000F))
/** Initialize the analogin peripheral
*
* Configures the pin used by analogin.
* @param obj The analogin object to initialize
* @param pin The analogin pin name
*/
void analogin_init(analogin_t *obj, PinName pin)
{
uint32_t periph;
MBED_ASSERT(obj);
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
MBED_ASSERT(obj->adc != (ADCName)NC);
uint32_t function = pinmap_function(pin, PinMap_ADC);
MBED_ASSERT(function != (uint32_t)NC);
obj->channel = GD_PIN_CHANNEL_GET(function);
MBED_ASSERT(obj->channel <= ADC_CHANNEL_17);
obj->pin = pin;
if ((ADC_CHANNEL_17 == obj->channel) || (ADC_CHANNEL_16 == obj->channel)) {
/* no need to config port */
} else {
pinmap_pinout(pin, PinMap_ADC);
}
periph = obj->adc;
/* when pin >= ADC_TEMP, it indicates that the channel has no external pins */
if (pin < ADC_TEMP) {
pinmap_pinout(pin, PinMap_ADC);
}
/* ADC clock enable */
switch (periph) {
case ADC0:
rcu_periph_clock_enable(RCU_ADC0);
break;
case ADC1:
rcu_periph_clock_enable(RCU_ADC1);
break;
#ifndef GD32F30X_CL
case ADC2:
rcu_periph_clock_enable(RCU_ADC2);
break;
#endif /* GD32F30X_CL */
}
/* ADC clock cannot be greater than 42M */
rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV6);
/* ADC configuration */
adc_data_alignment_config(obj->adc, ADC_DATAALIGN_RIGHT);
adc_channel_length_config(obj->adc, ADC_REGULAR_CHANNEL, 1);
adc_special_function_config(obj->adc, ADC_SCAN_MODE, DISABLE);
adc_special_function_config(obj->adc, ADC_CONTINUOUS_MODE, DISABLE);
adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);
adc_external_trigger_source_config(obj->adc, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);
/* ADC enable */
adc_enable(obj->adc);
adc_calibration_enable(obj->adc);
}
/** Read the value from analogin pin, represented as an unsigned 16bit value
*
* @param obj The analogin object
* @return An unsigned 16bit value representing the current input voltage
*/
uint16_t analogin_read_u16(analogin_t *obj)
{
uint16_t reval;
adc_regular_channel_config(obj->adc, 0, obj->channel, ADC_SAMPLETIME_7POINT5);
adc_flag_clear(obj->adc, ADC_FLAG_EOC);
/* start Conversion */
adc_software_trigger_enable(obj->adc, ADC_REGULAR_CHANNEL);
while (SET != adc_flag_get(obj->adc, ADC_FLAG_EOC)) {
}
/* ADC actual accuracy is 12 bits */
reval = adc_regular_data_read(obj->adc);
reval = DEV_ADC_PRECISION_12TO16(reval);
return reval;
}
/** Read the input voltage, represented as a float in the range [0.0, 1.0]
*
* @param obj The analogin object
* @return A floating value representing the current input voltage
*/
float analogin_read(analogin_t *obj)
{
uint16_t reval;
adc_regular_channel_config(obj->adc, 0, obj->channel, ADC_SAMPLETIME_7POINT5);
adc_flag_clear(obj->adc, ADC_FLAG_EOC);
/* start Conversion */
adc_software_trigger_enable(obj->adc, ADC_REGULAR_CHANNEL);
/* wait for conversion to complete */
while (SET != adc_flag_get(obj->adc, ADC_FLAG_EOC)) {
}
/* ADC actual accuracy is 12 bits */
reval = adc_regular_data_read(obj->adc);
return (float)reval * (1.0f / (float)DEV_ADC_ACCURACY_12BIT);
}
#endif /* DEVICE_ANALOGIN */

View File

@ -1,158 +1,160 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* 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 "analogout_api.h"
#include "mbed_assert.h"
#if DEVICE_ANALOGOUT
#include "cmsis.h"
#include "pinmap.h"
#include "mbed_error.h"
#include "PeripheralPins.h"
#define DEV_DAC_ACCURACY_12BIT (0xFFF) // 12 bits
#define DEV_DAC_BITS (12)
/** Initialize the analogout peripheral
*
* Configures the pin used by analogout.
* @param obj The analogout object to initialize
* @param pin The analogout pin name
*/
void analogout_init(dac_t *obj, PinName pin)
{
/* get the peripheral name from the pin and assign it to the object */
obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
MBED_ASSERT(obj->dac != (DACName)NC);
/* get the pin function and assign the used channel to the object */
uint32_t function = pinmap_function(pin, PinMap_DAC);
MBED_ASSERT(function != (uint32_t)NC);
obj->channel = GD_PIN_CHANNEL_GET(function);
MBED_ASSERT(obj->channel <= DAC1);
/* configure GPIO */
pinmap_pinout(pin, PinMap_DAC);
/* save the pin for future use */
obj->pin = pin;
/* enable DAC clock */
rcu_periph_clock_enable(RCU_DAC);
/* configure DAC */
dac_wave_mode_config(obj->channel, DAC_WAVE_DISABLE);
dac_trigger_disable(obj->channel);
dac_output_buffer_enable(obj->channel);
analogout_write_u16(obj, 0);
}
/** Release the analogout object
*
* Note: This is not currently used in the mbed-drivers
* @param obj The analogout object
*/
void analogout_free(dac_t *obj)
{
/* Reset DAC and disable clock */
dac_deinit();
rcu_periph_clock_disable(RCU_DAC);
/* configure GPIO */
/* get the pin function and assign the used channel to the object */
uint32_t function = pinmap_function(obj->pin, PinMap_DAC);
MBED_ASSERT(function != (uint32_t)NC);
pin_function(obj->pin, function);
}
/** set the output voltage with specified as a integer
*
* @param obj The analogin object
* @param value The integer-point output voltage to be set
*/
static inline void dev_dac_data_set(dac_t *obj, int value)
{
dac_data_set(obj->channel, DAC_ALIGN_12B_R, (value & DEV_DAC_ACCURACY_12BIT));
dac_enable(obj->channel);
dac_software_trigger_enable(obj->channel);
}
/** get the current DAC data
*
* @param obj The analogin object
* @return DAC data
*/
static inline int dev_dac_data_get(dac_t *obj)
{
return (int)dac_output_value_get(obj->channel);
}
/** Set the output voltage, specified as a percentage (float)
*
* @param obj The analogin object
* @param value The floating-point output voltage to be set
*/
void analogout_write(dac_t *obj, float value)
{
if (value < 0.0f) {
/* when the value is less than 0.0, set DAC output date to 0 */
dev_dac_data_set(obj, 0);
} else if (value > 1.0f) {
/* when the value is more than 1.0, set DAC output date to 0xFFF */
dev_dac_data_set(obj, (int)DEV_DAC_ACCURACY_12BIT);
} else {
dev_dac_data_set(obj, (int)(value * (float)DEV_DAC_ACCURACY_12BIT));
}
}
/** Set the output voltage, specified as unsigned 16-bit
*
* @param obj The analogin object
* @param value The unsigned 16-bit output voltage to be set
*/
void analogout_write_u16(dac_t *obj, uint16_t value)
{
dev_dac_data_set(obj, value >> (16 - DEV_DAC_BITS));
}
/** Read the current voltage value on the pin
*
* @param obj The analogin object
* @return A floating-point value representing the current voltage on the pin,
* measured as a percentage
*/
float analogout_read(dac_t *obj)
{
uint32_t ret_val = dev_dac_data_get(obj);
return (float)ret_val * (1.0f / (float)DEV_DAC_ACCURACY_12BIT);
}
/** Read the current voltage value on the pin, as a normalized unsigned 16bit value
*
* @param obj The analogin object
* @return An unsigned 16-bit value representing the current voltage on the pin
*/
uint16_t analogout_read_u16(dac_t *obj)
{
uint32_t ret_val = dev_dac_data_get(obj);
return (ret_val << 4) | ((ret_val >> 8) & 0x000F);
}
#endif /* DEVICE_ANALOGOUT */
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 "analogout_api.h"
#include "mbed_assert.h"
#if DEVICE_ANALOGOUT
#include "cmsis.h"
#include "pinmap.h"
#include "mbed_error.h"
#include "PeripheralPins.h"
#define DEV_DAC_ACCURACY_12BIT (0xFFF) // 12 bits
#define DEV_DAC_BITS (12)
/** Initialize the analogout peripheral
*
* Configures the pin used by analogout.
* @param obj The analogout object to initialize
* @param pin The analogout pin name
*/
void analogout_init(dac_t *obj, PinName pin)
{
/* get the peripheral name from the pin and assign it to the object */
obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
MBED_ASSERT(obj->dac != (DACName)NC);
/* get the pin function and assign the used channel to the object */
uint32_t function = pinmap_function(pin, PinMap_DAC);
MBED_ASSERT(function != (uint32_t)NC);
obj->channel = GD_PIN_CHANNEL_GET(function);
MBED_ASSERT(obj->channel <= DAC1);
/* configure GPIO */
pinmap_pinout(pin, PinMap_DAC);
/* save the pin for future use */
obj->pin = pin;
/* enable DAC clock */
rcu_periph_clock_enable(RCU_DAC);
/* configure DAC */
dac_wave_mode_config(obj->channel, DAC_WAVE_DISABLE);
dac_trigger_disable(obj->channel);
dac_output_buffer_enable(obj->channel);
analogout_write_u16(obj, 0);
}
/** Release the analogout object
*
* Note: This is not currently used in the mbed-drivers
* @param obj The analogout object
*/
void analogout_free(dac_t *obj)
{
/* Reset DAC and disable clock */
dac_deinit();
rcu_periph_clock_disable(RCU_DAC);
/* configure GPIO */
/* get the pin function and assign the used channel to the object */
uint32_t function = pinmap_function(obj->pin, PinMap_DAC);
MBED_ASSERT(function != (uint32_t)NC);
pin_function(obj->pin, function);
}
/** set the output voltage with specified as a integer
*
* @param obj The analogin object
* @param value The integer-point output voltage to be set
*/
static inline void dev_dac_data_set(dac_t *obj, int value)
{
dac_data_set(obj->channel, DAC_ALIGN_12B_R, (value & DEV_DAC_ACCURACY_12BIT));
dac_enable(obj->channel);
dac_software_trigger_enable(obj->channel);
}
/** get the current DAC data
*
* @param obj The analogin object
* @return DAC data
*/
static inline int dev_dac_data_get(dac_t *obj)
{
return (int)dac_output_value_get(obj->channel);
}
/** Set the output voltage, specified as a percentage (float)
*
* @param obj The analogin object
* @param value The floating-point output voltage to be set
*/
void analogout_write(dac_t *obj, float value)
{
if (value < 0.0f) {
/* when the value is less than 0.0, set DAC output date to 0 */
dev_dac_data_set(obj, 0);
} else if (value > 1.0f) {
/* when the value is more than 1.0, set DAC output date to 0xFFF */
dev_dac_data_set(obj, (int)DEV_DAC_ACCURACY_12BIT);
} else {
dev_dac_data_set(obj, (int)(value * (float)DEV_DAC_ACCURACY_12BIT));
}
}
/** Set the output voltage, specified as unsigned 16-bit
*
* @param obj The analogin object
* @param value The unsigned 16-bit output voltage to be set
*/
void analogout_write_u16(dac_t *obj, uint16_t value)
{
dev_dac_data_set(obj, value >> (16 - DEV_DAC_BITS));
}
/** Read the current voltage value on the pin
*
* @param obj The analogin object
* @return A floating-point value representing the current voltage on the pin,
* measured as a percentage
*/
float analogout_read(dac_t *obj)
{
uint32_t ret_val = dev_dac_data_get(obj);
return (float)ret_val * (1.0f / (float)DEV_DAC_ACCURACY_12BIT);
}
/** Read the current voltage value on the pin, as a normalized unsigned 16bit value
*
* @param obj The analogin object
* @return An unsigned 16-bit value representing the current voltage on the pin
*/
uint16_t analogout_read_u16(dac_t *obj)
{
uint32_t ret_val = dev_dac_data_get(obj);
return (ret_val << 4) | ((ret_val >> 8) & 0x000F);
}
#endif /* DEVICE_ANALOGOUT */

View File

@ -1,6 +1,8 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at

View File

@ -1,25 +1,27 @@
/* The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches. */
/* Check the 'features' section of the target description in 'targets.json' for more details. */
/* mbed Microcontroller Library
* Copyright (c) 2006-2018 ARM Limited
*
* 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 MBED_DEVICE_H
#define MBED_DEVICE_H
#define DEVICE_ID_LENGTH 24
#include "objects.h"
#endif /* MBED_DEVICE_H */
/* The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches. */
/* Check the 'features' section of the target description in 'targets.json' for more details. */
/* mbed Microcontroller Library
* Copyright (c) 2006-2018 ARM Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 MBED_DEVICE_H
#define MBED_DEVICE_H
#define DEVICE_ID_LENGTH 24
#include "objects.h"
#endif /* MBED_DEVICE_H */

View File

@ -1,6 +1,8 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at

View File

@ -1,149 +1,151 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* 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 "gd32f30x_gpio.h"
#include "mbed_assert.h"
#include "gpio_api.h"
#include "pinmap.h"
#include "mbed_error.h"
extern const int GD_GPIO_REMAP[];
extern const int GD_GPIO_SPEED[];
extern const int GD_GPIO_MODE[];
/* Enable GPIO clock and return GPIO base address */
uint32_t gpio_clock_enable(uint32_t port_idx)
{
uint32_t gpio_add = 0;
switch (port_idx) {
case PORTA:
gpio_add = GPIOA;
rcu_periph_clock_enable(RCU_GPIOA);
break;
case PORTB:
gpio_add = GPIOB;
rcu_periph_clock_enable(RCU_GPIOB);
break;
case PORTC:
gpio_add = GPIOC;
rcu_periph_clock_enable(RCU_GPIOC);
break;
case PORTD:
gpio_add = GPIOD;
rcu_periph_clock_enable(RCU_GPIOD);
break;
case PORTE:
gpio_add = GPIOE;
rcu_periph_clock_enable(RCU_GPIOE);
break;
default:
error("port number not exist");
break;
}
return gpio_add;
}
/** Set the given pin as GPIO
*
* @param pin The pin to be set as GPIO
* @return The GPIO port mask for this pin
*/
uint32_t gpio_set(PinName pin)
{
MBED_ASSERT(pin != (PinName)NC);
pin_function(pin, MODE_IN_FLOATING);
/* return pin mask */
return (uint32_t)(1 << ((uint32_t)pin & 0xF));
}
/** Initialize the GPIO pin
*
* @param obj The GPIO object to initialize
* @param pin The GPIO pin to initialize
*/
void gpio_init(gpio_t *obj, PinName pin)
{
obj->pin = pin;
if (pin == (PinName)NC) {
return;
}
/* fill struct parameter for future use */
uint32_t port_index = GD_PORT_GET(pin);
uint32_t gpio = gpio_clock_enable(port_index);
obj->mask = gpio_set(pin);
obj->gpio_periph = gpio;
}
/** Set the input pin mode
*
* @param obj The GPIO object
* @param mode The pin mode to be set
*/
void gpio_mode(gpio_t *obj, PinMode mode)
{
pin_mode(obj->pin, mode);
}
/** Set the output value
*
* @param obj The GPIO object
* @param value The value to be set
*/
void gpio_write(gpio_t *obj, int value)
{
/* set or reset GPIO pin */
if (value) {
GPIO_BOP(obj->gpio_periph) = (1 << (uint32_t)GD_PIN_GET(obj->pin));
} else {
GPIO_BC(obj->gpio_periph) = (1 << (uint32_t)GD_PIN_GET(obj->pin));
}
}
/** Read the input value
*
* @param obj The GPIO object
* @return An integer value 1 or 0
*/
int gpio_read(gpio_t *obj)
{
/* return state of GPIO pin */
return ((GPIO_ISTAT(obj->gpio_periph) & obj->mask) ? 1 : 0);
}
/* Checks if gpio object is connected (pin was not initialized with NC)
* @param pin The pin to be set as GPIO
* @return 0 if port is initialized with NC
**/
int gpio_is_connected(const gpio_t *obj)
{
return obj->pin != (PinName)NC;
}
/** Set the pin direction
*
* @param obj The GPIO object
* @param direction The pin direction to be set
*/
void gpio_dir(gpio_t *obj, PinDirection direction)
{
/* config GPIO pin as input or output */
if (direction == PIN_INPUT) {
gpio_para_init(obj->gpio_periph, GD_GPIO_MODE[MODE_IN_FLOATING], GD_GPIO_SPEED[0], (1 << (uint32_t)GD_PIN_GET(obj->pin)));
} else {
gpio_para_init(obj->gpio_periph, GD_GPIO_MODE[MODE_OUT_PP], GD_GPIO_SPEED[0], (1 << (uint32_t)GD_PIN_GET(obj->pin)));
}
}
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 "gd32f30x_gpio.h"
#include "mbed_assert.h"
#include "gpio_api.h"
#include "pinmap.h"
#include "mbed_error.h"
extern const int GD_GPIO_REMAP[];
extern const int GD_GPIO_SPEED[];
extern const int GD_GPIO_MODE[];
/* Enable GPIO clock and return GPIO base address */
uint32_t gpio_clock_enable(uint32_t port_idx)
{
uint32_t gpio_add = 0;
switch (port_idx) {
case PORTA:
gpio_add = GPIOA;
rcu_periph_clock_enable(RCU_GPIOA);
break;
case PORTB:
gpio_add = GPIOB;
rcu_periph_clock_enable(RCU_GPIOB);
break;
case PORTC:
gpio_add = GPIOC;
rcu_periph_clock_enable(RCU_GPIOC);
break;
case PORTD:
gpio_add = GPIOD;
rcu_periph_clock_enable(RCU_GPIOD);
break;
case PORTE:
gpio_add = GPIOE;
rcu_periph_clock_enable(RCU_GPIOE);
break;
default:
error("port number not exist");
break;
}
return gpio_add;
}
/** Set the given pin as GPIO
*
* @param pin The pin to be set as GPIO
* @return The GPIO port mask for this pin
*/
uint32_t gpio_set(PinName pin)
{
MBED_ASSERT(pin != (PinName)NC);
pin_function(pin, MODE_IN_FLOATING);
/* return pin mask */
return (uint32_t)(1 << ((uint32_t)pin & 0xF));
}
/** Initialize the GPIO pin
*
* @param obj The GPIO object to initialize
* @param pin The GPIO pin to initialize
*/
void gpio_init(gpio_t *obj, PinName pin)
{
obj->pin = pin;
if (pin == (PinName)NC) {
return;
}
/* fill struct parameter for future use */
uint32_t port_index = GD_PORT_GET(pin);
uint32_t gpio = gpio_clock_enable(port_index);
obj->mask = gpio_set(pin);
obj->gpio_periph = gpio;
}
/** Set the input pin mode
*
* @param obj The GPIO object
* @param mode The pin mode to be set
*/
void gpio_mode(gpio_t *obj, PinMode mode)
{
pin_mode(obj->pin, mode);
}
/** Set the output value
*
* @param obj The GPIO object
* @param value The value to be set
*/
void gpio_write(gpio_t *obj, int value)
{
/* set or reset GPIO pin */
if (value) {
GPIO_BOP(obj->gpio_periph) = (1 << (uint32_t)GD_PIN_GET(obj->pin));
} else {
GPIO_BC(obj->gpio_periph) = (1 << (uint32_t)GD_PIN_GET(obj->pin));
}
}
/** Read the input value
*
* @param obj The GPIO object
* @return An integer value 1 or 0
*/
int gpio_read(gpio_t *obj)
{
/* return state of GPIO pin */
return ((GPIO_ISTAT(obj->gpio_periph) & obj->mask) ? 1 : 0);
}
/* Checks if gpio object is connected (pin was not initialized with NC)
* @param pin The pin to be set as GPIO
* @return 0 if port is initialized with NC
**/
int gpio_is_connected(const gpio_t *obj)
{
return obj->pin != (PinName)NC;
}
/** Set the pin direction
*
* @param obj The GPIO object
* @param direction The pin direction to be set
*/
void gpio_dir(gpio_t *obj, PinDirection direction)
{
/* config GPIO pin as input or output */
if (direction == PIN_INPUT) {
gpio_para_init(obj->gpio_periph, GD_GPIO_MODE[MODE_IN_FLOATING], GD_GPIO_SPEED[0], (1 << (uint32_t)GD_PIN_GET(obj->pin)));
} else {
gpio_para_init(obj->gpio_periph, GD_GPIO_MODE[MODE_OUT_PP], GD_GPIO_SPEED[0], (1 << (uint32_t)GD_PIN_GET(obj->pin)));
}
}

View File

@ -1,328 +1,330 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* 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 <stddef.h>
#include "cmsis.h"
#include "gpio_irq_api.h"
#include "pinmap.h"
#include "mbed_error.h"
#define EDGE_NONE (0)
#define EDGE_RISE (1)
#define EDGE_FALL (2)
extern uint32_t gpio_clock_enable(uint32_t port_idx);
static gpio_irq_handler irq_handler;
typedef struct {
uint32_t exti_idx;
uint32_t exti_gpiox; /* base address of gpio */
uint32_t exti_pinx; /* pin number */
} gpio_exti_info_struct;
/* EXTI0...EXTI15 */
static gpio_exti_info_struct exti_info_array[16] = {0};
/** handle EXTI interrupt in EXTI0 to EXTI15
* @param irq_index the line of EXTI(0~15)
*/
static void exti_handle_interrupt(uint32_t irq_index)
{
gpio_exti_info_struct *gpio_exti = &exti_info_array[irq_index];
/* get the port and pin of EXTI */
uint32_t gpio = (uint32_t)(gpio_exti->exti_gpiox);
uint32_t pin = (uint32_t)(1 << (gpio_exti->exti_pinx));
/* clear interrupt flag */
if (exti_interrupt_flag_get((exti_line_enum)pin) != RESET) {
exti_interrupt_flag_clear((exti_line_enum)pin);
/* check which edge has generated the irq */
if ((GPIO_ISTAT(gpio) & pin) == 0) {
irq_handler(gpio_exti->exti_idx, IRQ_FALL);
} else {
irq_handler(gpio_exti->exti_idx, IRQ_RISE);
}
}
}
/* EXTI0 interrupt handler */
static void gpio_irq_exti0(void)
{
exti_handle_interrupt(0);
}
/* EXTI1 interrupt handler */
static void gpio_irq_exti1(void)
{
exti_handle_interrupt(1);
}
/* EXTI2 interrupt handler */
static void gpio_irq_exti2(void)
{
exti_handle_interrupt(2);
}
/* EXTI3 interrupt handler */
static void gpio_irq_exti3(void)
{
exti_handle_interrupt(3);
}
/* EXTI4 interrupt handler */
static void gpio_irq_exti4(void)
{
exti_handle_interrupt(4);
}
/* EXTI5 interrupt handler */
static void gpio_irq_exti5(void)
{
exti_handle_interrupt(5);
}
/* EXTI6 interrupt handler */
static void gpio_irq_exti6(void)
{
exti_handle_interrupt(6);
}
/* EXTI7 interrupt handler */
static void gpio_irq_exti7(void)
{
exti_handle_interrupt(7);
}
/* EXTI8 interrupt handler */
static void gpio_irq_exti8(void)
{
exti_handle_interrupt(8);
}
/* EXTI9 interrupt handler */
static void gpio_irq_exti9(void)
{
exti_handle_interrupt(9);
}
/* EXTI10 interrupt handler */
static void gpio_irq_exti10(void)
{
exti_handle_interrupt(10);
}
/* EXTI11 interrupt handler */
static void gpio_irq_exti11(void)
{
exti_handle_interrupt(11);
}
/* EXTI12 interrupt handler */
static void gpio_irq_exti12(void)
{
exti_handle_interrupt(12);
}
/* EXTI13 interrupt handler */
static void gpio_irq_exti13(void)
{
exti_handle_interrupt(13);
}
/* EXTI14 interrupt handler */
static void gpio_irq_exti14(void)
{
exti_handle_interrupt(14);
}
/* EXTI15 interrupt handler */
static void gpio_irq_exti15(void)
{
exti_handle_interrupt(15);
}
/** Initialize the GPIO IRQ pin
*
* @param obj The GPIO object to initialize
* @param pin The GPIO pin name
* @param handler The handler to be attached to GPIO IRQ
* @param id The object ID (id != 0, 0 is reserved)
* @return -1 if pin is NC, 0 otherwise
*/
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
{
uint32_t vector = 0;
gpio_exti_info_struct *gpio_exti;
if (pin == NC) {
return -1;
}
/* Enable AF Clock */
rcu_periph_clock_enable(RCU_AF);
uint32_t port_index = GD_PORT_GET(pin);
uint32_t pin_index = GD_PIN_GET(pin);
/* Enable GPIO clock */
uint32_t gpio_add = gpio_clock_enable(port_index);
/* fill EXTI information according to pin_index .
eg. use PORTE_9 as EXTI interrupt, the irq type is EXTI5_9_IRQn */
if (pin_index == 0) {
vector = (uint32_t)&gpio_irq_exti0;
obj->irq_index = 0;
obj->irq_n = EXTI0_IRQn;
} else if (pin_index == 1) {
vector = (uint32_t)&gpio_irq_exti1;
obj->irq_index = 1;
obj->irq_n = EXTI1_IRQn;
} else if (pin_index == 2) {
vector = (uint32_t)&gpio_irq_exti2;
obj->irq_index = 2;
obj->irq_n = EXTI2_IRQn;
} else if (pin_index == 3) {
vector = (uint32_t)&gpio_irq_exti3;
obj->irq_index = 3;
obj->irq_n = EXTI3_IRQn;
} else if (pin_index == 4) {
vector = (uint32_t)&gpio_irq_exti4;
obj->irq_index = 4;
obj->irq_n = EXTI4_IRQn;
} else if (pin_index == 5) {
vector = (uint32_t)&gpio_irq_exti5;
obj->irq_index = 5;
obj->irq_n = EXTI5_9_IRQn;
} else if (pin_index == 6) {
vector = (uint32_t)&gpio_irq_exti6;
obj->irq_index = 6;
obj->irq_n = EXTI5_9_IRQn;
} else if (pin_index == 7) {
vector = (uint32_t)&gpio_irq_exti7;
obj->irq_index = 7;
obj->irq_n = EXTI5_9_IRQn;
} else if (pin_index == 8) {
vector = (uint32_t)&gpio_irq_exti8;
obj->irq_index = 8;
obj->irq_n = EXTI5_9_IRQn;
} else if (pin_index == 9) {
vector = (uint32_t)&gpio_irq_exti9;
obj->irq_index = 9;
obj->irq_n = EXTI5_9_IRQn;
} else if (pin_index == 10) {
vector = (uint32_t)&gpio_irq_exti10;
obj->irq_index = 10;
obj->irq_n = EXTI10_15_IRQn;
} else if (pin_index == 11) {
vector = (uint32_t)&gpio_irq_exti11;
obj->irq_index = 11;
obj->irq_n = EXTI10_15_IRQn;
} else if (pin_index == 12) {
vector = (uint32_t)&gpio_irq_exti12;
obj->irq_index = 12;
obj->irq_n = EXTI10_15_IRQn;
} else if (pin_index == 13) {
vector = (uint32_t)&gpio_irq_exti13;
obj->irq_index = 13;
obj->irq_n = EXTI10_15_IRQn;
} else if (pin_index == 14) {
vector = (uint32_t)&gpio_irq_exti14;
obj->irq_index = 14;
obj->irq_n = EXTI10_15_IRQn;
} else if (pin_index == 15) {
vector = (uint32_t)&gpio_irq_exti15;
obj->irq_index = 15;
obj->irq_n = EXTI10_15_IRQn;
} else {
error("pin not supported for interrupt in.\n");
return -1;
}
/* Save informations for future use */
obj->event = EDGE_NONE;
obj->pin = pin;
gpio_exti = &exti_info_array[obj->irq_index];
gpio_exti->exti_idx = id;
gpio_exti->exti_gpiox = gpio_add;
gpio_exti->exti_pinx = pin_index;
irq_handler = handler;
/* Enable EXTI interrupt */
NVIC_SetVector(obj->irq_n, vector);
gpio_irq_enable(obj);
return 0;
}
/** Release the GPIO IRQ PIN
*
* @param obj The gpio object
*/
void gpio_irq_free(gpio_irq_t *obj)
{
gpio_exti_info_struct *gpio_exti = &exti_info_array[obj->irq_index];
/* Disable EXTI interrupt */
gpio_irq_disable(obj);
/* Reset struct of exti information */
gpio_exti->exti_idx = 0;
gpio_exti->exti_gpiox = 0;
gpio_exti->exti_pinx = 0;
}
/** Enable/disable pin IRQ event
*
* @param obj The GPIO object
* @param event The GPIO IRQ event
* @param enable The enable flag
*/
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
{
if (event == IRQ_RISE) {
if (enable) {
exti_init((exti_line_enum)(1 << GD_PIN_GET(obj->pin)), EXTI_INTERRUPT, EXTI_TRIG_RISING);
/* Clear interrupt enable bit, rising/falling bit */
} else {
EXTI_INTEN &= ~(uint32_t)(exti_line_enum)(1 << GD_PIN_GET(obj->pin));
EXTI_RTEN &= ~(uint32_t)(exti_line_enum)(1 << GD_PIN_GET(obj->pin));
EXTI_FTEN &= ~(uint32_t)(exti_line_enum)(1 << GD_PIN_GET(obj->pin));
}
}
if (event == IRQ_FALL) {
if (enable) {
exti_init((exti_line_enum)(1 << (GD_PIN_GET(obj->pin))), EXTI_INTERRUPT, EXTI_TRIG_FALLING);
/* Clear interrupt enable bit, rising/falling bit */
} else {
EXTI_INTEN &= ~(uint32_t)(exti_line_enum)(1 << GD_PIN_GET(obj->pin));
EXTI_RTEN &= ~(uint32_t)(exti_line_enum)(1 << GD_PIN_GET(obj->pin));
EXTI_FTEN &= ~(uint32_t)(exti_line_enum)(1 << GD_PIN_GET(obj->pin));
}
}
}
/** Enable GPIO IRQ
*
* This is target dependent, as it might enable the entire port or just a pin
* @param obj The GPIO object
*/
void gpio_irq_enable(gpio_irq_t *obj)
{
/* Select EXTI Source */
gpio_exti_source_select(GD_PORT_GET(obj->pin), GD_PIN_GET(obj->pin));
exti_interrupt_enable((exti_line_enum)(1 << GD_PIN_GET(obj->pin)));
NVIC_EnableIRQ(obj->irq_n);
}
/** Disable GPIO IRQ
*
* This is target dependent, as it might disable the entire port or just a pin
* @param obj The GPIO object
*/
void gpio_irq_disable(gpio_irq_t *obj)
{
/* Clear EXTI line configuration */
exti_interrupt_disable((exti_line_enum)(1 << GD_PIN_GET(obj->pin)));
NVIC_DisableIRQ(obj->irq_n);
NVIC_ClearPendingIRQ(obj->irq_n);
obj->event = EDGE_NONE;
}
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 <stddef.h>
#include "cmsis.h"
#include "gpio_irq_api.h"
#include "pinmap.h"
#include "mbed_error.h"
#define EDGE_NONE (0)
#define EDGE_RISE (1)
#define EDGE_FALL (2)
extern uint32_t gpio_clock_enable(uint32_t port_idx);
static gpio_irq_handler irq_handler;
typedef struct {
uint32_t exti_idx;
uint32_t exti_gpiox; /* base address of gpio */
uint32_t exti_pinx; /* pin number */
} gpio_exti_info_struct;
/* EXTI0...EXTI15 */
static gpio_exti_info_struct exti_info_array[16] = {0};
/** handle EXTI interrupt in EXTI0 to EXTI15
* @param irq_index the line of EXTI(0~15)
*/
static void exti_handle_interrupt(uint32_t irq_index)
{
gpio_exti_info_struct *gpio_exti = &exti_info_array[irq_index];
/* get the port and pin of EXTI */
uint32_t gpio = (uint32_t)(gpio_exti->exti_gpiox);
uint32_t pin = (uint32_t)(1 << (gpio_exti->exti_pinx));
/* clear interrupt flag */
if (exti_interrupt_flag_get((exti_line_enum)pin) != RESET) {
exti_interrupt_flag_clear((exti_line_enum)pin);
/* check which edge has generated the irq */
if ((GPIO_ISTAT(gpio) & pin) == 0) {
irq_handler(gpio_exti->exti_idx, IRQ_FALL);
} else {
irq_handler(gpio_exti->exti_idx, IRQ_RISE);
}
}
}
/* EXTI0 interrupt handler */
static void gpio_irq_exti0(void)
{
exti_handle_interrupt(0);
}
/* EXTI1 interrupt handler */
static void gpio_irq_exti1(void)
{
exti_handle_interrupt(1);
}
/* EXTI2 interrupt handler */
static void gpio_irq_exti2(void)
{
exti_handle_interrupt(2);
}
/* EXTI3 interrupt handler */
static void gpio_irq_exti3(void)
{
exti_handle_interrupt(3);
}
/* EXTI4 interrupt handler */
static void gpio_irq_exti4(void)
{
exti_handle_interrupt(4);
}
/* EXTI5 interrupt handler */
static void gpio_irq_exti5(void)
{
exti_handle_interrupt(5);
}
/* EXTI6 interrupt handler */
static void gpio_irq_exti6(void)
{
exti_handle_interrupt(6);
}
/* EXTI7 interrupt handler */
static void gpio_irq_exti7(void)
{
exti_handle_interrupt(7);
}
/* EXTI8 interrupt handler */
static void gpio_irq_exti8(void)
{
exti_handle_interrupt(8);
}
/* EXTI9 interrupt handler */
static void gpio_irq_exti9(void)
{
exti_handle_interrupt(9);
}
/* EXTI10 interrupt handler */
static void gpio_irq_exti10(void)
{
exti_handle_interrupt(10);
}
/* EXTI11 interrupt handler */
static void gpio_irq_exti11(void)
{
exti_handle_interrupt(11);
}
/* EXTI12 interrupt handler */
static void gpio_irq_exti12(void)
{
exti_handle_interrupt(12);
}
/* EXTI13 interrupt handler */
static void gpio_irq_exti13(void)
{
exti_handle_interrupt(13);
}
/* EXTI14 interrupt handler */
static void gpio_irq_exti14(void)
{
exti_handle_interrupt(14);
}
/* EXTI15 interrupt handler */
static void gpio_irq_exti15(void)
{
exti_handle_interrupt(15);
}
/** Initialize the GPIO IRQ pin
*
* @param obj The GPIO object to initialize
* @param pin The GPIO pin name
* @param handler The handler to be attached to GPIO IRQ
* @param id The object ID (id != 0, 0 is reserved)
* @return -1 if pin is NC, 0 otherwise
*/
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
{
uint32_t vector = 0;
gpio_exti_info_struct *gpio_exti;
if (pin == NC) {
return -1;
}
/* Enable AF Clock */
rcu_periph_clock_enable(RCU_AF);
uint32_t port_index = GD_PORT_GET(pin);
uint32_t pin_index = GD_PIN_GET(pin);
/* Enable GPIO clock */
uint32_t gpio_add = gpio_clock_enable(port_index);
/* fill EXTI information according to pin_index .
eg. use PORTE_9 as EXTI interrupt, the irq type is EXTI5_9_IRQn */
if (pin_index == 0) {
vector = (uint32_t)&gpio_irq_exti0;
obj->irq_index = 0;
obj->irq_n = EXTI0_IRQn;
} else if (pin_index == 1) {
vector = (uint32_t)&gpio_irq_exti1;
obj->irq_index = 1;
obj->irq_n = EXTI1_IRQn;
} else if (pin_index == 2) {
vector = (uint32_t)&gpio_irq_exti2;
obj->irq_index = 2;
obj->irq_n = EXTI2_IRQn;
} else if (pin_index == 3) {
vector = (uint32_t)&gpio_irq_exti3;
obj->irq_index = 3;
obj->irq_n = EXTI3_IRQn;
} else if (pin_index == 4) {
vector = (uint32_t)&gpio_irq_exti4;
obj->irq_index = 4;
obj->irq_n = EXTI4_IRQn;
} else if (pin_index == 5) {
vector = (uint32_t)&gpio_irq_exti5;
obj->irq_index = 5;
obj->irq_n = EXTI5_9_IRQn;
} else if (pin_index == 6) {
vector = (uint32_t)&gpio_irq_exti6;
obj->irq_index = 6;
obj->irq_n = EXTI5_9_IRQn;
} else if (pin_index == 7) {
vector = (uint32_t)&gpio_irq_exti7;
obj->irq_index = 7;
obj->irq_n = EXTI5_9_IRQn;
} else if (pin_index == 8) {
vector = (uint32_t)&gpio_irq_exti8;
obj->irq_index = 8;
obj->irq_n = EXTI5_9_IRQn;
} else if (pin_index == 9) {
vector = (uint32_t)&gpio_irq_exti9;
obj->irq_index = 9;
obj->irq_n = EXTI5_9_IRQn;
} else if (pin_index == 10) {
vector = (uint32_t)&gpio_irq_exti10;
obj->irq_index = 10;
obj->irq_n = EXTI10_15_IRQn;
} else if (pin_index == 11) {
vector = (uint32_t)&gpio_irq_exti11;
obj->irq_index = 11;
obj->irq_n = EXTI10_15_IRQn;
} else if (pin_index == 12) {
vector = (uint32_t)&gpio_irq_exti12;
obj->irq_index = 12;
obj->irq_n = EXTI10_15_IRQn;
} else if (pin_index == 13) {
vector = (uint32_t)&gpio_irq_exti13;
obj->irq_index = 13;
obj->irq_n = EXTI10_15_IRQn;
} else if (pin_index == 14) {
vector = (uint32_t)&gpio_irq_exti14;
obj->irq_index = 14;
obj->irq_n = EXTI10_15_IRQn;
} else if (pin_index == 15) {
vector = (uint32_t)&gpio_irq_exti15;
obj->irq_index = 15;
obj->irq_n = EXTI10_15_IRQn;
} else {
error("pin not supported for interrupt in.\n");
return -1;
}
/* Save informations for future use */
obj->event = EDGE_NONE;
obj->pin = pin;
gpio_exti = &exti_info_array[obj->irq_index];
gpio_exti->exti_idx = id;
gpio_exti->exti_gpiox = gpio_add;
gpio_exti->exti_pinx = pin_index;
irq_handler = handler;
/* Enable EXTI interrupt */
NVIC_SetVector(obj->irq_n, vector);
gpio_irq_enable(obj);
return 0;
}
/** Release the GPIO IRQ PIN
*
* @param obj The gpio object
*/
void gpio_irq_free(gpio_irq_t *obj)
{
gpio_exti_info_struct *gpio_exti = &exti_info_array[obj->irq_index];
/* Disable EXTI interrupt */
gpio_irq_disable(obj);
/* Reset struct of exti information */
gpio_exti->exti_idx = 0;
gpio_exti->exti_gpiox = 0;
gpio_exti->exti_pinx = 0;
}
/** Enable/disable pin IRQ event
*
* @param obj The GPIO object
* @param event The GPIO IRQ event
* @param enable The enable flag
*/
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
{
if (event == IRQ_RISE) {
if (enable) {
exti_init((exti_line_enum)(1 << GD_PIN_GET(obj->pin)), EXTI_INTERRUPT, EXTI_TRIG_RISING);
/* Clear interrupt enable bit, rising/falling bit */
} else {
EXTI_INTEN &= ~(uint32_t)(exti_line_enum)(1 << GD_PIN_GET(obj->pin));
EXTI_RTEN &= ~(uint32_t)(exti_line_enum)(1 << GD_PIN_GET(obj->pin));
EXTI_FTEN &= ~(uint32_t)(exti_line_enum)(1 << GD_PIN_GET(obj->pin));
}
}
if (event == IRQ_FALL) {
if (enable) {
exti_init((exti_line_enum)(1 << (GD_PIN_GET(obj->pin))), EXTI_INTERRUPT, EXTI_TRIG_FALLING);
/* Clear interrupt enable bit, rising/falling bit */
} else {
EXTI_INTEN &= ~(uint32_t)(exti_line_enum)(1 << GD_PIN_GET(obj->pin));
EXTI_RTEN &= ~(uint32_t)(exti_line_enum)(1 << GD_PIN_GET(obj->pin));
EXTI_FTEN &= ~(uint32_t)(exti_line_enum)(1 << GD_PIN_GET(obj->pin));
}
}
}
/** Enable GPIO IRQ
*
* This is target dependent, as it might enable the entire port or just a pin
* @param obj The GPIO object
*/
void gpio_irq_enable(gpio_irq_t *obj)
{
/* Select EXTI Source */
gpio_exti_source_select(GD_PORT_GET(obj->pin), GD_PIN_GET(obj->pin));
exti_interrupt_enable((exti_line_enum)(1 << GD_PIN_GET(obj->pin)));
NVIC_EnableIRQ(obj->irq_n);
}
/** Disable GPIO IRQ
*
* This is target dependent, as it might disable the entire port or just a pin
* @param obj The GPIO object
*/
void gpio_irq_disable(gpio_irq_t *obj)
{
/* Clear EXTI line configuration */
exti_interrupt_disable((exti_line_enum)(1 << GD_PIN_GET(obj->pin)));
NVIC_DisableIRQ(obj->irq_n);
NVIC_ClearPendingIRQ(obj->irq_n);
obj->event = EDGE_NONE;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,154 +1,156 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2018 ARM Limited
*
* 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 "gd32f30x.h"
#include "cmsis.h"
#include "hal_tick.h"
int mbed_sdk_inited = 0;
/*!
\brief configure the system clock to 120M by PLL which selects HXTAL(8M) as its clock source
\param[in] none
\param[out] none
\retval none
*/
#if TICKER_TIMER_WIDTH_BIT == 16
extern void ticker_16bits_timer_init(void);
#else
extern void ticker_32bits_timer_init(void);
#endif
/*!
\brief configure the system clock to 120M by PLL which selects HXTAL(8M) as its clock source
\param[in] none
\param[out] none
\retval none
*/
static void system_clock_120m_hxtal(void)
{
uint32_t timeout = 0U;
uint32_t stab_flag = 0U;
/* enable HXTAL */
RCU_CTL |= RCU_CTL_HXTALEN;
/* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
do {
timeout++;
stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
} while ((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
/* if fail */
if (0U == (RCU_CTL & RCU_CTL_HXTALSTB)) {
while (1) {
}
}
RCU_APB1EN |= RCU_APB1EN_PMUEN;
PMU_CTL |= PMU_CTL_LDOVS;
/* HXTAL is stable */
/* AHB = SYSCLK */
RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
/* APB2 = AHB/1 */
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
/* APB1 = AHB/2 */
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
#if (defined(GD32F30X_HD) || defined(GD32F30X_XD))
/* select HXTAL/2 as clock source */
RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0);
RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_CFG0_PREDV0);
/* CK_PLL = (CK_HXTAL/2) * 30 = 120 MHz */
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
RCU_CFG0 |= RCU_PLL_MUL30;
#elif defined(GD32F30X_CL)
/* CK_PLL = (CK_PREDIV0) * 30 = 120 MHz */
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL30);
/* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
/* enable PLL1 */
RCU_CTL |= RCU_CTL_PLL1EN;
/* wait till PLL1 is ready */
while ((RCU_CTL & RCU_CTL_PLL1STB) == 0U) {
}
#endif /* GD32F30X_HD and GD32F30X_XD */
/* enable PLL */
RCU_CTL |= RCU_CTL_PLLEN;
/* wait until PLL is stable */
while (0U == (RCU_CTL & RCU_CTL_PLLSTB)) {
}
/* enable the high-drive to extend the clock frequency to 120 MHz */
PMU_CTL |= PMU_CTL_HDEN;
while (0U == (PMU_CS & PMU_CS_HDRF)) {
}
/* select the high-drive mode */
PMU_CTL |= PMU_CTL_HDS;
while (0U == (PMU_CS & PMU_CS_HDSRF)) {
}
/* select PLL as system clock */
RCU_CFG0 &= ~RCU_CFG0_SCS;
RCU_CFG0 |= RCU_CKSYSSRC_PLL;
/* wait until PLL is selected as system clock */
while (0U == (RCU_CFG0 & RCU_SCSS_PLL)) {
}
}
/**
* SDK hook for running code before ctors or OS
*
* This is a weak function which can be overridden by a target's
* SDK to allow code to run after ram is initialized but before
* the OS has been started or constructors have run.
*
* Preconditions:
* - Ram is initialized
* - NVIC is setup
*/
/**
* This function is called after RAM initialization and before main.
*/
void mbed_sdk_init()
{
/* Update the SystemCoreClock */
SystemCoreClockUpdate();
nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
/* configure 1ms tick */
#if TICKER_TIMER_WIDTH_BIT == 16
ticker_16bits_timer_init();
#else
ticker_32bits_timer_init();
#endif
system_clock_120m_hxtal();
SystemCoreClockUpdate();
mbed_sdk_inited = 1;
}
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 "gd32f30x.h"
#include "cmsis.h"
#include "hal_tick.h"
int mbed_sdk_inited = 0;
/*!
\brief configure the system clock to 120M by PLL which selects HXTAL(8M) as its clock source
\param[in] none
\param[out] none
\retval none
*/
#if TICKER_TIMER_WIDTH_BIT == 16
extern void ticker_16bits_timer_init(void);
#else
extern void ticker_32bits_timer_init(void);
#endif
/*!
\brief configure the system clock to 120M by PLL which selects HXTAL(8M) as its clock source
\param[in] none
\param[out] none
\retval none
*/
static void system_clock_120m_hxtal(void)
{
uint32_t timeout = 0U;
uint32_t stab_flag = 0U;
/* enable HXTAL */
RCU_CTL |= RCU_CTL_HXTALEN;
/* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
do {
timeout++;
stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
} while ((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
/* if fail */
if (0U == (RCU_CTL & RCU_CTL_HXTALSTB)) {
while (1) {
}
}
RCU_APB1EN |= RCU_APB1EN_PMUEN;
PMU_CTL |= PMU_CTL_LDOVS;
/* HXTAL is stable */
/* AHB = SYSCLK */
RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
/* APB2 = AHB/1 */
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
/* APB1 = AHB/2 */
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
#if (defined(GD32F30X_HD) || defined(GD32F30X_XD))
/* select HXTAL/2 as clock source */
RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0);
RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_CFG0_PREDV0);
/* CK_PLL = (CK_HXTAL/2) * 30 = 120 MHz */
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
RCU_CFG0 |= RCU_PLL_MUL30;
#elif defined(GD32F30X_CL)
/* CK_PLL = (CK_PREDIV0) * 30 = 120 MHz */
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL30);
/* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
/* enable PLL1 */
RCU_CTL |= RCU_CTL_PLL1EN;
/* wait till PLL1 is ready */
while ((RCU_CTL & RCU_CTL_PLL1STB) == 0U) {
}
#endif /* GD32F30X_HD and GD32F30X_XD */
/* enable PLL */
RCU_CTL |= RCU_CTL_PLLEN;
/* wait until PLL is stable */
while (0U == (RCU_CTL & RCU_CTL_PLLSTB)) {
}
/* enable the high-drive to extend the clock frequency to 120 MHz */
PMU_CTL |= PMU_CTL_HDEN;
while (0U == (PMU_CS & PMU_CS_HDRF)) {
}
/* select the high-drive mode */
PMU_CTL |= PMU_CTL_HDS;
while (0U == (PMU_CS & PMU_CS_HDSRF)) {
}
/* select PLL as system clock */
RCU_CFG0 &= ~RCU_CFG0_SCS;
RCU_CFG0 |= RCU_CKSYSSRC_PLL;
/* wait until PLL is selected as system clock */
while (0U == (RCU_CFG0 & RCU_SCSS_PLL)) {
}
}
/**
* SDK hook for running code before ctors or OS
*
* This is a weak function which can be overridden by a target's
* SDK to allow code to run after ram is initialized but before
* the OS has been started or constructors have run.
*
* Preconditions:
* - Ram is initialized
* - NVIC is setup
*/
/**
* This function is called after RAM initialization and before main.
*/
void mbed_sdk_init()
{
/* Update the SystemCoreClock */
SystemCoreClockUpdate();
nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
/* configure 1ms tick */
#if TICKER_TIMER_WIDTH_BIT == 16
ticker_16bits_timer_init();
#else
ticker_32bits_timer_init();
#endif
system_clock_120m_hxtal();
SystemCoreClockUpdate();
mbed_sdk_inited = 1;
}

View File

@ -1,181 +1,183 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* 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 MBED_OBJECTS_H
#define MBED_OBJECTS_H
#include "cmsis.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#include "mbed_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct gpio_s gpio_t;
struct gpio_s {
uint32_t mask;
PinName pin;
__IO uint32_t gpio_periph;
};
struct gpio_irq_s {
IRQn_Type irq_n;
uint32_t irq_index;
uint32_t event;
PinName pin;
};
struct port_s {
PortName port;
uint32_t mask;
PinDirection direction;
__IO uint32_t *reg_in;
__IO uint32_t *reg_out;
};
struct analogin_s {
ADCName adc;
PinName pin;
uint8_t channel;
};
#if DEVICE_ANALOGOUT
struct dac_s {
DACName dac;
PinName pin;
uint32_t channel;
};
#endif
struct can_s {
CANName can;
int index;
};
struct pwmout_s {
PWMName pwm;
uint32_t cnt_unit;
uint8_t ch;
};
struct serial_s {
/* basic information */
UARTName uart;
int index;
PinName pin_tx;
PinName pin_rx;
/* configure information */
uint32_t baudrate;
uint32_t databits;
uint32_t stopbits;
uint32_t parity;
/* operating parameters */
uint16_t rx_size;
uint8_t *tx_buffer_ptr;
uint8_t *rx_buffer_ptr;
__IO uint16_t tx_count;
__IO uint16_t rx_count;
__IO uint32_t error_code;
__IO operation_state_enum tx_state;
__IO operation_state_enum rx_state;
#if DEVICE_SERIAL_ASYNCH
uint32_t events;
#endif
#if DEVICE_SERIAL_FC
uint32_t hw_flow_ctl;
PinName pin_rts;
PinName pin_cts;
#endif
};
struct spi_s {
spi_parameter_struct spi_struct;
IRQn_Type spi_irq;
SPIName spi;
PinName pin_miso;
PinName pin_mosi;
PinName pin_sclk;
PinName pin_ssel;
};
struct i2c_s {
/* basic information */
I2CName i2c;
uint8_t index;
PinName sda;
PinName scl;
int i2c_inited; /* flag used to indicate whether the i2c has been initialized */
/* configure information */
int freq; /* i2c frequence */
uint32_t addr_bit_mode; /* 7 bits or 10 bits */
uint32_t slave_addr0;
uint32_t slave_addr1;
uint16_t transfer_size;
uint8_t *buffer_pointer;
/* operating parameters */
__IO operation_state_enum state;
__IO i2c_mode_enum mode;
__IO uint32_t previous_state_mode;
__IO uint32_t i2c_target_dev_addr;
__IO uint32_t event_count;
__IO uint32_t transfer_count;
__IO uint32_t transfer_option;
__IO uint32_t error_code;
/* I2C DMA information */
uint32_t tx_dma_periph;
dma_channel_enum tx_dma_channel;
uint32_t rx_dma_periph;
dma_channel_enum rx_dma_channel;
IRQn_Type event_i2cIRQ;
IRQn_Type error_i2cIRQ;
uint32_t global_trans_option;
volatile uint8_t event;
#if DEVICE_I2CSLAVE
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
uint8_t stop;
uint8_t available_events;
#endif
};
#if DEVICE_FLASH
struct flash_s {
/* nothing to be stored for now */
uint32_t dummy;
};
#endif
#ifdef __cplusplus
}
#endif
#endif
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 MBED_OBJECTS_H
#define MBED_OBJECTS_H
#include "cmsis.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#include "mbed_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct gpio_s gpio_t;
struct gpio_s {
uint32_t mask;
PinName pin;
__IO uint32_t gpio_periph;
};
struct gpio_irq_s {
IRQn_Type irq_n;
uint32_t irq_index;
uint32_t event;
PinName pin;
};
struct port_s {
PortName port;
uint32_t mask;
PinDirection direction;
__IO uint32_t *reg_in;
__IO uint32_t *reg_out;
};
struct analogin_s {
ADCName adc;
PinName pin;
uint8_t channel;
};
#if DEVICE_ANALOGOUT
struct dac_s {
DACName dac;
PinName pin;
uint32_t channel;
};
#endif
struct can_s {
CANName can;
int index;
};
struct pwmout_s {
PWMName pwm;
uint32_t cnt_unit;
uint8_t ch;
};
struct serial_s {
/* basic information */
UARTName uart;
int index;
PinName pin_tx;
PinName pin_rx;
/* configure information */
uint32_t baudrate;
uint32_t databits;
uint32_t stopbits;
uint32_t parity;
/* operating parameters */
uint16_t rx_size;
uint8_t *tx_buffer_ptr;
uint8_t *rx_buffer_ptr;
__IO uint16_t tx_count;
__IO uint16_t rx_count;
__IO uint32_t error_code;
__IO operation_state_enum tx_state;
__IO operation_state_enum rx_state;
#if DEVICE_SERIAL_ASYNCH
uint32_t events;
#endif
#if DEVICE_SERIAL_FC
uint32_t hw_flow_ctl;
PinName pin_rts;
PinName pin_cts;
#endif
};
struct spi_s {
spi_parameter_struct spi_struct;
IRQn_Type spi_irq;
SPIName spi;
PinName pin_miso;
PinName pin_mosi;
PinName pin_sclk;
PinName pin_ssel;
};
struct i2c_s {
/* basic information */
I2CName i2c;
uint8_t index;
PinName sda;
PinName scl;
int i2c_inited; /* flag used to indicate whether the i2c has been initialized */
/* configure information */
int freq; /* i2c frequence */
uint32_t addr_bit_mode; /* 7 bits or 10 bits */
uint32_t slave_addr0;
uint32_t slave_addr1;
uint16_t transfer_size;
uint8_t *buffer_pointer;
/* operating parameters */
__IO operation_state_enum state;
__IO i2c_mode_enum mode;
__IO uint32_t previous_state_mode;
__IO uint32_t i2c_target_dev_addr;
__IO uint32_t event_count;
__IO uint32_t transfer_count;
__IO uint32_t transfer_option;
__IO uint32_t error_code;
/* I2C DMA information */
uint32_t tx_dma_periph;
dma_channel_enum tx_dma_channel;
uint32_t rx_dma_periph;
dma_channel_enum rx_dma_channel;
IRQn_Type event_i2cIRQ;
IRQn_Type error_i2cIRQ;
uint32_t global_trans_option;
volatile uint8_t event;
#if DEVICE_I2CSLAVE
uint8_t slave;
volatile uint8_t pending_slave_tx_master_rx;
volatile uint8_t pending_slave_rx_maxter_tx;
#endif
#if DEVICE_I2C_ASYNCH
uint32_t address;
uint8_t stop;
uint8_t available_events;
#endif
};
#if DEVICE_FLASH
struct flash_s {
/* nothing to be stored for now */
uint32_t dummy;
};
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,133 +1,135 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* 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 "mbed_assert.h"
#include "pinmap.h"
#include "PortNames.h"
#include "mbed_error.h"
extern uint32_t gpio_clock_enable(uint32_t port_idx);
extern const int GD_GPIO_REMAP[];
extern const int GD_GPIO_MODE[];
extern const int GD_GPIO_SPEED[];
static void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pin);
/** Configure pin (mode, speed, reamp function )
*
* @param pin gpio pin name
* @param function gpio pin mode, speed, remap function
*/
void pin_function(PinName pin, int function)
{
MBED_ASSERT(pin != (PinName)NC);
uint32_t mode = GD_PIN_MODE_GET(function);
uint32_t remap = GD_PIN_REMAP_GET(function);
uint32_t speed = GD_PIN_SPEED_GET(function);
uint32_t port = GD_PORT_GET(pin);
uint32_t gd_pin = 1 << GD_PIN_GET(pin);
uint32_t gpio = gpio_clock_enable(port);
gpio_para_init(gpio, GD_GPIO_MODE[mode], GD_GPIO_SPEED[speed], gd_pin);
if (remap != 0) {
rcu_periph_clock_enable(RCU_AF);
gpio_pin_remap_config(GD_GPIO_REMAP[remap], ENABLE);
}
}
/** Only configure pin mode
*
* @param pin gpio pin name
* @param function gpio pin mode
*/
void pin_mode(PinName pin, PinMode mode)
{
MBED_ASSERT(pin != (PinName)NC);
uint32_t port = GD_PORT_GET(pin);
uint32_t gd_pin = 1 << GD_PIN_GET(pin);
uint32_t gpio = gpio_clock_enable(port);
if (mode != PullNone) {
gpio_mode_set(gpio, GD_GPIO_MODE[mode], gd_pin);
}
}
/** configure gpio pin mode
*
* @param gpio_periph gpio port name
* @param mode gpio pin mode
* @param pin gpio pin number
*/
static void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pin)
{
uint16_t i;
uint32_t temp_mode = 0U;
uint32_t reg = 0U;
/* GPIO mode configuration */
temp_mode = (uint32_t)(mode & ((uint32_t)0x0FU));
/* configure the eight low port pins with GPIO_CTL0 */
for (i = 0U; i < 8U; i++) {
if ((1U << i) & pin) {
reg = GPIO_CTL0(gpio_periph);
/* set the specified pin mode bits */
reg |= GPIO_MODE_SET(i, temp_mode);
/* set IPD or IPU */
if (GPIO_MODE_IPD == mode) {
/* reset the corresponding OCTL bit */
GPIO_BC(gpio_periph) = (uint32_t)pin;
} else {
/* set the corresponding OCTL bit */
if (GPIO_MODE_IPU == mode) {
GPIO_BOP(gpio_periph) = (uint32_t)pin;
}
}
/* set GPIO_CTL0 register */
GPIO_CTL0(gpio_periph) = reg;
}
}
/* configure the eight high port pins with GPIO_CTL1 */
for (i = 8U; i < 16U; i++) {
if ((1U << i) & pin) {
reg = GPIO_CTL1(gpio_periph);
/* set the specified pin mode bits */
reg |= GPIO_MODE_SET(i - 8U, temp_mode);
/* set IPD or IPU */
if (GPIO_MODE_IPD == mode) {
/* reset the corresponding OCTL bit */
GPIO_BC(gpio_periph) = (uint32_t)pin;
} else {
/* set the corresponding OCTL bit */
if (GPIO_MODE_IPU == mode) {
GPIO_BOP(gpio_periph) = (uint32_t)pin;
}
}
/* set GPIO_CTL1 register */
GPIO_CTL1(gpio_periph) = reg;
}
}
}
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 "mbed_assert.h"
#include "pinmap.h"
#include "PortNames.h"
#include "mbed_error.h"
extern uint32_t gpio_clock_enable(uint32_t port_idx);
extern const int GD_GPIO_REMAP[];
extern const int GD_GPIO_MODE[];
extern const int GD_GPIO_SPEED[];
static void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pin);
/** Configure pin (mode, speed, reamp function )
*
* @param pin gpio pin name
* @param function gpio pin mode, speed, remap function
*/
void pin_function(PinName pin, int function)
{
MBED_ASSERT(pin != (PinName)NC);
uint32_t mode = GD_PIN_MODE_GET(function);
uint32_t remap = GD_PIN_REMAP_GET(function);
uint32_t speed = GD_PIN_SPEED_GET(function);
uint32_t port = GD_PORT_GET(pin);
uint32_t gd_pin = 1 << GD_PIN_GET(pin);
uint32_t gpio = gpio_clock_enable(port);
gpio_para_init(gpio, GD_GPIO_MODE[mode], GD_GPIO_SPEED[speed], gd_pin);
if (remap != 0) {
rcu_periph_clock_enable(RCU_AF);
gpio_pin_remap_config(GD_GPIO_REMAP[remap], ENABLE);
}
}
/** Only configure pin mode
*
* @param pin gpio pin name
* @param function gpio pin mode
*/
void pin_mode(PinName pin, PinMode mode)
{
MBED_ASSERT(pin != (PinName)NC);
uint32_t port = GD_PORT_GET(pin);
uint32_t gd_pin = 1 << GD_PIN_GET(pin);
uint32_t gpio = gpio_clock_enable(port);
if (mode != PullNone) {
gpio_mode_set(gpio, GD_GPIO_MODE[mode], gd_pin);
}
}
/** configure gpio pin mode
*
* @param gpio_periph gpio port name
* @param mode gpio pin mode
* @param pin gpio pin number
*/
static void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pin)
{
uint16_t i;
uint32_t temp_mode = 0U;
uint32_t reg = 0U;
/* GPIO mode configuration */
temp_mode = (uint32_t)(mode & ((uint32_t)0x0FU));
/* configure the eight low port pins with GPIO_CTL0 */
for (i = 0U; i < 8U; i++) {
if ((1U << i) & pin) {
reg = GPIO_CTL0(gpio_periph);
/* set the specified pin mode bits */
reg |= GPIO_MODE_SET(i, temp_mode);
/* set IPD or IPU */
if (GPIO_MODE_IPD == mode) {
/* reset the corresponding OCTL bit */
GPIO_BC(gpio_periph) = (uint32_t)pin;
} else {
/* set the corresponding OCTL bit */
if (GPIO_MODE_IPU == mode) {
GPIO_BOP(gpio_periph) = (uint32_t)pin;
}
}
/* set GPIO_CTL0 register */
GPIO_CTL0(gpio_periph) = reg;
}
}
/* configure the eight high port pins with GPIO_CTL1 */
for (i = 8U; i < 16U; i++) {
if ((1U << i) & pin) {
reg = GPIO_CTL1(gpio_periph);
/* set the specified pin mode bits */
reg |= GPIO_MODE_SET(i - 8U, temp_mode);
/* set IPD or IPU */
if (GPIO_MODE_IPD == mode) {
/* reset the corresponding OCTL bit */
GPIO_BC(gpio_periph) = (uint32_t)pin;
} else {
/* set the corresponding OCTL bit */
if (GPIO_MODE_IPU == mode) {
GPIO_BOP(gpio_periph) = (uint32_t)pin;
}
}
/* set GPIO_CTL1 register */
GPIO_CTL1(gpio_periph) = reg;
}
}
}

View File

@ -1,118 +1,120 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* 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 "port_api.h"
#include "pinmap.h"
#include "gpio_api.h"
#include "mbed_error.h"
#if DEVICE_PORTIN || DEVICE_PORTOUT
extern uint32_t gpio_clock_enable(uint32_t port_idx);
/** Get the pin name from the port's pin number
*
* @param port The port name
* @param pin_n The pin number within the specified port
* @return The pin name for the port's pin number
* BIT[7:4] port number
BIT[3:0] pin number
*/
PinName port_pin(PortName port, int pin_n)
{
return (PinName)(pin_n + (port << 4));
}
/** Initilize the port
*
* @param obj The port object to initialize
* @param port The port name
* @param mask The bitmask to identify which bits in the port should be included (0 - ignore)
* @param dir The port direction
*/
void port_init(port_t *obj, PortName port, int mask, PinDirection dir)
{
uint32_t port_index = (uint32_t)port;
uint32_t gpio = gpio_clock_enable(port_index);
obj->port = port;
obj->mask = mask;
obj->direction = dir;
obj->reg_in = &GPIO_ISTAT(gpio);
obj->reg_out = &GPIO_OCTL(gpio);
port_dir(obj, dir);
}
/** Set port direction (in/out)
*
* @param obj The port object
* @param dir The port direction to be set
*/
void port_dir(port_t *obj, PinDirection dir)
{
uint32_t i;
obj->direction = dir;
for (i = 0; i < 16; i++) {
if (obj->mask & (1 << i)) {
if (dir == PIN_OUTPUT) {
pin_function(port_pin(obj->port, i), MODE_OUT_PP);
} else {
pin_function(port_pin(obj->port, i), MODE_IN_FLOATING);
}
}
}
}
/** Set the input port mode
*
* @param obj The port object
* @param mode THe port mode to be set
*/
void port_mode(port_t *obj, PinMode mode)
{
uint32_t i;
for (i = 0; i < 16; i++) {
if (obj->mask & (1 << i)) {
pin_mode(port_pin(obj->port, i), mode);
}
}
}
/** Write value to the port
*
* @param obj The port object
* @param value The value to be set
*/
void port_write(port_t *obj, int value)
{
*obj->reg_out = (*obj->reg_out & ~obj->mask) | (value & obj->mask);
}
/** Read the current value on the port
*
* @param obj The port object
* @return An integer with each bit corresponding to an associated port pin setting
*/
int port_read(port_t *obj)
{
if (obj->direction == PIN_OUTPUT) {
return (*obj->reg_out & obj->mask);
} else {
return (*obj->reg_in & obj->mask);
}
}
#endif
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 "port_api.h"
#include "pinmap.h"
#include "gpio_api.h"
#include "mbed_error.h"
#if DEVICE_PORTIN || DEVICE_PORTOUT
extern uint32_t gpio_clock_enable(uint32_t port_idx);
/** Get the pin name from the port's pin number
*
* @param port The port name
* @param pin_n The pin number within the specified port
* @return The pin name for the port's pin number
* BIT[7:4] port number
BIT[3:0] pin number
*/
PinName port_pin(PortName port, int pin_n)
{
return (PinName)(pin_n + (port << 4));
}
/** Initilize the port
*
* @param obj The port object to initialize
* @param port The port name
* @param mask The bitmask to identify which bits in the port should be included (0 - ignore)
* @param dir The port direction
*/
void port_init(port_t *obj, PortName port, int mask, PinDirection dir)
{
uint32_t port_index = (uint32_t)port;
uint32_t gpio = gpio_clock_enable(port_index);
obj->port = port;
obj->mask = mask;
obj->direction = dir;
obj->reg_in = &GPIO_ISTAT(gpio);
obj->reg_out = &GPIO_OCTL(gpio);
port_dir(obj, dir);
}
/** Set port direction (in/out)
*
* @param obj The port object
* @param dir The port direction to be set
*/
void port_dir(port_t *obj, PinDirection dir)
{
uint32_t i;
obj->direction = dir;
for (i = 0; i < 16; i++) {
if (obj->mask & (1 << i)) {
if (dir == PIN_OUTPUT) {
pin_function(port_pin(obj->port, i), MODE_OUT_PP);
} else {
pin_function(port_pin(obj->port, i), MODE_IN_FLOATING);
}
}
}
}
/** Set the input port mode
*
* @param obj The port object
* @param mode THe port mode to be set
*/
void port_mode(port_t *obj, PinMode mode)
{
uint32_t i;
for (i = 0; i < 16; i++) {
if (obj->mask & (1 << i)) {
pin_mode(port_pin(obj->port, i), mode);
}
}
}
/** Write value to the port
*
* @param obj The port object
* @param value The value to be set
*/
void port_write(port_t *obj, int value)
{
*obj->reg_out = (*obj->reg_out & ~obj->mask) | (value & obj->mask);
}
/** Read the current value on the port
*
* @param obj The port object
* @return An integer with each bit corresponding to an associated port pin setting
*/
int port_read(port_t *obj)
{
if (obj->direction == PIN_OUTPUT) {
return (*obj->reg_out & obj->mask);
} else {
return (*obj->reg_in & obj->mask);
}
}
#endif

View File

@ -1,297 +1,299 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* 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 "pwmout_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "mbed_error.h"
#include "PeripheralPins.h"
#define DEV_PWMOUT_APB_MASK 0x00010000U
#define DEV_PWMOUT_APB1 0U
#define DEV_PWMOUT_APB2 1U
static uint32_t timer_get_clock(uint32_t timer_periph);
static void dev_pwmout_init(pwmout_t *obj)
{
timer_oc_parameter_struct timer_ocintpara;
timer_parameter_struct timer_initpara;
MBED_ASSERT(obj);
uint32_t periph = obj->pwm;
switch (periph) {
case TIMER0:
rcu_periph_clock_enable(RCU_TIMER0);
break;
case TIMER1:
rcu_periph_clock_enable(RCU_TIMER1);
break;
case TIMER2:
rcu_periph_clock_enable(RCU_TIMER2);
break;
case TIMER3:
rcu_periph_clock_enable(RCU_TIMER3);
break;
case TIMER4:
rcu_periph_clock_enable(RCU_TIMER4);
break;
case TIMER7:
rcu_periph_clock_enable(RCU_TIMER7);
break;
case TIMER8:
rcu_periph_clock_enable(RCU_TIMER8);
break;
case TIMER9:
rcu_periph_clock_enable(RCU_TIMER9);
break;
case TIMER10:
rcu_periph_clock_enable(RCU_TIMER10);
break;
case TIMER11:
rcu_periph_clock_enable(RCU_TIMER11);
break;
case TIMER12:
rcu_periph_clock_enable(RCU_TIMER12);
break;
case TIMER13:
rcu_periph_clock_enable(RCU_TIMER13);
break;
}
/* configure TIMER base function */
timer_initpara.prescaler = 119;
timer_initpara.period = 9999;
timer_initpara.clockdivision = 0;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_init(obj->pwm, &timer_initpara);
/* configure TIMER channel output function */
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_ocintpara.outputnstate = TIMER_CCXN_ENABLE;
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_HIGH;
timer_channel_output_config(obj->pwm, obj->ch, &timer_ocintpara);
timer_channel_output_mode_config(obj->pwm, obj->ch, TIMER_OC_MODE_PWM0);
timer_channel_output_fast_config(obj->pwm, obj->ch, TIMER_OC_FAST_DISABLE);
timer_primary_output_config(obj->pwm, ENABLE);
}
static uint8_t dev_pwmout_apb_check(uint32_t periph)
{
uint8_t reval = DEV_PWMOUT_APB1;
/* check peripherals belongs to APB1 or APB2 */
if (DEV_PWMOUT_APB_MASK == (periph & DEV_PWMOUT_APB_MASK)) {
reval = DEV_PWMOUT_APB2;
}
return reval;
}
void pwmout_init(pwmout_t *obj, PinName pin)
{
MBED_ASSERT(obj);
obj->pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
MBED_ASSERT(obj->pwm != (PWMName)NC);
uint32_t function = pinmap_function(pin, PinMap_PWM);
MBED_ASSERT(function != (uint32_t)NC);
obj->ch = GD_PIN_CHANNEL_GET(function);
/* Peripheral initialization */
dev_pwmout_init(obj);
/* pin function initialization */
pinmap_pinout(pin, PinMap_PWM);
}
void pwmout_free(pwmout_t *obj)
{
timer_channel_output_state_config(obj->pwm, obj->ch, TIMER_CCX_DISABLE);
}
void pwmout_write(pwmout_t *obj, float value)
{
uint16_t period;
uint16_t pulse;
timer_disable(obj->pwm);
/* overflow protection */
if (value < (float)0.0) {
value = 0.0;
} else if (value > (float)1.0) {
value = 1.0;
}
period = TIMER_CAR(obj->pwm);
pulse = (uint16_t)(period * value);
timer_channel_output_pulse_value_config(obj->pwm, obj->ch, pulse);
timer_enable(obj->pwm);
}
float pwmout_read(pwmout_t *obj)
{
float value = 0;
uint16_t period;
uint16_t pulse;
period = TIMER_CAR(obj->pwm);
switch (obj->ch) {
case TIMER_CH_0:
pulse = TIMER_CH0CV(obj->pwm);
break;
case TIMER_CH_1:
pulse = TIMER_CH1CV(obj->pwm);
break;
case TIMER_CH_2:
pulse = TIMER_CH2CV(obj->pwm);
break;
case TIMER_CH_3:
pulse = TIMER_CH3CV(obj->pwm);
break;
default:
error("Error: pwm channel error! \r\n");
}
/* calculated waveform duty ratio */
value = (float)(pulse) / (float)(period);
if (value > (float)1.0) {
value = (float)1.0;
}
return value;
}
void pwmout_period(pwmout_t *obj, float seconds)
{
pwmout_period_us(obj, seconds * 1000000.0f);
}
void pwmout_period_ms(pwmout_t *obj, int ms)
{
pwmout_period_us(obj, ms * 1000);
}
void pwmout_period_us(pwmout_t *obj, int us)
{
uint32_t ultemp = 0;
uint32_t timer_clk = 0;
uint32_t period = us - 1;
uint32_t prescaler;
float duty_ratio;
duty_ratio = pwmout_read(obj);
timer_disable(obj->pwm);
timer_clk = timer_get_clock(obj->pwm);
ultemp = (timer_clk / 1000000);
prescaler = ultemp;
obj->cnt_unit = 1;
while (period > 0xFFFF) {
obj->cnt_unit = obj->cnt_unit << 1;
period = period >> 1;
prescaler = ultemp * obj->cnt_unit;
}
if (prescaler > 0xFFFF) {
error("Error: TIMER prescaler value is overflow \r\n");
}
timer_autoreload_value_config(obj->pwm, period);
timer_prescaler_config(obj->pwm, prescaler - 1, TIMER_PSC_RELOAD_NOW);
ultemp = duty_ratio * us;
pwmout_pulsewidth_us(obj, ultemp);
timer_enable(obj->pwm);
}
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
{
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
}
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
{
pwmout_pulsewidth_us(obj, ms * 1000);
}
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
{
uint32_t pulse;
uint32_t period;
period = TIMER_CAR(obj->pwm);
pulse = us / obj->cnt_unit;
if (pulse > period) {
pulse = period;
}
timer_channel_output_pulse_value_config(obj->pwm, obj->ch, pulse);
}
static uint32_t timer_get_clock(uint32_t timer_periph)
{
uint32_t timerclk;
if ((TIMER0 == timer_periph) || (TIMER7 == timer_periph) ||
(TIMER8 == timer_periph) || (TIMER9 == timer_periph) || (TIMER10 == timer_periph)) {
/* get the current APB2 TIMER clock source */
if (RCU_APB2_CKAHB_DIV1 == (RCU_CFG0 & RCU_CFG0_APB2PSC)) {
timerclk = rcu_clock_freq_get(CK_APB2);
} else {
timerclk = rcu_clock_freq_get(CK_APB2) * 2;
}
} else {
/* get the current APB1 TIMER clock source */
if (RCU_APB1_CKAHB_DIV1 == (RCU_CFG0 & RCU_CFG0_APB1PSC)) {
timerclk = rcu_clock_freq_get(CK_APB1);
} else {
timerclk = rcu_clock_freq_get(CK_APB1) * 2;
}
}
return timerclk;
}
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 "pwmout_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "mbed_error.h"
#include "PeripheralPins.h"
#define DEV_PWMOUT_APB_MASK 0x00010000U
#define DEV_PWMOUT_APB1 0U
#define DEV_PWMOUT_APB2 1U
static uint32_t timer_get_clock(uint32_t timer_periph);
static void dev_pwmout_init(pwmout_t *obj)
{
timer_oc_parameter_struct timer_ocintpara;
timer_parameter_struct timer_initpara;
MBED_ASSERT(obj);
uint32_t periph = obj->pwm;
switch (periph) {
case TIMER0:
rcu_periph_clock_enable(RCU_TIMER0);
break;
case TIMER1:
rcu_periph_clock_enable(RCU_TIMER1);
break;
case TIMER2:
rcu_periph_clock_enable(RCU_TIMER2);
break;
case TIMER3:
rcu_periph_clock_enable(RCU_TIMER3);
break;
case TIMER4:
rcu_periph_clock_enable(RCU_TIMER4);
break;
case TIMER7:
rcu_periph_clock_enable(RCU_TIMER7);
break;
case TIMER8:
rcu_periph_clock_enable(RCU_TIMER8);
break;
case TIMER9:
rcu_periph_clock_enable(RCU_TIMER9);
break;
case TIMER10:
rcu_periph_clock_enable(RCU_TIMER10);
break;
case TIMER11:
rcu_periph_clock_enable(RCU_TIMER11);
break;
case TIMER12:
rcu_periph_clock_enable(RCU_TIMER12);
break;
case TIMER13:
rcu_periph_clock_enable(RCU_TIMER13);
break;
}
/* configure TIMER base function */
timer_initpara.prescaler = 119;
timer_initpara.period = 9999;
timer_initpara.clockdivision = 0;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_init(obj->pwm, &timer_initpara);
/* configure TIMER channel output function */
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_ocintpara.outputnstate = TIMER_CCXN_ENABLE;
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_HIGH;
timer_channel_output_config(obj->pwm, obj->ch, &timer_ocintpara);
timer_channel_output_mode_config(obj->pwm, obj->ch, TIMER_OC_MODE_PWM0);
timer_channel_output_fast_config(obj->pwm, obj->ch, TIMER_OC_FAST_DISABLE);
timer_primary_output_config(obj->pwm, ENABLE);
}
static uint8_t dev_pwmout_apb_check(uint32_t periph)
{
uint8_t reval = DEV_PWMOUT_APB1;
/* check peripherals belongs to APB1 or APB2 */
if (DEV_PWMOUT_APB_MASK == (periph & DEV_PWMOUT_APB_MASK)) {
reval = DEV_PWMOUT_APB2;
}
return reval;
}
void pwmout_init(pwmout_t *obj, PinName pin)
{
MBED_ASSERT(obj);
obj->pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
MBED_ASSERT(obj->pwm != (PWMName)NC);
uint32_t function = pinmap_function(pin, PinMap_PWM);
MBED_ASSERT(function != (uint32_t)NC);
obj->ch = GD_PIN_CHANNEL_GET(function);
/* Peripheral initialization */
dev_pwmout_init(obj);
/* pin function initialization */
pinmap_pinout(pin, PinMap_PWM);
}
void pwmout_free(pwmout_t *obj)
{
timer_channel_output_state_config(obj->pwm, obj->ch, TIMER_CCX_DISABLE);
}
void pwmout_write(pwmout_t *obj, float value)
{
uint16_t period;
uint16_t pulse;
timer_disable(obj->pwm);
/* overflow protection */
if (value < (float)0.0) {
value = 0.0;
} else if (value > (float)1.0) {
value = 1.0;
}
period = TIMER_CAR(obj->pwm);
pulse = (uint16_t)(period * value);
timer_channel_output_pulse_value_config(obj->pwm, obj->ch, pulse);
timer_enable(obj->pwm);
}
float pwmout_read(pwmout_t *obj)
{
float value = 0;
uint16_t period;
uint16_t pulse;
period = TIMER_CAR(obj->pwm);
switch (obj->ch) {
case TIMER_CH_0:
pulse = TIMER_CH0CV(obj->pwm);
break;
case TIMER_CH_1:
pulse = TIMER_CH1CV(obj->pwm);
break;
case TIMER_CH_2:
pulse = TIMER_CH2CV(obj->pwm);
break;
case TIMER_CH_3:
pulse = TIMER_CH3CV(obj->pwm);
break;
default:
error("Error: pwm channel error! \r\n");
}
/* calculated waveform duty ratio */
value = (float)(pulse) / (float)(period);
if (value > (float)1.0) {
value = (float)1.0;
}
return value;
}
void pwmout_period(pwmout_t *obj, float seconds)
{
pwmout_period_us(obj, seconds * 1000000.0f);
}
void pwmout_period_ms(pwmout_t *obj, int ms)
{
pwmout_period_us(obj, ms * 1000);
}
void pwmout_period_us(pwmout_t *obj, int us)
{
uint32_t ultemp = 0;
uint32_t timer_clk = 0;
uint32_t period = us - 1;
uint32_t prescaler;
float duty_ratio;
duty_ratio = pwmout_read(obj);
timer_disable(obj->pwm);
timer_clk = timer_get_clock(obj->pwm);
ultemp = (timer_clk / 1000000);
prescaler = ultemp;
obj->cnt_unit = 1;
while (period > 0xFFFF) {
obj->cnt_unit = obj->cnt_unit << 1;
period = period >> 1;
prescaler = ultemp * obj->cnt_unit;
}
if (prescaler > 0xFFFF) {
error("Error: TIMER prescaler value is overflow \r\n");
}
timer_autoreload_value_config(obj->pwm, period);
timer_prescaler_config(obj->pwm, prescaler - 1, TIMER_PSC_RELOAD_NOW);
ultemp = duty_ratio * us;
pwmout_pulsewidth_us(obj, ultemp);
timer_enable(obj->pwm);
}
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
{
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
}
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
{
pwmout_pulsewidth_us(obj, ms * 1000);
}
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
{
uint32_t pulse;
uint32_t period;
period = TIMER_CAR(obj->pwm);
pulse = us / obj->cnt_unit;
if (pulse > period) {
pulse = period;
}
timer_channel_output_pulse_value_config(obj->pwm, obj->ch, pulse);
}
static uint32_t timer_get_clock(uint32_t timer_periph)
{
uint32_t timerclk;
if ((TIMER0 == timer_periph) || (TIMER7 == timer_periph) ||
(TIMER8 == timer_periph) || (TIMER9 == timer_periph) || (TIMER10 == timer_periph)) {
/* get the current APB2 TIMER clock source */
if (RCU_APB2_CKAHB_DIV1 == (RCU_CFG0 & RCU_CFG0_APB2PSC)) {
timerclk = rcu_clock_freq_get(CK_APB2);
} else {
timerclk = rcu_clock_freq_get(CK_APB2) * 2;
}
} else {
/* get the current APB1 TIMER clock source */
if (RCU_APB1_CKAHB_DIV1 == (RCU_CFG0 & RCU_CFG0_APB1PSC)) {
timerclk = rcu_clock_freq_get(CK_APB1);
} else {
timerclk = rcu_clock_freq_get(CK_APB1) * 2;
}
}
return timerclk;
}

View File

@ -1,6 +1,8 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,8 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at

View File

@ -1,372 +1,374 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* 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 "mbed_assert.h"
#include "mbed_error.h"
#include "spi_api.h"
#if DEVICE_SPI
#include "cmsis.h"
#include "pinmap.h"
#include "PeripheralPins.h"
#define SPI_S(obj) (( struct spi_s *)(obj))
/** Get the frequency of SPI clock source
*
* Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
* @param[out] spi_freq The SPI clock source freguency
* @param[in] obj The SPI object
*/
static int dev_spi_clock_source_frequency_get(spi_t *obj)
{
int spi_freq = 0;
struct spi_s *spiobj = SPI_S(obj);
switch ((int)spiobj->spi) {
case SPI0:
/* clock source is APB2 */
spi_freq = rcu_clock_freq_get(CK_APB2);
break;
case SPI1:
/* clock source is APB1 */
spi_freq = rcu_clock_freq_get(CK_APB1);
break;
case SPI2:
/* clock source is APB1 */
spi_freq = rcu_clock_freq_get(CK_APB1);
break;
default:
error("SPI clock source frequency get error");
break;
}
return spi_freq;
}
/** Initialize the SPI structure
*
* Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
* @param[out] obj The SPI object to initialize
*/
static void dev_spi_struct_init(spi_t *obj)
{
struct spi_s *spiobj = SPI_S(obj);
spi_disable(spiobj->spi);
spi_para_init(spiobj->spi, &obj->spi_struct);
spi_enable(spiobj->spi);
}
/** Initialize the SPI peripheral
*
* Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
* @param[out] obj The SPI object to initialize
* @param[in] mosi The pin to use for MOSI
* @param[in] miso The pin to use for MISO
* @param[in] sclk The pin to use for SCLK
* @param[in] ssel The pin to use for SSEL
*/
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
{
struct spi_s *spiobj = SPI_S(obj);
SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
/* return SPIName according to PinName */
SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
spiobj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl);
MBED_ASSERT(spiobj->spi != (SPIName)NC);
/* Set iqr type */
if (spiobj->spi == SPI0) {
rcu_periph_clock_enable(RCU_SPI0);
spiobj->spi_irq = SPI0_IRQn;
}
if (spiobj->spi == SPI1) {
rcu_periph_clock_enable(RCU_SPI1);
spiobj->spi_irq = SPI1_IRQn;
}
if (spiobj->spi == SPI2) {
rcu_periph_clock_enable(RCU_SPI2);
spiobj->spi_irq = SPI2_IRQn;
}
/* config GPIO mode of SPI pins */
pinmap_pinout(mosi, PinMap_SPI_MOSI);
pinmap_pinout(miso, PinMap_SPI_MISO);
pinmap_pinout(sclk, PinMap_SPI_SCLK);
spiobj->pin_miso = miso;
spiobj->pin_mosi = mosi;
spiobj->pin_sclk = sclk;
spiobj->pin_ssel = ssel;
if (ssel != NC) {
pinmap_pinout(ssel, PinMap_SPI_SSEL);
spiobj->spi_struct.nss = SPI_NSS_HARD;
} else {
spiobj->spi_struct.nss = SPI_NSS_SOFT;
}
/* Default values */
spiobj->spi_struct.device_mode = SPI_MASTER;
spiobj->spi_struct.prescale = SPI_PSC_256;
spiobj->spi_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
spiobj->spi_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
spiobj->spi_struct.frame_size = SPI_FRAMESIZE_8BIT;
spiobj->spi_struct.endian = SPI_ENDIAN_MSB;
dev_spi_struct_init(obj);
}
/** Release a SPI object
*
* TODO: spi_free is currently unimplemented
* This will require reference counting at the C++ level to be safe
*
* Return the pins owned by the SPI object to their reset state
* Disable the SPI peripheral
* Disable the SPI clock
* @param[in] obj The SPI object to deinitialize
*/
void spi_free(spi_t *obj)
{
struct spi_s *spiobj = SPI_S(obj);
spi_disable(spiobj->spi);
/* Disable and deinit SPI */
if (spiobj->spi == SPI0) {
spi_i2s_deinit(SPI0);
rcu_periph_clock_disable(RCU_SPI0);
}
if (spiobj->spi == SPI1) {
spi_i2s_deinit(SPI1);
rcu_periph_clock_disable(RCU_SPI1);
}
if (spiobj->spi == SPI2) {
spi_i2s_deinit(SPI2);
rcu_periph_clock_disable(RCU_SPI2);
}
/* Deinit GPIO mode of SPI pins */
pin_function(spiobj->pin_miso, MODE_IN_FLOATING);
pin_function(spiobj->pin_mosi, MODE_IN_FLOATING);
pin_function(spiobj->pin_sclk, MODE_IN_FLOATING);
if (spiobj->spi_struct.nss != SPI_NSS_SOFT) {
pin_function(spiobj->pin_ssel, MODE_IN_FLOATING);
}
}
/** Configure the SPI format
*
* Set the number of bits per frame, configure clock polarity and phase, shift order and master/slave mode.
* The default bit order is MSB.
* @param[in,out] obj The SPI object to configure
* @param[in] bits The number of bits per frame
* @param[in] mode The SPI mode (clock polarity, phase, and shift direction)
* @param[in] slave Zero for master mode or non-zero for slave mode
*/
void spi_format(spi_t *obj, int bits, int mode, int slave)
{
struct spi_s *spiobj = SPI_S(obj);
spiobj->spi_struct.frame_size = (bits == 16) ? SPI_FRAMESIZE_16BIT : SPI_FRAMESIZE_8BIT;
/* Config polarity and phase of SPI */
switch (mode) {
case 0:
spiobj->spi_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
break;
case 1:
spiobj->spi_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_2EDGE;
break;
case 2:
spiobj->spi_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_1EDGE;
break;
default:
spiobj->spi_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
break;
}
if (spiobj->spi_struct.nss != SPI_NSS_SOFT) {
spiobj->spi_struct.nss = SPI_NSS_HARD;
spi_nss_output_enable(spiobj->spi);
}
/* Select SPI as master or slave */
spiobj->spi_struct.device_mode = (slave) ? SPI_SLAVE : SPI_MASTER;
dev_spi_struct_init(obj);
}
static const uint16_t baudrate_prescaler_table[] = {SPI_PSC_2,
SPI_PSC_4,
SPI_PSC_8,
SPI_PSC_16,
SPI_PSC_32,
SPI_PSC_64,
SPI_PSC_128,
SPI_PSC_256
};
/** Set the SPI baud rate
*
* Actual frequency may differ from the desired frequency due to available dividers and bus clock
* Configures the SPI peripheral's baud rate
* @param[in,out] obj The SPI object to configure
* @param[in] hz The baud rate in Hz
*/
void spi_frequency(spi_t *obj, int hz)
{
struct spi_s *spiobj = SPI_S(obj);
int spi_hz = 0;
uint8_t prescaler_rank = 0;
uint8_t last_index = (sizeof(baudrate_prescaler_table) / sizeof(baudrate_prescaler_table[0])) - 1;
spi_hz = dev_spi_clock_source_frequency_get(obj) / 2;
/* Config SPI prescaler according to input frequency*/
while ((spi_hz > hz) && (prescaler_rank < last_index)) {
spi_hz = spi_hz / 2;
prescaler_rank++;
}
spiobj->spi_struct.prescale = baudrate_prescaler_table[prescaler_rank];
dev_spi_struct_init(obj);
}
/** Write a block out in master mode and receive a value
*
* The total number of bytes sent and received will be the maximum of
* tx_length and rx_length. The bytes written will be padded with the
* value 0xff.
*
* @param[in] obj The SPI peripheral to use for sending
* @param[in] tx_buffer Pointer to the byte-array of data to write to the device
* @param[in] tx_length Number of bytes to write, may be zero
* @param[in] rx_buffer Pointer to the byte-array of data to read from the device
* @param[in] rx_length Number of bytes to read, may be zero
* @param[in] write_fill Default data transmitted while performing a read
* @returns
* The number of bytes written and read from the device. This is
* maximum of tx_length and rx_length.
*/
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, char write_fill)
{
int total = (tx_length > rx_length) ? tx_length : rx_length;
for (int i = 0; i < total; i++) {
char out = (i < tx_length) ? tx_buffer[i] : write_fill;
char in = spi_master_write(obj, out);
if (i < rx_length) {
rx_buffer[i] = in;
}
}
return total;
}
/** Write a byte out in master mode and receive a value
*
* @param[in] obj The SPI peripheral to use for sending
* @param[in] value The value to send
* @return Returns the value received during send
*/
int spi_master_write(spi_t *obj, int value)
{
int count = 0;
struct spi_s *spiobj = SPI_S(obj);
/* wait the SPI transmit buffer is empty */
while ((RESET == spi_i2s_flag_get(spiobj->spi, SPI_FLAG_TBE)) && (count++ < 1000));
if (count >= 1000) {
return -1;
} else {
spi_i2s_data_transmit(spiobj->spi, value);
}
count = 0;
/* wait the SPI receive buffer is not empty */
while ((RESET == spi_i2s_flag_get(spiobj->spi, SPI_FLAG_RBNE)) && (count++ < 1000));
if (count >= 1000) {
return -1;
} else {
return spi_i2s_data_receive(spiobj->spi);
}
}
/** Check if a value is available to read
*
* @param[in] obj The SPI peripheral to check
* @return non-zero if a value is available
*/
int spi_slave_receive(spi_t *obj)
{
int status;
struct spi_s *spiobj = SPI_S(obj);
/* check whether or not the SPI receive buffer is empty */
status = ((spi_i2s_flag_get(spiobj->spi, SPI_FLAG_RBNE) != RESET) ? 1 : 0);
return status;
}
/** Get a received value out of the SPI receive buffer in slave mode
*
* Blocks until a value is available
* @param[in] obj The SPI peripheral to read
* @return The value received
*/
int spi_slave_read(spi_t *obj)
{
int count = 0;
struct spi_s *spiobj = SPI_S(obj);
/* wait the SPI receive buffer is not empty */
while ((RESET == spi_i2s_flag_get(spiobj->spi, SPI_FLAG_RBNE)) && (count++ < 1000));
if (count >= 1000) {
return -1;
} else {
return spi_i2s_data_receive(spiobj->spi);
}
}
/** Write a value to the SPI peripheral in slave mode
*
* Blocks until the SPI peripheral can be written to
* @param[in] obj The SPI peripheral to write
* @param[in] value The value to write
*/
void spi_slave_write(spi_t *obj, int value)
{
struct spi_s *spiobj = SPI_S(obj);
/* wait the SPI transmit buffer is empty */
while (RESET == spi_i2s_flag_get(spiobj->spi, SPI_FLAG_TBE));
spi_i2s_data_transmit(spiobj->spi, value);
}
/** Checks if the specified SPI peripheral is in use
*
* @param[in] obj The SPI peripheral to check
* @return non-zero if the peripheral is currently transmitting
*/
int spi_busy(spi_t *obj)
{
int status;
struct spi_s *spiobj = SPI_S(obj);
/* check whether or not the SPI is busy */
status = ((spi_i2s_flag_get(spiobj->spi, SPI_FLAG_TRANS) != RESET) ? 1 : 0);
return status;
}
#endif
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 "mbed_assert.h"
#include "mbed_error.h"
#include "spi_api.h"
#if DEVICE_SPI
#include "cmsis.h"
#include "pinmap.h"
#include "PeripheralPins.h"
#define SPI_S(obj) (( struct spi_s *)(obj))
/** Get the frequency of SPI clock source
*
* Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
* @param[out] spi_freq The SPI clock source freguency
* @param[in] obj The SPI object
*/
static int dev_spi_clock_source_frequency_get(spi_t *obj)
{
int spi_freq = 0;
struct spi_s *spiobj = SPI_S(obj);
switch ((int)spiobj->spi) {
case SPI0:
/* clock source is APB2 */
spi_freq = rcu_clock_freq_get(CK_APB2);
break;
case SPI1:
/* clock source is APB1 */
spi_freq = rcu_clock_freq_get(CK_APB1);
break;
case SPI2:
/* clock source is APB1 */
spi_freq = rcu_clock_freq_get(CK_APB1);
break;
default:
error("SPI clock source frequency get error");
break;
}
return spi_freq;
}
/** Initialize the SPI structure
*
* Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
* @param[out] obj The SPI object to initialize
*/
static void dev_spi_struct_init(spi_t *obj)
{
struct spi_s *spiobj = SPI_S(obj);
spi_disable(spiobj->spi);
spi_para_init(spiobj->spi, &obj->spi_struct);
spi_enable(spiobj->spi);
}
/** Initialize the SPI peripheral
*
* Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
* @param[out] obj The SPI object to initialize
* @param[in] mosi The pin to use for MOSI
* @param[in] miso The pin to use for MISO
* @param[in] sclk The pin to use for SCLK
* @param[in] ssel The pin to use for SSEL
*/
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
{
struct spi_s *spiobj = SPI_S(obj);
SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
/* return SPIName according to PinName */
SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
spiobj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl);
MBED_ASSERT(spiobj->spi != (SPIName)NC);
/* Set iqr type */
if (spiobj->spi == SPI0) {
rcu_periph_clock_enable(RCU_SPI0);
spiobj->spi_irq = SPI0_IRQn;
}
if (spiobj->spi == SPI1) {
rcu_periph_clock_enable(RCU_SPI1);
spiobj->spi_irq = SPI1_IRQn;
}
if (spiobj->spi == SPI2) {
rcu_periph_clock_enable(RCU_SPI2);
spiobj->spi_irq = SPI2_IRQn;
}
/* config GPIO mode of SPI pins */
pinmap_pinout(mosi, PinMap_SPI_MOSI);
pinmap_pinout(miso, PinMap_SPI_MISO);
pinmap_pinout(sclk, PinMap_SPI_SCLK);
spiobj->pin_miso = miso;
spiobj->pin_mosi = mosi;
spiobj->pin_sclk = sclk;
spiobj->pin_ssel = ssel;
if (ssel != NC) {
pinmap_pinout(ssel, PinMap_SPI_SSEL);
spiobj->spi_struct.nss = SPI_NSS_HARD;
} else {
spiobj->spi_struct.nss = SPI_NSS_SOFT;
}
/* Default values */
spiobj->spi_struct.device_mode = SPI_MASTER;
spiobj->spi_struct.prescale = SPI_PSC_256;
spiobj->spi_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
spiobj->spi_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
spiobj->spi_struct.frame_size = SPI_FRAMESIZE_8BIT;
spiobj->spi_struct.endian = SPI_ENDIAN_MSB;
dev_spi_struct_init(obj);
}
/** Release a SPI object
*
* TODO: spi_free is currently unimplemented
* This will require reference counting at the C++ level to be safe
*
* Return the pins owned by the SPI object to their reset state
* Disable the SPI peripheral
* Disable the SPI clock
* @param[in] obj The SPI object to deinitialize
*/
void spi_free(spi_t *obj)
{
struct spi_s *spiobj = SPI_S(obj);
spi_disable(spiobj->spi);
/* Disable and deinit SPI */
if (spiobj->spi == SPI0) {
spi_i2s_deinit(SPI0);
rcu_periph_clock_disable(RCU_SPI0);
}
if (spiobj->spi == SPI1) {
spi_i2s_deinit(SPI1);
rcu_periph_clock_disable(RCU_SPI1);
}
if (spiobj->spi == SPI2) {
spi_i2s_deinit(SPI2);
rcu_periph_clock_disable(RCU_SPI2);
}
/* Deinit GPIO mode of SPI pins */
pin_function(spiobj->pin_miso, MODE_IN_FLOATING);
pin_function(spiobj->pin_mosi, MODE_IN_FLOATING);
pin_function(spiobj->pin_sclk, MODE_IN_FLOATING);
if (spiobj->spi_struct.nss != SPI_NSS_SOFT) {
pin_function(spiobj->pin_ssel, MODE_IN_FLOATING);
}
}
/** Configure the SPI format
*
* Set the number of bits per frame, configure clock polarity and phase, shift order and master/slave mode.
* The default bit order is MSB.
* @param[in,out] obj The SPI object to configure
* @param[in] bits The number of bits per frame
* @param[in] mode The SPI mode (clock polarity, phase, and shift direction)
* @param[in] slave Zero for master mode or non-zero for slave mode
*/
void spi_format(spi_t *obj, int bits, int mode, int slave)
{
struct spi_s *spiobj = SPI_S(obj);
spiobj->spi_struct.frame_size = (bits == 16) ? SPI_FRAMESIZE_16BIT : SPI_FRAMESIZE_8BIT;
/* Config polarity and phase of SPI */
switch (mode) {
case 0:
spiobj->spi_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
break;
case 1:
spiobj->spi_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_2EDGE;
break;
case 2:
spiobj->spi_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_1EDGE;
break;
default:
spiobj->spi_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
break;
}
if (spiobj->spi_struct.nss != SPI_NSS_SOFT) {
spiobj->spi_struct.nss = SPI_NSS_HARD;
spi_nss_output_enable(spiobj->spi);
}
/* Select SPI as master or slave */
spiobj->spi_struct.device_mode = (slave) ? SPI_SLAVE : SPI_MASTER;
dev_spi_struct_init(obj);
}
static const uint16_t baudrate_prescaler_table[] = {SPI_PSC_2,
SPI_PSC_4,
SPI_PSC_8,
SPI_PSC_16,
SPI_PSC_32,
SPI_PSC_64,
SPI_PSC_128,
SPI_PSC_256
};
/** Set the SPI baud rate
*
* Actual frequency may differ from the desired frequency due to available dividers and bus clock
* Configures the SPI peripheral's baud rate
* @param[in,out] obj The SPI object to configure
* @param[in] hz The baud rate in Hz
*/
void spi_frequency(spi_t *obj, int hz)
{
struct spi_s *spiobj = SPI_S(obj);
int spi_hz = 0;
uint8_t prescaler_rank = 0;
uint8_t last_index = (sizeof(baudrate_prescaler_table) / sizeof(baudrate_prescaler_table[0])) - 1;
spi_hz = dev_spi_clock_source_frequency_get(obj) / 2;
/* Config SPI prescaler according to input frequency*/
while ((spi_hz > hz) && (prescaler_rank < last_index)) {
spi_hz = spi_hz / 2;
prescaler_rank++;
}
spiobj->spi_struct.prescale = baudrate_prescaler_table[prescaler_rank];
dev_spi_struct_init(obj);
}
/** Write a block out in master mode and receive a value
*
* The total number of bytes sent and received will be the maximum of
* tx_length and rx_length. The bytes written will be padded with the
* value 0xff.
*
* @param[in] obj The SPI peripheral to use for sending
* @param[in] tx_buffer Pointer to the byte-array of data to write to the device
* @param[in] tx_length Number of bytes to write, may be zero
* @param[in] rx_buffer Pointer to the byte-array of data to read from the device
* @param[in] rx_length Number of bytes to read, may be zero
* @param[in] write_fill Default data transmitted while performing a read
* @returns
* The number of bytes written and read from the device. This is
* maximum of tx_length and rx_length.
*/
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, char write_fill)
{
int total = (tx_length > rx_length) ? tx_length : rx_length;
for (int i = 0; i < total; i++) {
char out = (i < tx_length) ? tx_buffer[i] : write_fill;
char in = spi_master_write(obj, out);
if (i < rx_length) {
rx_buffer[i] = in;
}
}
return total;
}
/** Write a byte out in master mode and receive a value
*
* @param[in] obj The SPI peripheral to use for sending
* @param[in] value The value to send
* @return Returns the value received during send
*/
int spi_master_write(spi_t *obj, int value)
{
int count = 0;
struct spi_s *spiobj = SPI_S(obj);
/* wait the SPI transmit buffer is empty */
while ((RESET == spi_i2s_flag_get(spiobj->spi, SPI_FLAG_TBE)) && (count++ < 1000));
if (count >= 1000) {
return -1;
} else {
spi_i2s_data_transmit(spiobj->spi, value);
}
count = 0;
/* wait the SPI receive buffer is not empty */
while ((RESET == spi_i2s_flag_get(spiobj->spi, SPI_FLAG_RBNE)) && (count++ < 1000));
if (count >= 1000) {
return -1;
} else {
return spi_i2s_data_receive(spiobj->spi);
}
}
/** Check if a value is available to read
*
* @param[in] obj The SPI peripheral to check
* @return non-zero if a value is available
*/
int spi_slave_receive(spi_t *obj)
{
int status;
struct spi_s *spiobj = SPI_S(obj);
/* check whether or not the SPI receive buffer is empty */
status = ((spi_i2s_flag_get(spiobj->spi, SPI_FLAG_RBNE) != RESET) ? 1 : 0);
return status;
}
/** Get a received value out of the SPI receive buffer in slave mode
*
* Blocks until a value is available
* @param[in] obj The SPI peripheral to read
* @return The value received
*/
int spi_slave_read(spi_t *obj)
{
int count = 0;
struct spi_s *spiobj = SPI_S(obj);
/* wait the SPI receive buffer is not empty */
while ((RESET == spi_i2s_flag_get(spiobj->spi, SPI_FLAG_RBNE)) && (count++ < 1000));
if (count >= 1000) {
return -1;
} else {
return spi_i2s_data_receive(spiobj->spi);
}
}
/** Write a value to the SPI peripheral in slave mode
*
* Blocks until the SPI peripheral can be written to
* @param[in] obj The SPI peripheral to write
* @param[in] value The value to write
*/
void spi_slave_write(spi_t *obj, int value)
{
struct spi_s *spiobj = SPI_S(obj);
/* wait the SPI transmit buffer is empty */
while (RESET == spi_i2s_flag_get(spiobj->spi, SPI_FLAG_TBE));
spi_i2s_data_transmit(spiobj->spi, value);
}
/** Checks if the specified SPI peripheral is in use
*
* @param[in] obj The SPI peripheral to check
* @return non-zero if the peripheral is currently transmitting
*/
int spi_busy(spi_t *obj)
{
int status;
struct spi_s *spiobj = SPI_S(obj);
/* check whether or not the SPI is busy */
status = ((spi_i2s_flag_get(spiobj->spi, SPI_FLAG_TRANS) != RESET) ? 1 : 0);
return status;
}
#endif

View File

@ -1,386 +1,388 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* 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 "gd32f30x.h"
#include "us_ticker_api.h"
#include "PeripheralNames.h"
#include "hal_tick.h"
#if TICKER_TIMER_WIDTH_BIT == 16
uint32_t time_before;
uint32_t total_elapsed_time;
#endif
/* this variable is set to 1 at the end of mbed_sdk_init function.
the ticker_read_us() function must not be called until the mbed_sdk_init is terminated */
extern int mbed_sdk_inited;
uint32_t ticker_timer_cnt;
uint32_t ticker_timer_ch0cv;
uint32_t ticker_timer_dmainten;
void ticker_timer_init(void);
#if TICKER_TIMER_WIDTH_BIT == 16
void ticker_16bits_timer_init(void);
#else
void ticker_32bits_timer_init(void);
#endif
void ticker_timer_irq_handler(void);
/* get TIMER clock */
static uint32_t timer_get_clock(uint32_t timer_periph);
uint32_t ticker_tick_get(void);
void ticker_timer_data_save(void);
void ticker_timer_data_save(void);
void ticker_timer_data_restore(void);
void ticker_timer_init(void)
{
#if TICKER_TIMER_WIDTH_BIT == 16
ticker_16bits_timer_init();
#else
ticker_32bits_timer_init();
#endif
}
/** get tick
*
* @return the tick
*/
uint32_t ticker_tick_get(void)
{
#if TICKER_TIMER_WIDTH_BIT == 16
uint32_t new_time;
if (mbed_sdk_inited) {
/* Apply the latest time recorded just before the sdk is inited */
new_time = ticker_read_us(get_us_ticker_data()) + time_before;
time_before = 0;
return (new_time / 1000);
} else {
/* Prevent small values from subtracting large ones
example:
0x0010-0xFFEE=FFFF0022 , (0xFFFF-0xFFEE+0x10+1=0x22,1 mean CNT=0 tick)
FFFF0022 & 0xFFFF = 0022
*/
new_time = us_ticker_read();
total_elapsed_time += (new_time - time_before) & 0xFFFF;
time_before = new_time;
return (total_elapsed_time / 1000);
}
#else // 32-bit timer
if (mbed_sdk_inited) {
return (ticker_read_us(get_us_ticker_data()) / 1000);
} else {
return (us_ticker_read() / 1000);
}
#endif
}
/** Get frequency and counter bits of this ticker.
*/
const ticker_info_t *us_ticker_get_info()
{
static const ticker_info_t info = {
1000000,
TICKER_TIMER_WIDTH_BIT
};
return &info;
}
/* config for 32bits TIMER */
#if TICKER_TIMER_WIDTH_BIT == 16
/** config the interrupt handler
*/
void ticker_timer_irq_handler(void)
{
if (SET == timer_interrupt_flag_get(TICKER_TIMER, TIMER_INT_FLAG_CH0)) {
timer_interrupt_flag_clear(TICKER_TIMER, TIMER_INT_FLAG_CH0);
us_ticker_irq_handler();
}
}
/** initialize the TIMER
*/
void ticker_16bits_timer_init(void)
{
timer_parameter_struct timer_initpara;
uint32_t timer_clk = timer_get_clock(TICKER_TIMER);
/* enable ticker timer clock */
TICKER_TIMER_RCU_CLOCK_ENABLE;
/* reset ticker timer peripheral */
TICKER_TIMER_RESET_ENABLE;
TICKER_TIMER_RESET_DISABLE;
/* TICKER_TIMER configuration */
timer_initpara.prescaler = (uint32_t)(timer_clk / 1000000) - 1;;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 0xFFFF;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TICKER_TIMER, &timer_initpara);
/* auto-reload preload disable */
timer_auto_reload_shadow_disable(TICKER_TIMER);
/* configure TIMER channel enable state */
timer_channel_output_state_config(TICKER_TIMER, TIMER_CH_0, TIMER_CCX_ENABLE);
/* configure TIMER primary output function */
timer_primary_output_config(TICKER_TIMER, ENABLE);
timer_enable(TICKER_TIMER);
/* Output compare channel 0 interrupt for mbed timeout */
NVIC_SetVector(TICKER_TIMER_IRQ, (uint32_t)ticker_timer_irq_handler);
NVIC_EnableIRQ(TICKER_TIMER_IRQ);
/* if define the FREEZE_TIMER_ON_DEBUG macro in mbed_app.json or other file,
hold the TICKER_TIMER counter for debug when core halted
*/
#if !defined(NDEBUG) && defined(FREEZE_TIMER_ON_DEBUG) && defined(TICKER_TIMER_DEBUG_STOP)
TICKER_TIMER_DEBUG_STOP;
#endif
timer_interrupt_disable(TICKER_TIMER, TIMER_INT_CH0);
/* used by ticker_tick_get() */
time_before = 0;
total_elapsed_time = 0;
}
/* config for 32bits TIMER */
#else
/** config the interrupt handler
*/
void ticker_timer_irq_handler(void)
{
if (SET == timer_interrupt_flag_get(TICKER_TIMER, TIMER_INT_FLAG_CH0)) {
timer_interrupt_flag_clear(TICKER_TIMER, TIMER_INT_FLAG_CH0);
us_ticker_irq_handler();
}
}
/** initialize the TIMER
*/
void ticker_32bits_timer_init(void)
{
timer_parameter_struct timer_initpara;
uint32_t timer_clk = timer_get_clock(TICKER_TIMER);
/* enable ticker timer clock */
TICKER_TIMER_RCU_CLOCK_ENABLE;
/* reset ticker timer peripheral */
TICKER_TIMER_RESET_ENABLE;
TICKER_TIMER_RESET_DISABLE;
/* TICKER_TIMER configuration */
timer_initpara.prescaler = (uint32_t)(timer_clk / 1000000) - 1;;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 0xFFFFFFFF;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TICKER_TIMER, &timer_initpara);
/* auto-reload preload disable */
timer_auto_reload_shadow_disable(TICKER_TIMER);
/* configure TIMER channel enable state */
timer_channel_output_state_config(TICKER_TIMER, TIMER_CH_0, TIMER_CCX_ENABLE);
/* configure TIMER primary output function */
timer_primary_output_config(TICKER_TIMER, ENABLE);
timer_enable(TICKER_TIMER);
/* Output compare channel 0 interrupt for mbed timeout */
NVIC_SetVector(TICKER_TIMER_IRQ, (uint32_t)ticker_timer_irq_handler);
NVIC_EnableIRQ(TICKER_TIMER_IRQ);
/* if define the FREEZE_TIMER_ON_DEBUG macro in mbed_app.json or other file,
hold the TICKER_TIMER counter for debug when core halted
*/
#if !defined(NDEBUG) && defined(FREEZE_TIMER_ON_DEBUG) && defined(TICKER_TIMER_DEBUG_STOP)
TICKER_TIMER_DEBUG_STOP;
#endif
timer_interrupt_disable(TICKER_TIMER, TIMER_INT_CH0);
}
#endif /* 16-bit/32-bit timer init */
/** Initialize the ticker
*
* Initialize or re-initialize the ticker. This resets all the
* clocking and prescaler registers, along with disabling
* the compare interrupt.
*
* @note Initialization properties tested by ::ticker_init_test
*/
void us_ticker_init(void)
{
/* TIMER is already initialized in ticker_timer_init() */
/* disable the TIMER interrupt */
timer_interrupt_disable(TICKER_TIMER, TIMER_INT_CH0);
/* configure TIMER channel enable state */
timer_channel_output_state_config(TICKER_TIMER, TIMER_CH_0, TIMER_CCX_ENABLE);
/* configure TIMER primary output function */
timer_primary_output_config(TICKER_TIMER, ENABLE);
timer_enable(TICKER_TIMER);
}
/** Read the current counter
*
* Read the current counter value without performing frequency conversions.
* If no rollover has occurred, the seconds passed since us_ticker_init()
* was called can be found by dividing the ticks returned by this function
* by the frequency returned by ::us_ticker_get_info.
*
* @return The current timer's counter value in ticks
*/
uint32_t us_ticker_read()
{
/* read TIMER counter value */
uint32_t count_value = 0U;
count_value = TIMER_CNT(TICKER_TIMER);
return (count_value);
}
/** Set interrupt for specified timestamp
*
* @param timestamp The time in ticks to be set
*
* @note no special handling needs to be done for times in the past
* as the common timer code will detect this and call
* us_ticker_fire_interrupt() if this is the case
*
* @note calling this function with timestamp of more than the supported
* number of bits returned by ::us_ticker_get_info results in undefined
* behavior.
*/
void us_ticker_set_interrupt(timestamp_t timestamp)
{
/* configure TIMER channel output pulse value.Only set this value when you interrupt disabled */
timer_channel_output_pulse_value_config(TICKER_TIMER, TIMER_CH_0, (uint32_t)timestamp);
/* clear TIMER interrupt flag,enable the TIMER interrupt */
timer_interrupt_flag_clear(TICKER_TIMER, TIMER_INT_FLAG_CH0);
timer_interrupt_enable(TICKER_TIMER, TIMER_INT_CH0);
}
/** Set pending interrupt that should be fired right away.
*
* The ticker should be initialized prior calling this function.
*/
void us_ticker_fire_interrupt(void)
{
/* clear TIMER interrupt flag */
timer_interrupt_flag_clear(TICKER_TIMER, TIMER_INT_FLAG_CH0);
/* channel 0 capture or compare event generation immediately,so CH0IF set for interrupt */
timer_event_software_generate(TICKER_TIMER, TIMER_EVENT_SRC_CH0G);
/* enable the TIMER interrupt */
timer_interrupt_enable(TICKER_TIMER, TIMER_INT_CH0);
}
/** Disable us ticker interrupt
*/
void us_ticker_disable_interrupt(void)
{
/* disable the TIMER interrupt */
timer_interrupt_disable(TICKER_TIMER, TIMER_INT_CH0);
}
/** Clear us ticker interrupt
* note: must be called with interrupts disabled function
*/
void us_ticker_clear_interrupt(void)
{
/* clear TIMER interrupt flag */
timer_interrupt_flag_clear(TICKER_TIMER, TIMER_INT_FLAG_CH0);
}
/** save ticker TIMER data when MCU go to deepsleep
*/
void ticker_timer_data_save(void)
{
ticker_timer_cnt = TIMER_CNT(TICKER_TIMER);
ticker_timer_ch0cv = TIMER_CH0CV(TICKER_TIMER);
ticker_timer_dmainten = TIMER_DMAINTEN(TICKER_TIMER);
}
/** restore ticker TIMER data when MCU go out deepsleep
*/
void ticker_timer_data_restore(void)
{
TIMER_CNT(TICKER_TIMER) = ticker_timer_cnt;
TIMER_CH0CV(TICKER_TIMER) = ticker_timer_ch0cv;
TIMER_DMAINTEN(TICKER_TIMER) = ticker_timer_dmainten;
}
/** Deinitialize the us ticker
*
* Powerdown the us ticker in preparation for sleep, powerdown, or reset.
*
* After this function is called, no other ticker functions should be called
* except us_ticker_init(), calling any function other than init is undefined.
*
* @note This function stops the ticker from counting.
*/
void us_ticker_free(void)
{
/* configure TIMER channel enable state */
timer_channel_output_state_config(TICKER_TIMER, TIMER_CH_0, TIMER_CCX_DISABLE);
/* configure TIMER primary output function */
timer_primary_output_config(TICKER_TIMER, DISABLE);
/* disable a TIMER */
timer_disable(TICKER_TIMER);
us_ticker_disable_interrupt();
}
/** get TIMER clock
* @param timer_dev: TIMER device information structrue
the structure is not necessary to be reconfigured after structrue initialization,
the structure parameters altering is automatically configured by core
* @return TIMER clock
*/
static uint32_t timer_get_clock(uint32_t timer_periph)
{
uint32_t timerclk;
if ((TIMER0 == timer_periph) || (TIMER7 == timer_periph) ||
(TIMER8 == timer_periph) || (TIMER9 == timer_periph) || (TIMER10 == timer_periph)) {
/* get the current APB2 TIMER clock source */
if (RCU_APB2_CKAHB_DIV1 == (RCU_CFG0 & RCU_CFG0_APB2PSC)) {
timerclk = rcu_clock_freq_get(CK_APB2);
} else {
timerclk = rcu_clock_freq_get(CK_APB2) * 2;
}
} else {
/* get the current APB1 TIMER clock source */
if (RCU_APB1_CKAHB_DIV1 == (RCU_CFG0 & RCU_CFG0_APB1PSC)) {
timerclk = rcu_clock_freq_get(CK_APB1);
} else {
timerclk = rcu_clock_freq_get(CK_APB1) * 2;
}
}
return timerclk;
}
/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 "gd32f30x.h"
#include "us_ticker_api.h"
#include "PeripheralNames.h"
#include "hal_tick.h"
#if TICKER_TIMER_WIDTH_BIT == 16
uint32_t time_before;
uint32_t total_elapsed_time;
#endif
/* this variable is set to 1 at the end of mbed_sdk_init function.
the ticker_read_us() function must not be called until the mbed_sdk_init is terminated */
extern int mbed_sdk_inited;
uint32_t ticker_timer_cnt;
uint32_t ticker_timer_ch0cv;
uint32_t ticker_timer_dmainten;
void ticker_timer_init(void);
#if TICKER_TIMER_WIDTH_BIT == 16
void ticker_16bits_timer_init(void);
#else
void ticker_32bits_timer_init(void);
#endif
void ticker_timer_irq_handler(void);
/* get TIMER clock */
static uint32_t timer_get_clock(uint32_t timer_periph);
uint32_t ticker_tick_get(void);
void ticker_timer_data_save(void);
void ticker_timer_data_save(void);
void ticker_timer_data_restore(void);
void ticker_timer_init(void)
{
#if TICKER_TIMER_WIDTH_BIT == 16
ticker_16bits_timer_init();
#else
ticker_32bits_timer_init();
#endif
}
/** get tick
*
* @return the tick
*/
uint32_t ticker_tick_get(void)
{
#if TICKER_TIMER_WIDTH_BIT == 16
uint32_t new_time;
if (mbed_sdk_inited) {
/* Apply the latest time recorded just before the sdk is inited */
new_time = ticker_read_us(get_us_ticker_data()) + time_before;
time_before = 0;
return (new_time / 1000);
} else {
/* Prevent small values from subtracting large ones
example:
0x0010-0xFFEE=FFFF0022 , (0xFFFF-0xFFEE+0x10+1=0x22,1 mean CNT=0 tick)
FFFF0022 & 0xFFFF = 0022
*/
new_time = us_ticker_read();
total_elapsed_time += (new_time - time_before) & 0xFFFF;
time_before = new_time;
return (total_elapsed_time / 1000);
}
#else // 32-bit timer
if (mbed_sdk_inited) {
return (ticker_read_us(get_us_ticker_data()) / 1000);
} else {
return (us_ticker_read() / 1000);
}
#endif
}
/** Get frequency and counter bits of this ticker.
*/
const ticker_info_t *us_ticker_get_info()
{
static const ticker_info_t info = {
1000000,
TICKER_TIMER_WIDTH_BIT
};
return &info;
}
/* config for 32bits TIMER */
#if TICKER_TIMER_WIDTH_BIT == 16
/** config the interrupt handler
*/
void ticker_timer_irq_handler(void)
{
if (SET == timer_interrupt_flag_get(TICKER_TIMER, TIMER_INT_FLAG_CH0)) {
timer_interrupt_flag_clear(TICKER_TIMER, TIMER_INT_FLAG_CH0);
us_ticker_irq_handler();
}
}
/** initialize the TIMER
*/
void ticker_16bits_timer_init(void)
{
timer_parameter_struct timer_initpara;
uint32_t timer_clk = timer_get_clock(TICKER_TIMER);
/* enable ticker timer clock */
TICKER_TIMER_RCU_CLOCK_ENABLE;
/* reset ticker timer peripheral */
TICKER_TIMER_RESET_ENABLE;
TICKER_TIMER_RESET_DISABLE;
/* TICKER_TIMER configuration */
timer_initpara.prescaler = (uint32_t)(timer_clk / 1000000) - 1;;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 0xFFFF;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TICKER_TIMER, &timer_initpara);
/* auto-reload preload disable */
timer_auto_reload_shadow_disable(TICKER_TIMER);
/* configure TIMER channel enable state */
timer_channel_output_state_config(TICKER_TIMER, TIMER_CH_0, TIMER_CCX_ENABLE);
/* configure TIMER primary output function */
timer_primary_output_config(TICKER_TIMER, ENABLE);
timer_enable(TICKER_TIMER);
/* Output compare channel 0 interrupt for mbed timeout */
NVIC_SetVector(TICKER_TIMER_IRQ, (uint32_t)ticker_timer_irq_handler);
NVIC_EnableIRQ(TICKER_TIMER_IRQ);
/* if define the FREEZE_TIMER_ON_DEBUG macro in mbed_app.json or other file,
hold the TICKER_TIMER counter for debug when core halted
*/
#if !defined(NDEBUG) && defined(FREEZE_TIMER_ON_DEBUG) && defined(TICKER_TIMER_DEBUG_STOP)
TICKER_TIMER_DEBUG_STOP;
#endif
timer_interrupt_disable(TICKER_TIMER, TIMER_INT_CH0);
/* used by ticker_tick_get() */
time_before = 0;
total_elapsed_time = 0;
}
/* config for 32bits TIMER */
#else
/** config the interrupt handler
*/
void ticker_timer_irq_handler(void)
{
if (SET == timer_interrupt_flag_get(TICKER_TIMER, TIMER_INT_FLAG_CH0)) {
timer_interrupt_flag_clear(TICKER_TIMER, TIMER_INT_FLAG_CH0);
us_ticker_irq_handler();
}
}
/** initialize the TIMER
*/
void ticker_32bits_timer_init(void)
{
timer_parameter_struct timer_initpara;
uint32_t timer_clk = timer_get_clock(TICKER_TIMER);
/* enable ticker timer clock */
TICKER_TIMER_RCU_CLOCK_ENABLE;
/* reset ticker timer peripheral */
TICKER_TIMER_RESET_ENABLE;
TICKER_TIMER_RESET_DISABLE;
/* TICKER_TIMER configuration */
timer_initpara.prescaler = (uint32_t)(timer_clk / 1000000) - 1;;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 0xFFFFFFFF;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TICKER_TIMER, &timer_initpara);
/* auto-reload preload disable */
timer_auto_reload_shadow_disable(TICKER_TIMER);
/* configure TIMER channel enable state */
timer_channel_output_state_config(TICKER_TIMER, TIMER_CH_0, TIMER_CCX_ENABLE);
/* configure TIMER primary output function */
timer_primary_output_config(TICKER_TIMER, ENABLE);
timer_enable(TICKER_TIMER);
/* Output compare channel 0 interrupt for mbed timeout */
NVIC_SetVector(TICKER_TIMER_IRQ, (uint32_t)ticker_timer_irq_handler);
NVIC_EnableIRQ(TICKER_TIMER_IRQ);
/* if define the FREEZE_TIMER_ON_DEBUG macro in mbed_app.json or other file,
hold the TICKER_TIMER counter for debug when core halted
*/
#if !defined(NDEBUG) && defined(FREEZE_TIMER_ON_DEBUG) && defined(TICKER_TIMER_DEBUG_STOP)
TICKER_TIMER_DEBUG_STOP;
#endif
timer_interrupt_disable(TICKER_TIMER, TIMER_INT_CH0);
}
#endif /* 16-bit/32-bit timer init */
/** Initialize the ticker
*
* Initialize or re-initialize the ticker. This resets all the
* clocking and prescaler registers, along with disabling
* the compare interrupt.
*
* @note Initialization properties tested by ::ticker_init_test
*/
void us_ticker_init(void)
{
/* TIMER is already initialized in ticker_timer_init() */
/* disable the TIMER interrupt */
timer_interrupt_disable(TICKER_TIMER, TIMER_INT_CH0);
/* configure TIMER channel enable state */
timer_channel_output_state_config(TICKER_TIMER, TIMER_CH_0, TIMER_CCX_ENABLE);
/* configure TIMER primary output function */
timer_primary_output_config(TICKER_TIMER, ENABLE);
timer_enable(TICKER_TIMER);
}
/** Read the current counter
*
* Read the current counter value without performing frequency conversions.
* If no rollover has occurred, the seconds passed since us_ticker_init()
* was called can be found by dividing the ticks returned by this function
* by the frequency returned by ::us_ticker_get_info.
*
* @return The current timer's counter value in ticks
*/
uint32_t us_ticker_read()
{
/* read TIMER counter value */
uint32_t count_value = 0U;
count_value = TIMER_CNT(TICKER_TIMER);
return (count_value);
}
/** Set interrupt for specified timestamp
*
* @param timestamp The time in ticks to be set
*
* @note no special handling needs to be done for times in the past
* as the common timer code will detect this and call
* us_ticker_fire_interrupt() if this is the case
*
* @note calling this function with timestamp of more than the supported
* number of bits returned by ::us_ticker_get_info results in undefined
* behavior.
*/
void us_ticker_set_interrupt(timestamp_t timestamp)
{
/* configure TIMER channel output pulse value.Only set this value when you interrupt disabled */
timer_channel_output_pulse_value_config(TICKER_TIMER, TIMER_CH_0, (uint32_t)timestamp);
/* clear TIMER interrupt flag,enable the TIMER interrupt */
timer_interrupt_flag_clear(TICKER_TIMER, TIMER_INT_FLAG_CH0);
timer_interrupt_enable(TICKER_TIMER, TIMER_INT_CH0);
}
/** Set pending interrupt that should be fired right away.
*
* The ticker should be initialized prior calling this function.
*/
void us_ticker_fire_interrupt(void)
{
/* clear TIMER interrupt flag */
timer_interrupt_flag_clear(TICKER_TIMER, TIMER_INT_FLAG_CH0);
/* channel 0 capture or compare event generation immediately,so CH0IF set for interrupt */
timer_event_software_generate(TICKER_TIMER, TIMER_EVENT_SRC_CH0G);
/* enable the TIMER interrupt */
timer_interrupt_enable(TICKER_TIMER, TIMER_INT_CH0);
}
/** Disable us ticker interrupt
*/
void us_ticker_disable_interrupt(void)
{
/* disable the TIMER interrupt */
timer_interrupt_disable(TICKER_TIMER, TIMER_INT_CH0);
}
/** Clear us ticker interrupt
* note: must be called with interrupts disabled function
*/
void us_ticker_clear_interrupt(void)
{
/* clear TIMER interrupt flag */
timer_interrupt_flag_clear(TICKER_TIMER, TIMER_INT_FLAG_CH0);
}
/** save ticker TIMER data when MCU go to deepsleep
*/
void ticker_timer_data_save(void)
{
ticker_timer_cnt = TIMER_CNT(TICKER_TIMER);
ticker_timer_ch0cv = TIMER_CH0CV(TICKER_TIMER);
ticker_timer_dmainten = TIMER_DMAINTEN(TICKER_TIMER);
}
/** restore ticker TIMER data when MCU go out deepsleep
*/
void ticker_timer_data_restore(void)
{
TIMER_CNT(TICKER_TIMER) = ticker_timer_cnt;
TIMER_CH0CV(TICKER_TIMER) = ticker_timer_ch0cv;
TIMER_DMAINTEN(TICKER_TIMER) = ticker_timer_dmainten;
}
/** Deinitialize the us ticker
*
* Powerdown the us ticker in preparation for sleep, powerdown, or reset.
*
* After this function is called, no other ticker functions should be called
* except us_ticker_init(), calling any function other than init is undefined.
*
* @note This function stops the ticker from counting.
*/
void us_ticker_free(void)
{
/* configure TIMER channel enable state */
timer_channel_output_state_config(TICKER_TIMER, TIMER_CH_0, TIMER_CCX_DISABLE);
/* configure TIMER primary output function */
timer_primary_output_config(TICKER_TIMER, DISABLE);
/* disable a TIMER */
timer_disable(TICKER_TIMER);
us_ticker_disable_interrupt();
}
/** get TIMER clock
* @param timer_dev: TIMER device information structrue
the structure is not necessary to be reconfigured after structrue initialization,
the structure parameters altering is automatically configured by core
* @return TIMER clock
*/
static uint32_t timer_get_clock(uint32_t timer_periph)
{
uint32_t timerclk;
if ((TIMER0 == timer_periph) || (TIMER7 == timer_periph) ||
(TIMER8 == timer_periph) || (TIMER9 == timer_periph) || (TIMER10 == timer_periph)) {
/* get the current APB2 TIMER clock source */
if (RCU_APB2_CKAHB_DIV1 == (RCU_CFG0 & RCU_CFG0_APB2PSC)) {
timerclk = rcu_clock_freq_get(CK_APB2);
} else {
timerclk = rcu_clock_freq_get(CK_APB2) * 2;
}
} else {
/* get the current APB1 TIMER clock source */
if (RCU_APB1_CKAHB_DIV1 == (RCU_CFG0 & RCU_CFG0_APB1PSC)) {
timerclk = rcu_clock_freq_get(CK_APB1);
} else {
timerclk = rcu_clock_freq_get(CK_APB1) * 2;
}
}
return timerclk;
}

View File

@ -1,41 +1,43 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 ARM Limited
*
* 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 MBED_MBED_RTX_H
#define MBED_MBED_RTX_H
#include <stdint.h>
#if defined(TARGET_GD32F307VG)
#ifndef INITIAL_SP
#define INITIAL_SP (0x20018000UL)
#endif
#endif
#if (defined(__GNUC__) && !defined(__CC_ARM) && !defined(__ARMCC_VERSION) && defined(TWO_RAM_REGIONS))
extern uint32_t __StackLimit[];
extern uint32_t __StackTop[];
extern uint32_t __end__[];
extern uint32_t __HeapLimit[];
#define HEAP_START ((unsigned char*)__end__)
#define HEAP_SIZE ((uint32_t)((uint32_t)__HeapLimit - (uint32_t)HEAP_START))
#define ISR_STACK_START ((unsigned char*)__StackLimit)
#define ISR_STACK_SIZE ((uint32_t)((uint32_t)__StackTop - (uint32_t)__StackLimit))
#endif
#endif /* MBED_MBED_RTX_H */
/* mbed Microcontroller Library
* Copyright (c) 2009-2018 ARM Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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 MBED_MBED_RTX_H
#define MBED_MBED_RTX_H
#include <stdint.h>
#if defined(TARGET_GD32F307VG)
#ifndef INITIAL_SP
#define INITIAL_SP (0x20018000UL)
#endif
#endif
#if (defined(__GNUC__) && !defined(__CC_ARM) && !defined(__ARMCC_VERSION) && defined(TWO_RAM_REGIONS))
extern uint32_t __StackLimit[];
extern uint32_t __StackTop[];
extern uint32_t __end__[];
extern uint32_t __HeapLimit[];
#define HEAP_START ((unsigned char*)__end__)
#define HEAP_SIZE ((uint32_t)((uint32_t)__HeapLimit - (uint32_t)HEAP_START))
#define ISR_STACK_START ((unsigned char*)__StackLimit)
#define ISR_STACK_SIZE ((uint32_t)((uint32_t)__StackTop - (uint32_t)__StackLimit))
#endif
#endif /* MBED_MBED_RTX_H */