mirror of https://github.com/ARMmbed/mbed-os.git
CM3DS: update GPIO, IRQ and port implementation
This commit adds the GPIO drivers. The HAL implementations (gpio_api.c, gpio_irq_api.c, port_api.c) now call these drivers. Legacy definitions have been removed. Serial HAL implementation has been changed to compile at this stage. Change-Id: Ib76a3186358f5029ed350da671132e8aa11194f7 Signed-off-by: Galanakis, Minos <minos.galanakis@arm.com>pull/6170/head
parent
ffc7b91128
commit
3abc3faba2
|
@ -1,5 +1,5 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2017 ARM Limited
|
||||
* 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.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2017 ARM Limited
|
||||
* 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.
|
||||
|
|
|
@ -202,168 +202,6 @@ typedef struct
|
|||
#define CMSDK_UART_BAUDDIV_Pos 0 /* CMSDK_UART BAUDDIV: BAUDDIV Position */
|
||||
#define CMSDK_UART_BAUDDIV_Msk (0xFFFFFul << CMSDK_UART_BAUDDIV_Pos) /* CMSDK_UART BAUDDIV: BAUDDIV Mask */
|
||||
|
||||
/*-------------------- General Purpose Input Output (GPIO) -------------------*/
|
||||
typedef struct
|
||||
{
|
||||
__IO uint32_t DATA; /* Offset: 0x000 (R/W) DATA Register */
|
||||
__IO uint32_t DATAOUT; /* Offset: 0x004 (R/W) Data Output Latch Register */
|
||||
uint32_t RESERVED0[2];
|
||||
__IO uint32_t OUTENABLESET; /* Offset: 0x010 (R/W) Output Enable Set Register */
|
||||
__IO uint32_t OUTENABLECLR; /* Offset: 0x014 (R/W) Output Enable Clear Register */
|
||||
__IO uint32_t ALTFUNCSET; /* Offset: 0x018 (R/W) Alternate Function Set Register */
|
||||
__IO uint32_t ALTFUNCCLR; /* Offset: 0x01C (R/W) Alternate Function Clear Register */
|
||||
__IO uint32_t INTENSET; /* Offset: 0x020 (R/W) Interrupt Enable Set Register */
|
||||
__IO uint32_t INTENCLR; /* Offset: 0x024 (R/W) Interrupt Enable Clear Register */
|
||||
__IO uint32_t INTTYPESET; /* Offset: 0x028 (R/W) Interrupt Type Set Register */
|
||||
__IO uint32_t INTTYPECLR; /* Offset: 0x02C (R/W) Interrupt Type Clear Register */
|
||||
__IO uint32_t INTPOLSET; /* Offset: 0x030 (R/W) Interrupt Polarity Set Register */
|
||||
__IO uint32_t INTPOLCLR; /* Offset: 0x034 (R/W) Interrupt Polarity Clear Register */
|
||||
union {
|
||||
__I uint32_t INTSTATUS; /* Offset: 0x038 (R/ ) Interrupt Status Register */
|
||||
__O uint32_t INTCLEAR; /* Offset: 0x038 ( /W) Interrupt Clear Register */
|
||||
};
|
||||
uint32_t RESERVED1[241];
|
||||
__IO uint32_t LB_MASKED[256]; /* Offset: 0x400 - 0x7FC Lower byte Masked Access Register (R/W) */
|
||||
__IO uint32_t UB_MASKED[256]; /* Offset: 0x800 - 0xBFC Upper byte Masked Access Register (R/W) */
|
||||
} CMSDK_GPIO_TypeDef;
|
||||
|
||||
#define CMSDK_GPIO_DATA_Pos 0 /* CMSDK_GPIO DATA: DATA Position */
|
||||
#define CMSDK_GPIO_DATA_Msk (0xFFFFul << CMSDK_GPIO_DATA_Pos) /* CMSDK_GPIO DATA: DATA Mask */
|
||||
|
||||
#define CMSDK_GPIO_DATAOUT_Pos 0 /* CMSDK_GPIO DATAOUT: DATAOUT Position */
|
||||
#define CMSDK_GPIO_DATAOUT_Msk (0xFFFFul << CMSDK_GPIO_DATAOUT_Pos) /* CMSDK_GPIO DATAOUT: DATAOUT Mask */
|
||||
|
||||
#define CMSDK_GPIO_OUTENSET_Pos 0 /* CMSDK_GPIO OUTEN: OUTEN Position */
|
||||
#define CMSDK_GPIO_OUTENSET_Msk (0xFFFFul << CMSDK_GPIO_OUTEN_Pos) /* CMSDK_GPIO OUTEN: OUTEN Mask */
|
||||
|
||||
#define CMSDK_GPIO_OUTENCLR_Pos 0 /* CMSDK_GPIO OUTEN: OUTEN Position */
|
||||
#define CMSDK_GPIO_OUTENCLR_Msk (0xFFFFul << CMSDK_GPIO_OUTEN_Pos) /* CMSDK_GPIO OUTEN: OUTEN Mask */
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNCSET_Pos 0 /* CMSDK_GPIO ALTFUNC: ALTFUNC Position */
|
||||
#define CMSDK_GPIO_ALTFUNCSET_Msk (0xFFFFul << CMSDK_GPIO_ALTFUNC_Pos) /* CMSDK_GPIO ALTFUNC: ALTFUNC Mask */
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNCCLR_Pos 0 /* CMSDK_GPIO ALTFUNC: ALTFUNC Position */
|
||||
#define CMSDK_GPIO_ALTFUNCCLR_Msk (0xFFFFul << CMSDK_GPIO_ALTFUNC_Pos) /* CMSDK_GPIO ALTFUNC: ALTFUNC Mask */
|
||||
|
||||
#define CMSDK_GPIO_INTENSET_Pos 0 /* CMSDK_GPIO INTEN: INTEN Position */
|
||||
#define CMSDK_GPIO_INTENSET_Msk (0xFFFFul << CMSDK_GPIO_INTEN_Pos) /* CMSDK_GPIO INTEN: INTEN Mask */
|
||||
|
||||
#define CMSDK_GPIO_INTENCLR_Pos 0 /* CMSDK_GPIO INTEN: INTEN Position */
|
||||
#define CMSDK_GPIO_INTENCLR_Msk (0xFFFFul << CMSDK_GPIO_INTEN_Pos) /* CMSDK_GPIO INTEN: INTEN Mask */
|
||||
|
||||
#define CMSDK_GPIO_INTTYPESET_Pos 0 /* CMSDK_GPIO INTTYPE: INTTYPE Position */
|
||||
#define CMSDK_GPIO_INTTYPESET_Msk (0xFFFFul << CMSDK_GPIO_INTTYPE_Pos) /* CMSDK_GPIO INTTYPE: INTTYPE Mask */
|
||||
|
||||
#define CMSDK_GPIO_INTTYPECLR_Pos 0 /* CMSDK_GPIO INTTYPE: INTTYPE Position */
|
||||
#define CMSDK_GPIO_INTTYPECLR_Msk (0xFFFFul << CMSDK_GPIO_INTTYPE_Pos) /* CMSDK_GPIO INTTYPE: INTTYPE Mask */
|
||||
|
||||
#define CMSDK_GPIO_INTPOLSET_Pos 0 /* CMSDK_GPIO INTPOL: INTPOL Position */
|
||||
#define CMSDK_GPIO_INTPOLSET_Msk (0xFFFFul << CMSDK_GPIO_INTPOL_Pos) /* CMSDK_GPIO INTPOL: INTPOL Mask */
|
||||
|
||||
#define CMSDK_GPIO_INTPOLCLR_Pos 0 /* CMSDK_GPIO INTPOL: INTPOL Position */
|
||||
#define CMSDK_GPIO_INTPOLCLR_Msk (0xFFFFul << CMSDK_GPIO_INTPOL_Pos) /* CMSDK_GPIO INTPOL: INTPOL Mask */
|
||||
|
||||
#define CMSDK_GPIO_INTSTATUS_Pos 0 /* CMSDK_GPIO INTSTATUS: INTSTATUS Position */
|
||||
#define CMSDK_GPIO_INTSTATUS_Msk (0xFFul << CMSDK_GPIO_INTSTATUS_Pos) /* CMSDK_GPIO INTSTATUS: INTSTATUS Mask */
|
||||
|
||||
#define CMSDK_GPIO_INTCLEAR_Pos 0 /* CMSDK_GPIO INTCLEAR: INTCLEAR Position */
|
||||
#define CMSDK_GPIO_INTCLEAR_Msk (0xFFul << CMSDK_GPIO_INTCLEAR_Pos) /* CMSDK_GPIO INTCLEAR: INTCLEAR Mask */
|
||||
|
||||
#define CMSDK_GPIO_MASKLOWBYTE_Pos 0 /* CMSDK_GPIO MASKLOWBYTE: MASKLOWBYTE Position */
|
||||
#define CMSDK_GPIO_MASKLOWBYTE_Msk (0x00FFul << CMSDK_GPIO_MASKLOWBYTE_Pos) /* CMSDK_GPIO MASKLOWBYTE: MASKLOWBYTE Mask */
|
||||
|
||||
#define CMSDK_GPIO_MASKHIGHBYTE_Pos 0 /* CMSDK_GPIO MASKHIGHBYTE: MASKHIGHBYTE Position */
|
||||
#define CMSDK_GPIO_MASKHIGHBYTE_Msk (0xFF00ul << CMSDK_GPIO_MASKHIGHBYTE_Pos) /* CMSDK_GPIO MASKHIGHBYTE: MASKHIGHBYTE Mask */
|
||||
|
||||
/* GPIO Alternate function pin numbers */
|
||||
#define CMSDK_GPIO_ALTFUNC_SH0_UART2_RX 0 /* Shield 0 UART 2 Rx */
|
||||
#define CMSDK_GPIO_ALTFUNC_SH0_UART2_RX_SET (CMSDK_GPIO_ALTFUNC_SH0_UART2_RX % 16)
|
||||
#define CMSDK_GPIO_SH0_UART2_RX_GPIO_NUM (CMSDK_GPIO_ALTFUNC_SH0_UART2_RX / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_SH0_UART2_TX 4 /* Shield 0 UART 2 Tx */
|
||||
#define CMSDK_GPIO_ALTFUNC_SH0_UART2_TX_SET (CMSDK_GPIO_ALTFUNC_SH0_UART2_TX % 16)
|
||||
#define CMSDK_GPIO_SH0_UART2_TX_GPIO_NUM (CMSDK_GPIO_ALTFUNC_SH0_UART2_TX / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_SH1_UART3_RX 26 /* Shield 1 UART 3 Rx */
|
||||
#define CMSDK_GPIO_ALTFUNC_SH1_UART3_RX_SET (CMSDK_GPIO_ALTFUNC_SH1_UART3_RX % 16)
|
||||
#define CMSDK_GPIO_SH1_UART3_RX_GPIO_NUM (CMSDK_GPIO_ALTFUNC_SH1_UART3_RX / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_SH1_UART3_TX 30 /* Shield 1 UART 3 Tx */
|
||||
#define CMSDK_GPIO_ALTFUNC_SH1_UART3_TX_SET (CMSDK_GPIO_ALTFUNC_SH1_UART3_TX % 16)
|
||||
#define CMSDK_GPIO_SH1_UART3_TX_GPIO_NUM (CMSDK_GPIO_ALTFUNC_SH1_UART3_TX / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_UART4_RX 23 /* UART 4 Rx */
|
||||
#define CMSDK_GPIO_ALTFUNC_UART4_RX_SET (CMSDK_GPIO_ALTFUNC_UART4_RX % 16)
|
||||
#define CMSDK_GPIO_UART4_RX_GPIO_NUM (CMSDK_GPIO_ALTFUNC_UART4_RX / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_UART4_TX 24 /* UART 4 Tx */
|
||||
#define CMSDK_GPIO_ALTFUNC_UART4_TX_SET (CMSDK_GPIO_ALTFUNC_UART4_TX % 16)
|
||||
#define CMSDK_GPIO_UART4_TX_GPIO_NUM (CMSDK_GPIO_ALTFUNC_UART4_TX / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_SH0_SCL_I2C 5 /* Shield 0 SCL I2S */
|
||||
#define CMSDK_GPIO_ALTFUNC_SH0_SCL_I2C_SET (CMSDK_GPIO_ALTFUNC_SH0_SCL_I2C % 16)
|
||||
#define CMSDK_GPIO_SH0_SCL_I2C_GPIO_NUM (CMSDK_GPIO_ALTFUNC_SH0_SCL_I2C / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_SH0_SDA_I2C 15 /* Shield 0 SDA I2S */
|
||||
#define CMSDK_GPIO_ALTFUNC_SH0_SDA_I2C_SET (CMSDK_GPIO_ALTFUNC_SH0_SDA_I2C % 16)
|
||||
#define CMSDK_GPIO_SH0_SDA_I2C_GPIO_NUM (CMSDK_GPIO_ALTFUNC_SH0_SDA_I2C / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_SH1_SCL_I2C 31 /* Shield 1 SCL I2S */
|
||||
#define CMSDK_GPIO_ALTFUNC_SH1_SCL_I2C_SET (CMSDK_GPIO_ALTFUNC_SH1_SCL_I2C % 16)
|
||||
#define CMSDK_GPIO_SH1_SCL_I2C_GPIO_NUM (CMSDK_GPIO_ALTFUNC_SH1_SCL_I2C / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_SH1_SDA_I2C 41 /* Shield 1 SDA I2S */
|
||||
#define CMSDK_GPIO_ALTFUNC_SH1_SDA_I2C_SET (CMSDK_GPIO_ALTFUNC_SH1_SDA_I2C % 16)
|
||||
#define CMSDK_GPIO_SH1_SDA_I2C_GPIO_NUM (CMSDK_GPIO_ALTFUNC_SH1_SDA_I2C / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_SH0_SCK_SPI 11 /* Shield 0 SCK SPI */
|
||||
#define CMSDK_GPIO_ALTFUNC_SH0_SCK_SPI_SET (CMSDK_GPIO_ALTFUNC_SH0_SCK_SPI % 16)
|
||||
#define CMSDK_GPIO_SH0_SCK_SPI_GPIO_NUM (CMSDK_GPIO_ALTFUNC_SH0_SCK_SPI / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_SH0_CS_SPI 12 /* Shield 0 CS SPI */
|
||||
#define CMSDK_GPIO_ALTFUNC_SH0_CS_SPI_SET (CMSDK_GPIO_ALTFUNC_SH0_CS_SPI % 16)
|
||||
#define CMSDK_GPIO_SH0_CS_SPI_GPIO_NUM (CMSDK_GPIO_ALTFUNC_SH0_CS_SPI / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_SH0_MOSI_SPI 13 /* Shield 0 MOSI SPI */
|
||||
#define CMSDK_GPIO_ALTFUNC_SH0_MOSI_SPI_SET (CMSDK_GPIO_ALTFUNC_SH0_MOSI_SPI % 16)
|
||||
#define CMSDK_GPIO_SH0_MOSI_SPI_GPIO_NUM (CMSDK_GPIO_ALTFUNC_SH0_MOSI_SPI / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_SH0_MISO_SPI 14 /* Shield 0 MISO SPI */
|
||||
#define CMSDK_GPIO_ALTFUNC_SH0_MISO_SPI_SET (CMSDK_GPIO_ALTFUNC_SH0_MISO_SPI % 16)
|
||||
#define CMSDK_GPIO_SH0_MISO_SPI_GPIO_NUM (CMSDK_GPIO_ALTFUNC_SH0_MISO_SPI / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_SH1_SCK_SPI 44 /* Shield 1 SCK SPI */
|
||||
#define CMSDK_GPIO_ALTFUNC_SH1_SCK_SPI_SET (CMSDK_GPIO_ALTFUNC_SH1_SCK_SPI % 16)
|
||||
#define CMSDK_GPIO_SH1_SCK_SPI_GPIO_NUM (CMSDK_GPIO_ALTFUNC_SH1_SCK_SPI / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_SH1_CS_SPI 38 /* Shield 1 CS SPI */
|
||||
#define CMSDK_GPIO_ALTFUNC_SH1_CS_SPI_SET (CMSDK_GPIO_ALTFUNC_SH1_CS_SPI % 16)
|
||||
#define CMSDK_GPIO_SH1_CS_SPI_GPIO_NUM (CMSDK_GPIO_ALTFUNC_SH1_CS_SPI / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_SH1_MOSI_SPI 39 /* Shield 1 MOSI SPI */
|
||||
#define CMSDK_GPIO_ALTFUNC_SH1_MOSI_SPI_SET (CMSDK_GPIO_ALTFUNC_SH1_MOSI_SPI % 16)
|
||||
#define CMSDK_GPIO_SH1_MOSI_SPI_GPIO_NUM (CMSDK_GPIO_ALTFUNC_SH1_MOSI_SPI / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_SH1_MISO_SPI 40 /* Shield 1 MISO SPI */
|
||||
#define CMSDK_GPIO_ALTFUNC_SH1_MISO_SPI_SET (CMSDK_GPIO_ALTFUNC_SH1_MISO_SPI % 16)
|
||||
#define CMSDK_GPIO_SH1_MISO_SPI_GPIO_NUM (CMSDK_GPIO_ALTFUNC_SH1_MISO_SPI / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_ADC_SCK_SPI 19 /* Shield ADC SCK SPI */
|
||||
#define CMSDK_GPIO_ALTFUNC_ADC_SCK_SPI_SET (CMSDK_GPIO_ALTFUNC_ADC_SCK_SPI % 16)
|
||||
#define CMSDK_GPIO_ADC_SCK_SPI_GPIO_NUM (CMSDK_GPIO_ALTFUNC_ADC_SCK_SPI / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_ADC_CS_SPI 16 /* Shield ADC CS SPI */
|
||||
#define CMSDK_GPIO_ALTFUNC_ADC_CS_SPI_SET (CMSDK_GPIO_ALTFUNC_ADC_CS_SPI % 16)
|
||||
#define CMSDK_GPIO_ADC_CS_SPI_GPIO_NUM (CMSDK_GPIO_ALTFUNC_ADC_CS_SPI / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_ADC_MOSI_SPI 18 /* Shield ADC MOSI SPI */
|
||||
#define CMSDK_GPIO_ALTFUNC_ADC_MOSI_SPI_SET (CMSDK_GPIO_ALTFUNC_ADC_MOSI_SPI % 16)
|
||||
#define CMSDK_GPIO_ADC_MOSI_SPI_GPIO_NUM (CMSDK_GPIO_ALTFUNC_ADC_MOSI_SPI / 16)
|
||||
|
||||
#define CMSDK_GPIO_ALTFUNC_ADC_MISO_SPI 17 /* Shield ADC MISO SPI */
|
||||
#define CMSDK_GPIO_ALTFUNC_ADC_MISO_SPI_SET (CMSDK_GPIO_ALTFUNC_ADC_MISO_SPI % 16)
|
||||
#define CMSDK_GPIO_ADC_MISO_SPI_GPIO_NUM (CMSDK_GPIO_ALTFUNC_ADC_MISO_SPI / 16)
|
||||
|
||||
/*------------- System Control (SYSCON) --------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
|
@ -577,12 +415,6 @@ typedef struct
|
|||
#define CMSDK_UART4 ((CMSDK_UART_TypeDef *) CMSDK_UART4_BASE )
|
||||
#define CMSDK_RTC ((CMSDK_RTC_TypeDef *) CMSDK_RTC_BASE )
|
||||
#define CMSDK_WATCHDOG ((CMSDK_WATCHDOG_TypeDef *) CMSDK_WATCHDOG_BASE )
|
||||
#define CMSDK_GPIO0 ((CMSDK_GPIO_TypeDef *) CMSDK_GPIO0_BASE )
|
||||
#define CMSDK_GPIO1 ((CMSDK_GPIO_TypeDef *) CMSDK_GPIO1_BASE )
|
||||
#define CMSDK_GPIO2 ((CMSDK_GPIO_TypeDef *) CMSDK_GPIO2_BASE )
|
||||
#define CMSDK_GPIO3 ((CMSDK_GPIO_TypeDef *) CMSDK_GPIO3_BASE )
|
||||
#define CMSDK_GPIO4 ((CMSDK_GPIO_TypeDef *) CMSDK_GPIO4_BASE )
|
||||
#define CMSDK_GPIO5 ((CMSDK_GPIO_TypeDef *) CMSDK_GPIO5_BASE )
|
||||
#define CMSDK_SYSCON ((CMSDK_SYSCON_TypeDef *) CMSDK_SYSCTRL_BASE )
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -30,4 +30,16 @@
|
|||
#define ARM_CMSDK_TIMER0
|
||||
#define ARM_CMSDK_TIMER1
|
||||
|
||||
/* ARM GPIO */
|
||||
#define ARM_GPIO0
|
||||
#define ARM_GPIO1
|
||||
#define ARM_GPIO2
|
||||
#define ARM_GPIO3
|
||||
|
||||
/* ARM MPS2 IO FPGAIO */
|
||||
#define ARM_MPS2_IO_FPGAIO
|
||||
|
||||
/* ARM MPS2 IO SCC */
|
||||
#define ARM_MPS2_IO_SCC
|
||||
|
||||
#endif /* __ARM_LTD_DEVICE_CFG_H__ */
|
||||
|
|
|
@ -0,0 +1,316 @@
|
|||
/*
|
||||
* Copyright (c) 2016-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 "arm_gpio_drv.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* GPIO state definitions */
|
||||
#define ARM_GPIO_INITIALIZED (1 << 0)
|
||||
|
||||
#define MAX_PIN_NBR 16
|
||||
|
||||
/* GPIO register map structure */
|
||||
struct arm_gpio_reg_map_t {
|
||||
volatile uint32_t data; /* Offset: 0x000 (R/W) Data register */
|
||||
volatile uint32_t dataout; /* Offset: 0x004 (R/W) Data output
|
||||
* latch register */
|
||||
volatile uint32_t reserved0[2];
|
||||
volatile uint32_t outenableset; /* Offset: 0x010 (R/W) Output enable
|
||||
* set register */
|
||||
volatile uint32_t outenableclr; /* Offset: 0x014 (R/W) Output enable
|
||||
* clear register */
|
||||
volatile uint32_t altfuncset; /* Offset: 0x018 (R/W) Alternate function
|
||||
* set register */
|
||||
volatile uint32_t altfuncclr; /* Offset: 0x01C (R/W) Alternate function
|
||||
* clear register */
|
||||
volatile uint32_t intenset; /* Offset: 0x020 (R/W) Interrupt enable
|
||||
* set register */
|
||||
volatile uint32_t intenclr; /* Offset: 0x024 (R/W) Interrupt enable
|
||||
* clear register */
|
||||
volatile uint32_t inttypeset; /* Offset: 0x028 (R/W) Interrupt type
|
||||
* set register */
|
||||
volatile uint32_t inttypeclr; /* Offset: 0x02C (R/W) Interrupt type
|
||||
* clear register */
|
||||
volatile uint32_t intpolset; /* Offset: 0x030 (R/W) Interrupt polarity
|
||||
* set register */
|
||||
volatile uint32_t intpolclr; /* Offset: 0x034 (R/W) Interrupt polarity
|
||||
* clear register */
|
||||
union {
|
||||
volatile uint32_t intstatus; /* Offset: 0x038 (R/ ) Interrupt status
|
||||
* register */
|
||||
volatile uint32_t intclear; /* Offset: 0x038 ( /W) Interrupt clear
|
||||
* register */
|
||||
}intreg;
|
||||
volatile uint32_t reserved1[241];
|
||||
volatile uint32_t lb_masked[256]; /* Offset: 0x400 - 0x7FC (R/W)
|
||||
* Lower byte masked access register */
|
||||
volatile uint32_t ub_masked[256]; /* Offset: 0x800 - 0xBFC (R/W)
|
||||
* Upper byte masked access register */
|
||||
};
|
||||
|
||||
/*
|
||||
* \brief Configures the pin or port.
|
||||
*
|
||||
* \param[in] p_gpio_port GPIO port to configure \ref ahbarm_gpio_reg_map_t
|
||||
* \param[in] mask Pin bit mask.
|
||||
* \param[in] flags Pin flags.
|
||||
*/
|
||||
static void set_port_config(struct arm_gpio_reg_map_t* p_gpio_port,
|
||||
uint32_t mask,
|
||||
uint32_t flags)
|
||||
{
|
||||
if(flags & ARM_GPIO_PIN_DISABLE) {
|
||||
p_gpio_port->altfuncset = mask;
|
||||
return;
|
||||
}
|
||||
|
||||
if(flags & ARM_GPIO_OUTPUT) {
|
||||
p_gpio_port->outenableset = mask;
|
||||
} else if(flags & ARM_GPIO_INPUT) {
|
||||
p_gpio_port->outenableclr = mask;
|
||||
}
|
||||
|
||||
/* Sets interrupt configuration */
|
||||
if(flags & ARM_GPIO_IRQ) {
|
||||
/* Interrupt type: EDGE = 1 - LEVEL = 0 */
|
||||
if(flags & ARM_GPIO_IRQ_EDGE) {
|
||||
p_gpio_port->inttypeset = mask;
|
||||
} else if(flags & ARM_GPIO_IRQ_LEVEL) {
|
||||
p_gpio_port->inttypeclr = mask;
|
||||
}
|
||||
|
||||
/* Interrupt polarity */
|
||||
if(flags & ARM_GPIO_IRQ_ACTIVE_LOW) {
|
||||
p_gpio_port->intpolclr = mask;
|
||||
} else if(flags & ARM_GPIO_IRQ_ACTIVE_HIGH) {
|
||||
p_gpio_port->intpolset = mask;
|
||||
}
|
||||
}
|
||||
|
||||
if(flags & ARM_GPIO_PIN_ENABLE) {
|
||||
p_gpio_port->altfuncclr = mask;
|
||||
}
|
||||
}
|
||||
|
||||
void arm_gpio_init(struct arm_gpio_dev_t* dev)
|
||||
{
|
||||
struct arm_gpio_reg_map_t* p_gpio_port =
|
||||
(struct arm_gpio_reg_map_t*)dev->cfg->base;
|
||||
|
||||
if(dev->data->state != ARM_GPIO_INITIALIZED) {
|
||||
/* Disables all pins in this port */
|
||||
set_port_config(p_gpio_port, DEFAULT_PORT_MASK, ARM_GPIO_PIN_DISABLE);
|
||||
|
||||
dev->data->port_mask = DEFAULT_PORT_MASK;
|
||||
dev->data->state = ARM_GPIO_INITIALIZED;
|
||||
}
|
||||
}
|
||||
|
||||
enum arm_gpio_error_t arm_gpio_config(struct arm_gpio_dev_t* dev,
|
||||
enum arm_gpio_access_t access,
|
||||
uint8_t pin_num,
|
||||
uint32_t flags)
|
||||
{
|
||||
uint32_t pin_mask;
|
||||
struct arm_gpio_reg_map_t* p_gpio_port =
|
||||
(struct arm_gpio_reg_map_t*)dev->cfg->base;
|
||||
|
||||
if(dev->data->state != ARM_GPIO_INITIALIZED) {
|
||||
return ARM_GPIO_ERR_PORT_NOT_INIT;
|
||||
}
|
||||
|
||||
if(pin_num >= MAX_PIN_NBR) {
|
||||
return ARM_GPIO_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
switch(access) {
|
||||
case ARM_GPIO_ACCESS_PIN:
|
||||
pin_mask = (1UL << pin_num);
|
||||
set_port_config(p_gpio_port, pin_mask, flags);
|
||||
break;
|
||||
case ARM_GPIO_ACCESS_PORT:
|
||||
set_port_config(p_gpio_port, dev->data->port_mask, flags);
|
||||
break;
|
||||
/* default: The default is not defined intentionally to force the
|
||||
* compiler to check that all the enumeration values are
|
||||
* covered in the switch.*/
|
||||
}
|
||||
|
||||
return ARM_GPIO_ERR_NONE;
|
||||
}
|
||||
|
||||
enum arm_gpio_error_t arm_gpio_write(struct arm_gpio_dev_t* dev,
|
||||
enum arm_gpio_access_t access,
|
||||
uint8_t pin_num,
|
||||
uint32_t value)
|
||||
{
|
||||
struct arm_gpio_reg_map_t* p_gpio_port =
|
||||
(struct arm_gpio_reg_map_t*)dev->cfg->base;
|
||||
|
||||
if(pin_num >= MAX_PIN_NBR) {
|
||||
return ARM_GPIO_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* As ARM is a read-modify-write architecture, before set a
|
||||
* value on a GPIO register it is required to disable the
|
||||
* interrupts to prevent problems in a multitasking
|
||||
* environment */
|
||||
switch(access) {
|
||||
case ARM_GPIO_ACCESS_PIN:
|
||||
if(value) {
|
||||
/* Sets the pin */
|
||||
p_gpio_port->dataout |= (1UL << pin_num);
|
||||
} else {
|
||||
/* Clears the pin */
|
||||
p_gpio_port->dataout &= ~(1UL << pin_num);
|
||||
}
|
||||
break;
|
||||
case ARM_GPIO_ACCESS_PORT:
|
||||
if(value) {
|
||||
/* Sets masked pins */
|
||||
p_gpio_port->dataout |= dev->data->port_mask;
|
||||
} else {
|
||||
/* Clears masked pins */
|
||||
p_gpio_port->dataout &= ~(dev->data->port_mask);
|
||||
}
|
||||
break;
|
||||
/* default: The default is not defined intentionally to force the
|
||||
* compiler to check that all the enumeration values are
|
||||
* covered in the switch. */
|
||||
}
|
||||
|
||||
return ARM_GPIO_ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t arm_gpio_read(struct arm_gpio_dev_t* dev, enum arm_gpio_access_t access,
|
||||
uint8_t pin_num)
|
||||
{
|
||||
uint32_t value;
|
||||
struct arm_gpio_reg_map_t* p_gpio_port =
|
||||
(struct arm_gpio_reg_map_t*)dev->cfg->base;
|
||||
|
||||
value = p_gpio_port->data;
|
||||
|
||||
if(access == ARM_GPIO_ACCESS_PIN) {
|
||||
if(pin_num >= MAX_PIN_NBR) {
|
||||
return -1;
|
||||
}
|
||||
value = ((value >> pin_num) & 1UL);
|
||||
} else {
|
||||
value &= dev->data->port_mask;
|
||||
}
|
||||
|
||||
return (int32_t)value;
|
||||
}
|
||||
|
||||
enum arm_gpio_error_t arm_gpio_set_interrupt(struct arm_gpio_dev_t* dev,
|
||||
enum arm_gpio_access_t access,
|
||||
uint8_t pin_num,
|
||||
enum arm_gpio_irq_status_t status)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
struct arm_gpio_reg_map_t* p_gpio_port =
|
||||
(struct arm_gpio_reg_map_t*)dev->cfg->base;
|
||||
|
||||
if(dev->data->state != ARM_GPIO_INITIALIZED) {
|
||||
return ARM_GPIO_ERR_PORT_NOT_INIT;
|
||||
}
|
||||
|
||||
if(pin_num >= MAX_PIN_NBR) {
|
||||
return ARM_GPIO_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
switch(access) {
|
||||
case ARM_GPIO_ACCESS_PIN:
|
||||
mask = (1UL << pin_num);
|
||||
break;
|
||||
case ARM_GPIO_ACCESS_PORT:
|
||||
mask = dev->data->port_mask;
|
||||
break;
|
||||
/* default: The default is not defined intentionally to force the
|
||||
* compiler to check that all the enumeration values are
|
||||
* covered in the switch.*/
|
||||
}
|
||||
|
||||
if(status == ARM_GPIO_IRQ_ENABLE) {
|
||||
p_gpio_port->intenset = mask;
|
||||
} else {
|
||||
p_gpio_port->intenclr = mask;
|
||||
}
|
||||
|
||||
return ARM_GPIO_ERR_NONE;
|
||||
}
|
||||
|
||||
enum arm_gpio_error_t arm_gpio_get_irq_status(struct arm_gpio_dev_t* dev,
|
||||
enum arm_gpio_access_t access,
|
||||
uint8_t pin_num,
|
||||
uint32_t* status)
|
||||
{
|
||||
struct arm_gpio_reg_map_t* p_gpio_port =
|
||||
(struct arm_gpio_reg_map_t*)dev->cfg->base;
|
||||
|
||||
if(dev->data->state != ARM_GPIO_INITIALIZED) {
|
||||
return ARM_GPIO_ERR_PORT_NOT_INIT;
|
||||
}
|
||||
|
||||
if(pin_num >= MAX_PIN_NBR) {
|
||||
return ARM_GPIO_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*status = p_gpio_port->intreg.intstatus;
|
||||
|
||||
if(access == ARM_GPIO_ACCESS_PIN) {
|
||||
*status = ((*status >> pin_num) & 1UL);
|
||||
} else {
|
||||
*status &= dev->data->port_mask;
|
||||
}
|
||||
|
||||
return ARM_GPIO_ERR_NONE;
|
||||
}
|
||||
|
||||
enum arm_gpio_error_t arm_gpio_clear_interrupt(struct arm_gpio_dev_t* dev,
|
||||
uint8_t pin_num)
|
||||
{
|
||||
struct arm_gpio_reg_map_t* p_gpio_port =
|
||||
(struct arm_gpio_reg_map_t*)dev->cfg->base;
|
||||
|
||||
if(dev->data->state != ARM_GPIO_INITIALIZED) {
|
||||
return ARM_GPIO_ERR_PORT_NOT_INIT;
|
||||
}
|
||||
|
||||
if(pin_num >= MAX_PIN_NBR) {
|
||||
return ARM_GPIO_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
p_gpio_port->intreg.intstatus = (1UL << pin_num);
|
||||
|
||||
return ARM_GPIO_ERR_NONE;
|
||||
}
|
||||
|
||||
void arm_gpio_set_port_mask(struct arm_gpio_dev_t* dev, uint32_t port_mask)
|
||||
{
|
||||
dev->data->port_mask = (port_mask & DEFAULT_PORT_MASK);
|
||||
}
|
||||
|
||||
uint32_t arm_gpio_get_port_mask(struct arm_gpio_dev_t* dev)
|
||||
{
|
||||
if(dev->data->state != ARM_GPIO_INITIALIZED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (dev->data->port_mask & DEFAULT_PORT_MASK);
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* Copyright (c) 2016-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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file arm_gpio_drv.h
|
||||
* \brief Generic driver for ARM GPIO.
|
||||
*/
|
||||
|
||||
#ifndef __ARM_GPIO_DRV_H__
|
||||
#define __ARM_GPIO_DRV_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DEFAULT_PORT_MASK 0xFFFF /* Default port mask */
|
||||
|
||||
/* GPIO flags */
|
||||
#define ARM_GPIO_PIN_DISABLE (1 << 0)
|
||||
#define ARM_GPIO_PIN_ENABLE (1 << 1)
|
||||
#define ARM_GPIO_OUTPUT (1 << 2)
|
||||
#define ARM_GPIO_INPUT (1 << 3)
|
||||
#define ARM_GPIO_IRQ (1 << 4)
|
||||
#define ARM_GPIO_IRQ_EDGE (1 << 5)
|
||||
#define ARM_GPIO_IRQ_LEVEL (1 << 6)
|
||||
#define ARM_GPIO_IRQ_ACTIVE_LOW (1 << 7)
|
||||
#define ARM_GPIO_IRQ_ACTIVE_HIGH (1 << 8)
|
||||
|
||||
/* ARM GPIO enumeration types */
|
||||
enum arm_gpio_access_t {
|
||||
ARM_GPIO_ACCESS_PIN = 0, /*!< Pin access to GPIO */
|
||||
ARM_GPIO_ACCESS_PORT /*!< Port access to GPIO */
|
||||
};
|
||||
|
||||
enum arm_gpio_irq_status_t {
|
||||
ARM_GPIO_IRQ_DISABLE = 0, /*!< Disable interruptions */
|
||||
ARM_GPIO_IRQ_ENABLE /*!< Enable interruptions */
|
||||
};
|
||||
|
||||
enum arm_gpio_error_t {
|
||||
ARM_GPIO_ERR_NONE = 0, /*!< No error */
|
||||
ARM_GPIO_ERR_INVALID_ARG, /*!< Error invalid input argument */
|
||||
ARM_GPIO_ERR_PORT_NOT_INIT /*!< Error GPIO port not initialized */
|
||||
};
|
||||
|
||||
/* ARM GPIO device configuration structure */
|
||||
struct arm_gpio_dev_cfg_t {
|
||||
const uint32_t base; /*!< GPIO base address */
|
||||
};
|
||||
|
||||
/* ARM GPIO device data structure */
|
||||
struct arm_gpio_dev_data_t {
|
||||
uint32_t state; /*!< Indicates if the gpio driver
|
||||
is initialized and enabled */
|
||||
uint32_t port_mask; /*!< Port mask used for any port access */
|
||||
};
|
||||
|
||||
/* ARM GPIO device structure */
|
||||
struct arm_gpio_dev_t {
|
||||
const struct arm_gpio_dev_cfg_t* const cfg; /*!< GPIO configuration */
|
||||
struct arm_gpio_dev_data_t* const data; /*!< GPIO data */
|
||||
};
|
||||
|
||||
/* ARM GPIO pin structure */
|
||||
struct arm_gpio_pin_t {
|
||||
uint32_t number; /*!< Pin number */
|
||||
enum arm_gpio_access_t access_type; /*!< Type of access in the
|
||||
GPIO block */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Initializes GPIO port.
|
||||
*
|
||||
* \param[in] dev GPIO port to initalize \ref arm_gpio_dev_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
*/
|
||||
void arm_gpio_init(struct arm_gpio_dev_t* dev);
|
||||
|
||||
/**
|
||||
* \brief Configurates pin or port.
|
||||
*
|
||||
* \param[in] dev GPIO port to initalize \ref arm_gpio_dev_t
|
||||
* \param[in] access Access type \ref arm_gpio_access_t
|
||||
* \param[in] pin_num Pin number.
|
||||
* \param[in] flags Pin flags \ref arm_gpio_flags_t
|
||||
*
|
||||
* \return Returns error code as specified in \ref arm_gpio_error_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
*/
|
||||
enum arm_gpio_error_t arm_gpio_config(struct arm_gpio_dev_t* dev,
|
||||
enum arm_gpio_access_t access,
|
||||
uint8_t pin_num,
|
||||
uint32_t flags);
|
||||
|
||||
/**
|
||||
* \brief Writes to output pin or port.
|
||||
*
|
||||
* \param[in] dev GPIO port to initalize \ref arm_gpio_dev_t
|
||||
* \param[in] access Access type \ref arm_gpio_access_t
|
||||
* \param[in] pin_num Pin number.
|
||||
* \param[in] value Value(s) to set.
|
||||
*
|
||||
* \return Returns error code as specified in \ref arm_gpio_error_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
* \note As ARM is a read-modify-write architecture, before writing a
|
||||
* value on a GPIO pin it is required to disable the
|
||||
* interrupts to prevent problems in a multitasking
|
||||
* environment.
|
||||
*/
|
||||
enum arm_gpio_error_t arm_gpio_write(struct arm_gpio_dev_t* dev,
|
||||
enum arm_gpio_access_t access,
|
||||
uint8_t pin_num,
|
||||
uint32_t value);
|
||||
|
||||
/**
|
||||
* \brief Reads the pin or port status.
|
||||
*
|
||||
* \param[in] dev GPIO port to initalize \ref arm_gpio_dev_t
|
||||
* \param[in] access Access type \ref arm_gpio_access_t
|
||||
* \param[in] pin_num Pin number.
|
||||
* \param[in] value Value of input pin(s).
|
||||
*
|
||||
* \return Returns bit value for Pin access or port value for port access.
|
||||
* Negative value for error.
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
*/
|
||||
int32_t arm_gpio_read(struct arm_gpio_dev_t* dev, enum arm_gpio_access_t access,
|
||||
uint8_t pin_num);
|
||||
|
||||
/**
|
||||
* \brief Sets interrupt status for the given pin or port.
|
||||
*
|
||||
* \param[in] dev GPIO port to initalize \ref arm_gpio_dev_t
|
||||
* \param[in] access Access type \ref arm_gpio_access_t
|
||||
* \param[in] pin_num Pin number.
|
||||
* \param[in] status Interrupt status \ref arm_gpio_irq_status
|
||||
*
|
||||
* \return Returns error code as specified in \ref arm_gpio_error_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
*/
|
||||
enum arm_gpio_error_t arm_gpio_set_interrupt(struct arm_gpio_dev_t* dev,
|
||||
enum arm_gpio_access_t access,
|
||||
uint8_t pin_num,
|
||||
enum arm_gpio_irq_status_t status);
|
||||
|
||||
/**
|
||||
* \brief Gets interrupt status for the given pin or port.
|
||||
*
|
||||
* \param[in] dev GPIO port to initalize \ref arm_gpio_dev_t
|
||||
* \param[in] access Access type \ref arm_gpio_access_t
|
||||
* \param[in] pin_num Pin number.
|
||||
* \param[out] status Interrupt status values. If the access is by pin, then
|
||||
* the status will be 0 or 1.
|
||||
*
|
||||
* \return Returns error code as specified in \ref arm_gpio_error_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
*/
|
||||
enum arm_gpio_error_t arm_gpio_get_irq_status(struct arm_gpio_dev_t* dev,
|
||||
enum arm_gpio_access_t access,
|
||||
uint8_t pin_num,
|
||||
uint32_t* status);
|
||||
|
||||
/**
|
||||
* \brief Clears gpio interrupt.
|
||||
*
|
||||
* \param[in] dev GPIO port to initalize \ref arm_gpio_dev_t
|
||||
* \param[in] pin_num Pin number.
|
||||
*
|
||||
* \return Returns error code as specified in \ref arm_gpio_error_t
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
*/
|
||||
enum arm_gpio_error_t arm_gpio_clear_interrupt(struct arm_gpio_dev_t* dev,
|
||||
uint8_t pin_num);
|
||||
|
||||
/**
|
||||
* \brief Sets gpio mask for port access.
|
||||
*
|
||||
* \param[in] dev GPIO port \ref arm_gpio_dev_t
|
||||
* \param[in] port_mask New port mask to set, only the 16 LSb are taken into
|
||||
* account
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
*/
|
||||
void arm_gpio_set_port_mask(struct arm_gpio_dev_t* dev, uint32_t port_mask);
|
||||
|
||||
/**
|
||||
* \brief Gets gpio mask for port access.
|
||||
*
|
||||
* \param[in] dev GPIO port \ref arm_gpio_dev_t
|
||||
*
|
||||
* \return Returns the current port mask
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
*/
|
||||
uint32_t arm_gpio_get_port_mask(struct arm_gpio_dev_t* dev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __ARM_GPIO_DRV_H__ */
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "arm_mps2_io_drv.h"
|
||||
|
||||
/* There is at most 8 LEDs and switches on MPS2 SCC and 2 on FPGA IO */
|
||||
#define MAX_PIN_NBR_SCC 8
|
||||
#define MAX_PIN_NBR_FPGAIO 2
|
||||
|
||||
/* Mask to 1 the first X bits */
|
||||
#define MASK(X) ((1 << (X)) - 1)
|
||||
|
||||
/* MPS2 IO register map structure */
|
||||
struct arm_mps2_io_reg_map_t {
|
||||
union {
|
||||
volatile uint32_t scc_leds; /* Offset: 0x000 (R/W) Controls the MCC
|
||||
* user LEDs
|
||||
* [31:8] : Reserved
|
||||
* [7:0] : MCC LEDs */
|
||||
volatile uint32_t fpgaio_leds; /* Offset: 0x000 (R/W) LED connections
|
||||
* [31:2] : Reserved
|
||||
* [1:0] : FPGAIO LEDs */
|
||||
} led_reg;
|
||||
volatile uint32_t reserved[1];
|
||||
union {
|
||||
volatile uint32_t scc_switches; /* Offset: 0x008 (R/ ) Denotes the
|
||||
* state of the MCC
|
||||
* user switches
|
||||
* [31:8] : Reserved
|
||||
* [7:0] : State of the MCC
|
||||
* switches */
|
||||
volatile uint32_t fpgaio_buttons;/* Offset: 0x008 (R/ ) Buttons
|
||||
* [31:2] : Reserved
|
||||
* [1:0] : Buttons */
|
||||
} button_reg;
|
||||
};
|
||||
|
||||
void arm_mps2_io_write_leds(struct arm_mps2_io_dev_t* dev,
|
||||
enum arm_mps2_io_access_t access,
|
||||
uint8_t pin_num,
|
||||
uint32_t value)
|
||||
{
|
||||
struct arm_mps2_io_reg_map_t* p_mps2_io_port =
|
||||
(struct arm_mps2_io_reg_map_t*)dev->cfg->base;
|
||||
/* Mask of involved bits */
|
||||
uint32_t write_mask = 0;
|
||||
|
||||
switch (dev->cfg->type) {
|
||||
case ARM_MPS2_IO_TYPE_SCC:
|
||||
if (pin_num >= MAX_PIN_NBR_SCC) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (access) {
|
||||
case ARM_MPS2_IO_ACCESS_PIN:
|
||||
write_mask = (1UL << pin_num);
|
||||
break;
|
||||
case ARM_MPS2_IO_ACCESS_PORT:
|
||||
write_mask = MASK(MAX_PIN_NBR_SCC);
|
||||
break;
|
||||
/*
|
||||
* default: explicitely not used to force to cover all enumeration
|
||||
* cases
|
||||
*/
|
||||
}
|
||||
|
||||
if (value) {
|
||||
p_mps2_io_port->led_reg.scc_leds |= write_mask;
|
||||
} else {
|
||||
p_mps2_io_port->led_reg.scc_leds &= ~write_mask;
|
||||
}
|
||||
|
||||
break;
|
||||
case ARM_MPS2_IO_TYPE_FPGAIO:
|
||||
if (pin_num >= MAX_PIN_NBR_FPGAIO) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (access) {
|
||||
case ARM_MPS2_IO_ACCESS_PIN:
|
||||
write_mask = (1UL << pin_num);
|
||||
break;
|
||||
case ARM_MPS2_IO_ACCESS_PORT:
|
||||
write_mask = MASK(MAX_PIN_NBR_FPGAIO);
|
||||
break;
|
||||
/*
|
||||
* default: explicitely not used to force to cover all enumeration
|
||||
* cases
|
||||
*/
|
||||
}
|
||||
|
||||
if (value) {
|
||||
p_mps2_io_port->led_reg.fpgaio_leds |= write_mask;
|
||||
} else {
|
||||
p_mps2_io_port->led_reg.fpgaio_leds &= ~write_mask;
|
||||
}
|
||||
|
||||
break;
|
||||
/* default: explicitely not used to force to cover all enumeration cases */
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t arm_mps2_io_read_buttons(struct arm_mps2_io_dev_t* dev,
|
||||
enum arm_mps2_io_access_t access,
|
||||
uint8_t pin_num)
|
||||
{
|
||||
struct arm_mps2_io_reg_map_t* p_mps2_io_port =
|
||||
(struct arm_mps2_io_reg_map_t*)dev->cfg->base;
|
||||
uint32_t value = 0;
|
||||
|
||||
switch (dev->cfg->type) {
|
||||
case ARM_MPS2_IO_TYPE_SCC:
|
||||
if (pin_num >= MAX_PIN_NBR_SCC) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Only read significant bits from this register */
|
||||
value = p_mps2_io_port->button_reg.scc_switches & MASK(MAX_PIN_NBR_SCC);
|
||||
|
||||
break;
|
||||
case ARM_MPS2_IO_TYPE_FPGAIO:
|
||||
if (pin_num >= MAX_PIN_NBR_FPGAIO) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Only read significant bits from this register */
|
||||
value = p_mps2_io_port->button_reg.fpgaio_buttons &
|
||||
MASK(MAX_PIN_NBR_FPGAIO);
|
||||
|
||||
break;
|
||||
/* default: explicitely not used to force to cover all enumeration cases */
|
||||
}
|
||||
|
||||
if (access == ARM_MPS2_IO_ACCESS_PIN) {
|
||||
value = ((value >> pin_num) & 1UL);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
uint32_t arm_mps2_io_read_leds(struct arm_mps2_io_dev_t* dev,
|
||||
enum arm_mps2_io_access_t access,
|
||||
uint8_t pin_num)
|
||||
{
|
||||
struct arm_mps2_io_reg_map_t* p_mps2_io_port =
|
||||
(struct arm_mps2_io_reg_map_t*)dev->cfg->base;
|
||||
uint32_t value = 0;
|
||||
|
||||
switch (dev->cfg->type) {
|
||||
case ARM_MPS2_IO_TYPE_SCC:
|
||||
if (pin_num >= MAX_PIN_NBR_SCC) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Only read significant bits from this register */
|
||||
value = p_mps2_io_port->led_reg.scc_leds & MASK(MAX_PIN_NBR_SCC);
|
||||
|
||||
break;
|
||||
case ARM_MPS2_IO_TYPE_FPGAIO:
|
||||
if (pin_num >= MAX_PIN_NBR_FPGAIO) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Only read significant bits from this register */
|
||||
value = p_mps2_io_port->led_reg.fpgaio_leds & MASK(MAX_PIN_NBR_FPGAIO);
|
||||
|
||||
break;
|
||||
/* default: explicitely not used to force to cover all enumeration cases */
|
||||
}
|
||||
|
||||
if (access == ARM_MPS2_IO_ACCESS_PIN) {
|
||||
value = ((value >> pin_num) & 1UL);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file arm_mps2_io_drv.h
|
||||
* \brief Generic driver for ARM MPS2 IO.
|
||||
*/
|
||||
|
||||
#ifndef __ARM_MPS2_IO_DRV_H__
|
||||
#define __ARM_MPS2_IO_DRV_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ARM MPS2 IO enumeration types */
|
||||
enum arm_mps2_io_access_t {
|
||||
ARM_MPS2_IO_ACCESS_PIN = 0, /*!< Pin access to MPS2 IO */
|
||||
ARM_MPS2_IO_ACCESS_PORT /*!< Port access to MPS2 IO */
|
||||
};
|
||||
|
||||
enum arm_mps2_io_type_t {
|
||||
ARM_MPS2_IO_TYPE_SCC = 0, /*!< Use the SCC IO device */
|
||||
ARM_MPS2_IO_TYPE_FPGAIO /*!< Use the FPGA IO device */
|
||||
};
|
||||
|
||||
/* ARM MPS2 IO device configuration structure */
|
||||
struct arm_mps2_io_dev_cfg_t {
|
||||
const uint32_t base; /*!< MPS2 IO base address */
|
||||
const enum arm_mps2_io_type_t type; /*!< SCC or FPGAIO */
|
||||
};
|
||||
|
||||
/* ARM MPS2 IO device structure */
|
||||
struct arm_mps2_io_dev_t {
|
||||
const struct arm_mps2_io_dev_cfg_t* const cfg; /*!< MPS2 IO configuration */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Writes to output LEDs.
|
||||
*
|
||||
* \param[in] dev MPS2 IO device where to write \ref arm_mps2_io_dev_t
|
||||
* \param[in] access Access type \ref arm_mps2_io_access_t
|
||||
* \param[in] pin_num Pin number.
|
||||
* \param[in] value Value(s) to set.
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
*/
|
||||
void arm_mps2_io_write_leds(struct arm_mps2_io_dev_t* dev,
|
||||
enum arm_mps2_io_access_t access,
|
||||
uint8_t pin_num,
|
||||
uint32_t value);
|
||||
|
||||
/**
|
||||
* \brief Reads the buttons status.
|
||||
*
|
||||
* \param[in] dev MPS2 IO device where to read \ref arm_mps2_io_dev_t
|
||||
* \param[in] access Access type \ref arm_mps2_io_access_t
|
||||
* \param[in] pin_num Pin number.
|
||||
*
|
||||
* \return Returns bit value for Pin access or port value for port access.
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
*/
|
||||
uint32_t arm_mps2_io_read_buttons(struct arm_mps2_io_dev_t* dev,
|
||||
enum arm_mps2_io_access_t access,
|
||||
uint8_t pin_num);
|
||||
|
||||
/**
|
||||
* \brief Reads the LED status.
|
||||
*
|
||||
* \param[in] dev MPS2 IO device where to read \ref arm_mps2_io_dev_t
|
||||
* \param[in] access Access type \ref arm_mps2_io_access_t
|
||||
* \param[in] pin_num Pin number.
|
||||
*
|
||||
* \return Returns bit value for Pin access or port value for port access.
|
||||
*
|
||||
* \note This function doesn't check if dev is NULL.
|
||||
*/
|
||||
uint32_t arm_mps2_io_read_leds(struct arm_mps2_io_dev_t* dev,
|
||||
enum arm_mps2_io_access_t access,
|
||||
uint8_t pin_num);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ARM_MPS2_IO_DRV_H__ */
|
|
@ -35,3 +35,65 @@ static struct timer_cmsdk_dev_data_t CMSDK_TIMER1_DEV_DATA = {
|
|||
struct timer_cmsdk_dev_t CMSDK_TIMER1_DEV = {&(CMSDK_TIMER1_DEV_CFG),
|
||||
&(CMSDK_TIMER1_DEV_DATA)};
|
||||
#endif
|
||||
|
||||
/* ARM GPIO driver structures */
|
||||
#ifdef ARM_GPIO0
|
||||
static const struct arm_gpio_dev_cfg_t ARM_GPIO0_DEV_CFG = {
|
||||
.base = CMSDK_GPIO0_BASE};
|
||||
static struct arm_gpio_dev_data_t ARM_GPIO0_DEV_DATA = {
|
||||
.state = 0,
|
||||
.port_mask = DEFAULT_PORT_MASK};
|
||||
struct arm_gpio_dev_t ARM_GPIO0_DEV = {&(ARM_GPIO0_DEV_CFG),
|
||||
&(ARM_GPIO0_DEV_DATA)};
|
||||
#endif /* ARM_GPIO0 */
|
||||
|
||||
#ifdef ARM_GPIO1
|
||||
static const struct arm_gpio_dev_cfg_t ARM_GPIO1_DEV_CFG = {
|
||||
.base = CMSDK_GPIO1_BASE};
|
||||
static struct arm_gpio_dev_data_t ARM_GPIO1_DEV_DATA = {
|
||||
.state = 0,
|
||||
.port_mask = DEFAULT_PORT_MASK};
|
||||
struct arm_gpio_dev_t ARM_GPIO1_DEV = {&(ARM_GPIO1_DEV_CFG),
|
||||
&(ARM_GPIO1_DEV_DATA)};
|
||||
#endif /* ARM_GPIO1 */
|
||||
|
||||
#ifdef ARM_GPIO2
|
||||
static const struct arm_gpio_dev_cfg_t ARM_GPIO2_DEV_CFG = {
|
||||
.base = CMSDK_GPIO2_BASE};
|
||||
static struct arm_gpio_dev_data_t ARM_GPIO2_DEV_DATA = {
|
||||
.state = 0,
|
||||
.port_mask = DEFAULT_PORT_MASK};
|
||||
struct arm_gpio_dev_t ARM_GPIO2_DEV = {&(ARM_GPIO2_DEV_CFG),
|
||||
&(ARM_GPIO2_DEV_DATA)};
|
||||
#endif /* ARM_GPIO2 */
|
||||
|
||||
#ifdef ARM_GPIO3
|
||||
static const struct arm_gpio_dev_cfg_t ARM_GPIO3_DEV_CFG = {
|
||||
.base = CMSDK_GPIO3_BASE};
|
||||
static struct arm_gpio_dev_data_t ARM_GPIO3_DEV_DATA = {
|
||||
.state = 0,
|
||||
.port_mask = DEFAULT_PORT_MASK};
|
||||
struct arm_gpio_dev_t ARM_GPIO3_DEV = {&(ARM_GPIO3_DEV_CFG),
|
||||
&(ARM_GPIO3_DEV_DATA)};
|
||||
#endif /* ARM_GPIO3 */
|
||||
|
||||
/* ARM MPS2 IO FPGAIO driver structures */
|
||||
#ifdef ARM_MPS2_IO_FPGAIO
|
||||
static const struct arm_mps2_io_dev_cfg_t ARM_MPS2_IO_FPGAIO_DEV_CFG = {
|
||||
.base = MPS2_FPGAIO_BASE,
|
||||
.type = ARM_MPS2_IO_TYPE_FPGAIO};
|
||||
struct arm_mps2_io_dev_t ARM_MPS2_IO_FPGAIO_DEV =
|
||||
{&(ARM_MPS2_IO_FPGAIO_DEV_CFG)};
|
||||
#endif /* ARM_MPS2_IO_FPGAIO */
|
||||
|
||||
/* ARM MPS2 IO SCC driver structures */
|
||||
#ifdef ARM_MPS2_IO_SCC
|
||||
static const struct arm_mps2_io_dev_cfg_t ARM_MPS2_IO_SCC_DEV_CFG = {
|
||||
/*
|
||||
* MPS2 IO SCC and FPGAIO registers have similar structure
|
||||
* with 4 byte offset addresses.
|
||||
*/
|
||||
.base = MPS2_SCC_BASE + 4,
|
||||
.type = ARM_MPS2_IO_TYPE_SCC};
|
||||
struct arm_mps2_io_dev_t ARM_MPS2_IO_SCC_DEV = {&(ARM_MPS2_IO_SCC_DEV_CFG)};
|
||||
#endif /* ARM_MPS2_IO_SCC */
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
/* ======= Includes generic driver headers ======= */
|
||||
#include "timer_cmsdk_drv.h"
|
||||
#include "arm_gpio_drv.h"
|
||||
#include "arm_mps2_io_drv.h"
|
||||
|
||||
/* ======= Defines peripheral configuration structures ======= */
|
||||
|
||||
|
@ -33,4 +35,28 @@ extern struct timer_cmsdk_dev_t CMSDK_TIMER0_DEV;
|
|||
extern struct timer_cmsdk_dev_t CMSDK_TIMER1_DEV;
|
||||
#endif
|
||||
|
||||
/* ARM GPIO driver structures */
|
||||
#ifdef ARM_GPIO0
|
||||
extern struct arm_gpio_dev_t ARM_GPIO0_DEV;
|
||||
#endif
|
||||
#ifdef ARM_GPIO1
|
||||
extern struct arm_gpio_dev_t ARM_GPIO1_DEV;
|
||||
#endif
|
||||
#ifdef ARM_GPIO2
|
||||
extern struct arm_gpio_dev_t ARM_GPIO2_DEV;
|
||||
#endif
|
||||
#ifdef ARM_GPIO3
|
||||
extern struct arm_gpio_dev_t ARM_GPIO3_DEV;
|
||||
#endif
|
||||
|
||||
/* ARM MPS2 IO FPGAIO driver structures */
|
||||
#ifdef ARM_MPS2_IO_FPGAIO
|
||||
extern struct arm_mps2_io_dev_t ARM_MPS2_IO_FPGAIO_DEV;
|
||||
#endif
|
||||
|
||||
/* ARM MPS2 IO SCC driver structures */
|
||||
#ifdef ARM_MPS2_IO_SCC
|
||||
extern struct arm_mps2_io_dev_t ARM_MPS2_IO_SCC_DEV;
|
||||
#endif
|
||||
|
||||
#endif /* __ARM_LTD_PLATFORM_DEVICES_H__ */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2017 ARM Limited
|
||||
* 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.
|
||||
|
@ -17,177 +17,236 @@
|
|||
#include <stddef.h>
|
||||
#include "gpio_api.h"
|
||||
#include "pinmap.h"
|
||||
#include "objects.h"
|
||||
#include "mbed_error.h"
|
||||
|
||||
#define GPIO_PIN_POS_MASK 0x0F /* pin % 16 */
|
||||
#define RESERVED_MISC_PIN 7
|
||||
enum io_type {
|
||||
GPIO_DEVICE,
|
||||
MPS2_IO_DEVICE,
|
||||
DEVICE_UNKNOWN
|
||||
};
|
||||
|
||||
/* \brief Gets the FPGA MISC (Miscellaneous control) bit position for the given
|
||||
* pin name
|
||||
*
|
||||
* FPGA MISC bit mapping:
|
||||
* [31:7] Reserved
|
||||
* [6] CLCD_BL_CTRL
|
||||
* [5] CLCD_RD
|
||||
* [4] CLCD_RS
|
||||
* [3] CLCD_RESET
|
||||
* [2] Reserved
|
||||
* [1] SPI_nSS
|
||||
* [0] CLCD_CS
|
||||
*
|
||||
* \param[in] pin MISC pin name
|
||||
*
|
||||
* \return FPGA MISC bit position
|
||||
*/
|
||||
static uint8_t get_fpga_misc_pin_pos(PinName pin)
|
||||
/* Tell if the gpio is from GPIO device or MPS2 IO */
|
||||
static enum io_type io_type(gpio_t *obj)
|
||||
{
|
||||
uint8_t pin_position = RESERVED_MISC_PIN;
|
||||
|
||||
if (pin == SPI_SCLK) {
|
||||
pin_position = 0;
|
||||
} else if (pin == CLCD_SSEL) {
|
||||
pin_position = 1;
|
||||
} else if (pin == CLCD_RESET) {
|
||||
pin_position = 3;
|
||||
} else if (pin == CLCD_RS) {
|
||||
pin_position = 4;
|
||||
} else if (pin == CLCD_RD) {
|
||||
pin_position = 5;
|
||||
} else if (pin == CLCD_BL_CTRL){
|
||||
pin_position = 6;
|
||||
if (obj->gpio_dev != NULL && obj->mps2_io_dev == NULL) {
|
||||
return GPIO_DEVICE;
|
||||
}
|
||||
|
||||
return pin_position;
|
||||
if (obj->gpio_dev == NULL && obj->mps2_io_dev != NULL) {
|
||||
return MPS2_IO_DEVICE;
|
||||
}
|
||||
return DEVICE_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Return the correct mask of the given PIN */
|
||||
uint32_t gpio_set(PinName pin)
|
||||
{
|
||||
uint8_t pin_position;
|
||||
pin_function(pin, (int)GPIO_FUNC);
|
||||
|
||||
if (pin >=EXP0 && pin <= EXP51) {
|
||||
/* Set pin functinality as GPIO. pin_function asserts if pin == NC */
|
||||
pin_function(pin, GPIO_FUNC);
|
||||
if (pin >= EXP0 && pin <= EXP51) {
|
||||
/* GPIO pins */
|
||||
return (1 << GPIO_PIN_NUMBER(pin));
|
||||
} else if (pin == USERLED1 || pin == USERLED2) {
|
||||
/* User LEDs */
|
||||
return (1 << (pin - USERLED1));
|
||||
} else if (pin == USERSW1 || pin == USERSW2) {
|
||||
/* User Push buttons */
|
||||
return (1 << (pin - USERSW1));
|
||||
} else if (pin >= LED1 && pin <= LED8) {
|
||||
/* MCC LEDs */
|
||||
return (1 << (pin - LED1));
|
||||
} else if (pin >= SW1 && pin <= SW8) {
|
||||
/* MCC Switches */
|
||||
return (1 << (pin - SW1));
|
||||
} else {
|
||||
/* Check if pin is a MISC pin */
|
||||
pin_position = get_fpga_misc_pin_pos(pin);
|
||||
if (pin_position != RESERVED_MISC_PIN) {
|
||||
return (1 << pin_position);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return pin mask */
|
||||
return (1 << (pin & 0xFF));
|
||||
}
|
||||
|
||||
void gpio_init(gpio_t *obj, PinName pin)
|
||||
{
|
||||
uint8_t pin_position;
|
||||
struct arm_gpio_dev_t *gpio_dev;
|
||||
|
||||
if (pin == NC) {
|
||||
return;
|
||||
}
|
||||
|
||||
obj->pin = pin;
|
||||
obj->pin_number = pin;
|
||||
|
||||
if (pin <= EXP15) {
|
||||
obj->reg_data = &CMSDK_GPIO0->DATAOUT;
|
||||
obj->reg_in = &CMSDK_GPIO0->DATA;
|
||||
obj->reg_dir = &CMSDK_GPIO0->OUTENABLESET;
|
||||
obj->reg_dirclr = &CMSDK_GPIO0->OUTENABLECLR;
|
||||
/* Set pin function as a GPIO */
|
||||
pin_function(pin, GPIO_FUNC);
|
||||
pin_position = pin;
|
||||
} else if (pin >= EXP16 && pin <= EXP31) {
|
||||
obj->reg_data = &CMSDK_GPIO1->DATAOUT;
|
||||
obj->reg_in = &CMSDK_GPIO1->DATA;
|
||||
obj->reg_dir = &CMSDK_GPIO1->OUTENABLESET;
|
||||
obj->reg_dirclr = &CMSDK_GPIO1->OUTENABLECLR;
|
||||
/* Set pin function as a GPIO */
|
||||
pin_function(pin, GPIO_FUNC);
|
||||
pin_position = (pin & GPIO_PIN_POS_MASK);
|
||||
} else if (pin >= EXP32 && pin <= EXP47) {
|
||||
obj->reg_data = &CMSDK_GPIO2->DATAOUT;
|
||||
obj->reg_in = &CMSDK_GPIO2->DATA;
|
||||
obj->reg_dir = &CMSDK_GPIO2->OUTENABLESET;
|
||||
obj->reg_dirclr = &CMSDK_GPIO2->OUTENABLECLR;
|
||||
/* Set pin function as a GPIO */
|
||||
pin_function(pin, GPIO_FUNC);
|
||||
pin_position = (pin & GPIO_PIN_POS_MASK);
|
||||
} else if (pin >= EXP48 && pin <= EXP51) {
|
||||
obj->reg_data = &CMSDK_GPIO3->DATAOUT;
|
||||
obj->reg_in = &CMSDK_GPIO3->DATA;
|
||||
obj->reg_dir = &CMSDK_GPIO3->OUTENABLESET;
|
||||
obj->reg_dirclr = &CMSDK_GPIO3->OUTENABLECLR;
|
||||
/* Set pin function as a GPIO */
|
||||
pin_function(pin, GPIO_FUNC);
|
||||
pin_position = (pin & GPIO_PIN_POS_MASK);
|
||||
} else if (pin == 100 || pin == 101) {
|
||||
/* User LEDs */
|
||||
pin_position = (pin - 100);
|
||||
obj->reg_data = &MPS2_FPGAIO->LED;
|
||||
obj->reg_in = &MPS2_FPGAIO->LED;
|
||||
obj->reg_dir = NULL;
|
||||
obj->reg_dirclr = NULL;
|
||||
} else if (pin == 110 || pin == 111) {
|
||||
/* User buttons */
|
||||
pin_position = (pin - 110);
|
||||
obj->reg_data = &MPS2_FPGAIO->BUTTON;
|
||||
obj->reg_in = &MPS2_FPGAIO->BUTTON;
|
||||
obj->reg_dir = NULL;
|
||||
obj->reg_dirclr = NULL;
|
||||
} else if (pin >= 200 && pin <= 207) {
|
||||
/* MCC LEDs */
|
||||
pin_position = (pin - 200);
|
||||
obj->reg_data = &MPS2_SCC->LEDS;
|
||||
obj->reg_in = &MPS2_SCC->LEDS;
|
||||
obj->reg_dir = NULL;
|
||||
obj->reg_dirclr = NULL;
|
||||
} else if (pin >= 210 && pin <= 217) {
|
||||
/* MCC switches */
|
||||
pin_position = (pin - 210);
|
||||
obj->reg_in = &MPS2_SCC->SWITCHES;
|
||||
obj->reg_data = NULL;
|
||||
obj->reg_dir = NULL;
|
||||
obj->reg_dirclr = NULL;
|
||||
} else {
|
||||
/* Check if pin is a MISC pin */
|
||||
pin_position = get_fpga_misc_pin_pos(pin);
|
||||
if (pin_position != RESERVED_MISC_PIN) {
|
||||
obj->reg_data = &MPS2_FPGAIO->MISC;
|
||||
} else {
|
||||
pin_position = 0;
|
||||
if (pin >= EXP0 && pin <= EXP51) {
|
||||
/* GPIO pins */
|
||||
switch (GPIO_DEV_NUMBER(pin)) {
|
||||
#ifdef ARM_GPIO0
|
||||
case GPIO0_NUMBER:
|
||||
gpio_dev = &ARM_GPIO0_DEV;
|
||||
break;
|
||||
#endif /* ARM_GPIO0 */
|
||||
#ifdef ARM_GPIO1
|
||||
case GPIO1_NUMBER:
|
||||
gpio_dev = &ARM_GPIO1_DEV;
|
||||
break;
|
||||
#endif /* ARM_GPIO1 */
|
||||
#ifdef ARM_GPIO2
|
||||
case GPIO2_NUMBER:
|
||||
gpio_dev = &ARM_GPIO2_DEV;
|
||||
break;
|
||||
#endif /* ARM_GPIO2 */
|
||||
#ifdef ARM_GPIO3
|
||||
case GPIO3_NUMBER:
|
||||
gpio_dev = &ARM_GPIO3_DEV;
|
||||
break;
|
||||
#endif /* ARM_GPIO3 */
|
||||
default:
|
||||
error("GPIO %d, associated with expansion pin %d, is disabled",
|
||||
GPIO_DEV_NUMBER(pin), pin);
|
||||
return;
|
||||
}
|
||||
|
||||
arm_gpio_init(gpio_dev);
|
||||
|
||||
obj->gpio_dev = gpio_dev;
|
||||
obj->mps2_io_dev = NULL;
|
||||
obj->pin_number = GPIO_PIN_NUMBER(pin);
|
||||
/* GPIO is input by default */
|
||||
obj->direction = PIN_INPUT;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set pin mask */
|
||||
obj->mask = (1 << pin_position);
|
||||
#ifdef ARM_MPS2_IO_FPGAIO
|
||||
if (pin == USERLED1 || pin == USERLED2) {
|
||||
/* User LEDs */
|
||||
obj->gpio_dev = NULL;
|
||||
obj->mps2_io_dev = &ARM_MPS2_IO_FPGAIO_DEV;
|
||||
obj->pin_number = pin - USERLED1;
|
||||
obj->direction = PIN_OUTPUT;
|
||||
return;
|
||||
} else if (pin == USERSW1 || pin == USERSW2) {
|
||||
/* User Push buttons */
|
||||
obj->gpio_dev = NULL;
|
||||
obj->mps2_io_dev = &ARM_MPS2_IO_FPGAIO_DEV;
|
||||
obj->pin_number = pin - USERSW1;
|
||||
obj->direction = PIN_INPUT;
|
||||
return;
|
||||
}
|
||||
#endif /* ARM_MPS2_IO_FPGAIO */
|
||||
|
||||
#ifdef ARM_MPS2_IO_SCC
|
||||
if (pin >= LED1 && pin <= LED8) {
|
||||
/* MCC LEDs */
|
||||
obj->gpio_dev = NULL;
|
||||
obj->mps2_io_dev = &ARM_MPS2_IO_SCC_DEV;
|
||||
obj->pin_number = pin - LED1;
|
||||
obj->direction = PIN_OUTPUT;
|
||||
return;
|
||||
} else if (pin >= SW1 && pin <= SW8) {
|
||||
/* MCC Switches */
|
||||
obj->gpio_dev = NULL;
|
||||
obj->mps2_io_dev = &ARM_MPS2_IO_SCC_DEV;
|
||||
obj->pin_number = pin - SW1;
|
||||
obj->direction = PIN_INPUT;
|
||||
return;
|
||||
}
|
||||
#endif /* ARM_MPS2_IO_SCC */
|
||||
|
||||
error("pin %d is not a GPIO", pin);
|
||||
}
|
||||
|
||||
void gpio_mode(gpio_t *obj, PinMode mode)
|
||||
{
|
||||
pin_mode(obj->pin, mode);
|
||||
/* PinMode is not supported */
|
||||
}
|
||||
|
||||
void gpio_dir(gpio_t *obj, PinDirection direction)
|
||||
{
|
||||
if (obj->pin >= EXP0 && obj->pin <= EXP51) {
|
||||
uint32_t flags = ARM_GPIO_PIN_ENABLE;
|
||||
|
||||
obj->direction = direction;
|
||||
|
||||
switch (io_type(obj)) {
|
||||
case GPIO_DEVICE:
|
||||
switch (direction) {
|
||||
case PIN_INPUT :
|
||||
*obj->reg_dirclr = obj->mask;
|
||||
break;
|
||||
case PIN_OUTPUT:
|
||||
*obj->reg_dir |= obj->mask;
|
||||
break;
|
||||
case PIN_INPUT:
|
||||
flags |= ARM_GPIO_INPUT;
|
||||
break;
|
||||
case PIN_OUTPUT:
|
||||
flags |= ARM_GPIO_OUTPUT;
|
||||
break;
|
||||
/* default: not added to force to cover all enumeration cases */
|
||||
}
|
||||
|
||||
(void)arm_gpio_config(obj->gpio_dev, ARM_GPIO_ACCESS_PIN,
|
||||
obj->pin_number, flags);
|
||||
return;
|
||||
case MPS2_IO_DEVICE:
|
||||
/* Do nothing as MPS2 IO direction can not be changed */
|
||||
return;
|
||||
case DEVICE_UNKNOWN:
|
||||
break;
|
||||
/* default: The default is not defined intentionally to force the
|
||||
* compiler to check that all the enumeration values are
|
||||
* covered in the switch.*/
|
||||
}
|
||||
|
||||
error("can not change the direction of pin");
|
||||
}
|
||||
|
||||
int gpio_is_connected(const gpio_t *obj)
|
||||
{
|
||||
if (obj->pin != (PinName)NC) {
|
||||
if (obj->pin_number == (uint32_t)NC) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gpio_write(gpio_t *obj, int value)
|
||||
{
|
||||
switch (io_type(obj)) {
|
||||
case GPIO_DEVICE:
|
||||
(void)arm_gpio_write(obj->gpio_dev, ARM_GPIO_ACCESS_PIN,
|
||||
obj->pin_number, (uint32_t)value);
|
||||
return;
|
||||
case MPS2_IO_DEVICE:
|
||||
if (obj->direction == PIN_INPUT) {
|
||||
/*
|
||||
* If the given gpio is in fact a button, ignore the call to not
|
||||
* write to the corresponding LED instead.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
arm_mps2_io_write_leds(obj->mps2_io_dev, ARM_MPS2_IO_ACCESS_PIN,
|
||||
obj->pin_number, (uint32_t)value);
|
||||
return;
|
||||
case DEVICE_UNKNOWN:
|
||||
break;
|
||||
/* default: The default is not defined intentionally to force the
|
||||
* compiler to check that all the enumeration values are
|
||||
* covered in the switch.*/
|
||||
}
|
||||
|
||||
error("can not write pin");
|
||||
}
|
||||
|
||||
int gpio_read(gpio_t *obj)
|
||||
{
|
||||
switch (io_type(obj)) {
|
||||
case GPIO_DEVICE:
|
||||
return (int)arm_gpio_read(obj->gpio_dev, ARM_GPIO_ACCESS_PIN,
|
||||
obj->pin_number);
|
||||
case MPS2_IO_DEVICE:
|
||||
switch (obj->direction) {
|
||||
case PIN_INPUT:
|
||||
|
||||
return (int)arm_mps2_io_read_buttons(obj->mps2_io_dev,
|
||||
ARM_MPS2_IO_ACCESS_PIN,
|
||||
obj->pin_number);
|
||||
case PIN_OUTPUT:
|
||||
return (int)arm_mps2_io_read_leds(obj->mps2_io_dev,
|
||||
ARM_MPS2_IO_ACCESS_PIN,
|
||||
obj->pin_number);
|
||||
}
|
||||
|
||||
case DEVICE_UNKNOWN:
|
||||
break;
|
||||
/* default: The default is not defined intentionally to force the
|
||||
* compiler to check that all the enumeration values are
|
||||
* covered in the switch.*/
|
||||
}
|
||||
|
||||
error("can not read pin");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2017 ARM Limited
|
||||
* 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.
|
||||
|
@ -14,425 +14,192 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include "cmsis.h"
|
||||
#include "objects.h"
|
||||
#include "gpio_irq_api.h"
|
||||
#include "mbed_error.h"
|
||||
|
||||
#define CHANNEL_NUM 32
|
||||
#define CMSDK_GPIO_0 CMSDK_GPIO0
|
||||
#define CMSDK_GPIO_1 CMSDK_GPIO1
|
||||
#define PININT_IRQ 0
|
||||
#define ERROR_BIT_NUMBER 0xFF
|
||||
|
||||
static uint32_t channel_ids[CHANNEL_NUM] = {0};
|
||||
static gpio_irq_handler irq_handler;
|
||||
struct gpio_irq_handler_t {
|
||||
gpio_irq_handler handler;
|
||||
gpio_irq_event event;
|
||||
uint32_t id;
|
||||
};
|
||||
|
||||
static inline void handle_interrupt_in(uint32_t channel)
|
||||
/* Handlers registered */
|
||||
static struct gpio_irq_handler_t gpio_irq[PINS_NUMBER];
|
||||
|
||||
/*
|
||||
* Return the bit number of the lowest significant bit set to 1 or
|
||||
* ERROR_BIT_NUMBER if there is no bit set.
|
||||
*/
|
||||
static uint8_t find_first_set_bit(uint32_t word)
|
||||
{
|
||||
uint32_t ch_bit = (1 << channel);
|
||||
// Return immediately if:
|
||||
// * The interrupt was already served
|
||||
// * There is no user handler
|
||||
// * It is a level interrupt, not an edge interrupt
|
||||
if (ch_bit < 16) {
|
||||
if (((CMSDK_GPIO_0->INTSTATUS) == 0)
|
||||
|| (channel_ids[channel] == 0)
|
||||
|| ((CMSDK_GPIO_0->INTTYPESET) == 0) ) {
|
||||
return;
|
||||
}
|
||||
uint8_t bit_number = 0;
|
||||
|
||||
if ((CMSDK_GPIO_0->INTTYPESET & ch_bit) && (CMSDK_GPIO_0->INTPOLSET & ch_bit)) {
|
||||
irq_handler(channel_ids[channel], IRQ_RISE);
|
||||
CMSDK_GPIO_0->INTPOLSET = ch_bit;
|
||||
}
|
||||
if ((CMSDK_GPIO_0->INTTYPESET & ch_bit) && ~(CMSDK_GPIO_0->INTPOLSET & ch_bit)) {
|
||||
irq_handler(channel_ids[channel], IRQ_FALL);
|
||||
}
|
||||
|
||||
CMSDK_GPIO_0->INTCLEAR = ch_bit;
|
||||
} else {
|
||||
if (((CMSDK_GPIO_1->INTSTATUS) == 0)
|
||||
|| (channel_ids[channel] == 0)
|
||||
|| ((CMSDK_GPIO_1->INTTYPESET) == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((CMSDK_GPIO_1->INTTYPESET & ch_bit) && (CMSDK_GPIO_1->INTPOLSET & ch_bit)) {
|
||||
irq_handler(channel_ids[channel], IRQ_RISE);
|
||||
CMSDK_GPIO_1->INTPOLSET = ch_bit;
|
||||
}
|
||||
if ((CMSDK_GPIO_1->INTTYPESET & ch_bit) && ~(CMSDK_GPIO_1->INTPOLSET & ch_bit)) {
|
||||
irq_handler(channel_ids[channel], IRQ_FALL);
|
||||
}
|
||||
CMSDK_GPIO_1->INTCLEAR = ch_bit;
|
||||
if (word == 0) {
|
||||
return ERROR_BIT_NUMBER;
|
||||
}
|
||||
|
||||
while (((word >> bit_number++) & 1UL) == 0);
|
||||
|
||||
return (bit_number - 1);
|
||||
}
|
||||
|
||||
void gpio0_irq0(void)
|
||||
static void handler(struct arm_gpio_dev_t* dev, uint32_t gpio_number,
|
||||
uint32_t exp_pin_base)
|
||||
{
|
||||
handle_interrupt_in(0);
|
||||
uint32_t irq_status = 0;
|
||||
/* Pin that triggered the IRQ in this GPIO */
|
||||
uint8_t pin_number;
|
||||
/* Pin number in the expension port */
|
||||
uint8_t exp_pin_number;
|
||||
|
||||
(void)arm_gpio_get_irq_status(dev, ARM_GPIO_ACCESS_PORT, ARG_NOT_USED,
|
||||
&irq_status);
|
||||
|
||||
pin_number = find_first_set_bit(irq_status);
|
||||
if (pin_number == ERROR_BIT_NUMBER) {
|
||||
/* There was no IRQ */
|
||||
return;
|
||||
}
|
||||
|
||||
(void)arm_gpio_clear_interrupt(dev, pin_number);
|
||||
|
||||
exp_pin_number = exp_pin_base + pin_number;
|
||||
|
||||
gpio_irq[exp_pin_number].handler(gpio_irq[exp_pin_number].id,
|
||||
gpio_irq[exp_pin_number].event);
|
||||
}
|
||||
|
||||
void gpio0_irq1(void)
|
||||
#ifdef ARM_GPIO0
|
||||
void PORT0_IRQHandler(void)
|
||||
{
|
||||
handle_interrupt_in(1);
|
||||
handler(&ARM_GPIO0_DEV, GPIO0_NUMBER, EXP_PIN_BASE0);
|
||||
}
|
||||
#endif /* ARM_GPIO0 */
|
||||
|
||||
void gpio0_irq2(void)
|
||||
#ifdef ARM_GPIO1
|
||||
void PORT1_ALL_IRQHandler(void)
|
||||
{
|
||||
handle_interrupt_in(2);
|
||||
handler(&ARM_GPIO1_DEV, GPIO1_NUMBER, EXP_PIN_BASE1);
|
||||
}
|
||||
#endif /* ARM_GPIO1 */
|
||||
|
||||
void gpio0_irq3(void)
|
||||
#ifdef ARM_GPIO2
|
||||
void PORT2_ALL_IRQHandler(void)
|
||||
{
|
||||
handle_interrupt_in(3);
|
||||
handler(&ARM_GPIO2_DEV, GPIO2_NUMBER, EXP_PIN_BASE2);
|
||||
}
|
||||
#endif /* ARM_GPIO2 */
|
||||
|
||||
void gpio0_irq4(void)
|
||||
#ifdef ARM_GPIO3
|
||||
void PORT3_ALL_IRQHandler(void)
|
||||
{
|
||||
handle_interrupt_in(4);
|
||||
handler(&ARM_GPIO3_DEV, GPIO3_NUMBER, EXP_PIN_BASE3);
|
||||
}
|
||||
#endif /* ARM_GPIO3 */
|
||||
|
||||
void gpio0_irq5(void)
|
||||
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler,
|
||||
uint32_t id)
|
||||
{
|
||||
handle_interrupt_in(5);
|
||||
}
|
||||
struct arm_gpio_dev_t *gpio_dev;
|
||||
|
||||
void gpio0_irq6(void)
|
||||
{
|
||||
handle_interrupt_in(6);
|
||||
}
|
||||
if (pin >= EXP0 && pin <= EXP51) {
|
||||
/* GPIO pins */
|
||||
switch (GPIO_DEV_NUMBER(pin)) {
|
||||
#ifdef ARM_GPIO0
|
||||
case 0:
|
||||
gpio_dev = &ARM_GPIO0_DEV;
|
||||
obj->irq_number = PORT0_ALL_IRQn;
|
||||
break;
|
||||
#endif /* ARM_GPIO0 */
|
||||
#ifdef ARM_GPIO1
|
||||
case 1:
|
||||
gpio_dev = &ARM_GPIO1_DEV;
|
||||
obj->irq_number = PORT1_ALL_IRQn;
|
||||
break;
|
||||
#endif /* ARM_GPIO1 */
|
||||
#ifdef ARM_GPIO2
|
||||
case 2:
|
||||
gpio_dev = &ARM_GPIO2_DEV;
|
||||
obj->irq_number = PORT2_ALL_IRQn;
|
||||
break;
|
||||
#endif /* ARM_GPIO2 */
|
||||
#ifdef ARM_GPIO3
|
||||
case 3:
|
||||
gpio_dev = &ARM_GPIO3_DEV;
|
||||
obj->irq_number = PORT3_ALL_IRQn;
|
||||
break;
|
||||
#endif /* ARM_GPIO3 */
|
||||
default:
|
||||
error("GPIO %d is not enabled", GPIO_DEV_NUMBER(pin));
|
||||
return -1;
|
||||
}
|
||||
|
||||
void gpio0_irq7(void)
|
||||
{
|
||||
handle_interrupt_in(7);
|
||||
}
|
||||
obj->gpio_dev = gpio_dev;
|
||||
obj->pin_number = GPIO_PIN_NUMBER(pin);
|
||||
obj->exp_pin_number = pin;
|
||||
|
||||
void gpio0_irq8(void)
|
||||
{
|
||||
handle_interrupt_in(8);
|
||||
}
|
||||
arm_gpio_init(gpio_dev);
|
||||
|
||||
void gpio0_irq9(void)
|
||||
{
|
||||
handle_interrupt_in(9);
|
||||
}
|
||||
/* Save the handler and id into the global structure */
|
||||
gpio_irq[pin].handler = handler;
|
||||
gpio_irq[pin].id = id;
|
||||
|
||||
void gpio0_irq10(void)
|
||||
{
|
||||
handle_interrupt_in(10);
|
||||
}
|
||||
|
||||
void gpio0_irq11(void)
|
||||
{
|
||||
handle_interrupt_in(11);
|
||||
}
|
||||
|
||||
void gpio0_irq12(void)
|
||||
{
|
||||
handle_interrupt_in(12);
|
||||
}
|
||||
|
||||
void gpio0_irq13(void)
|
||||
{
|
||||
handle_interrupt_in(13);
|
||||
}
|
||||
|
||||
void gpio0_irq14(void)
|
||||
{
|
||||
handle_interrupt_in(14);
|
||||
}
|
||||
|
||||
void gpio0_irq15(void)
|
||||
{
|
||||
handle_interrupt_in(15);
|
||||
}
|
||||
|
||||
void gpio1_irq0(void)
|
||||
{
|
||||
handle_interrupt_in(16);
|
||||
}
|
||||
|
||||
void gpio1_irq1(void)
|
||||
{
|
||||
handle_interrupt_in(17);
|
||||
}
|
||||
void gpio1_irq2(void)
|
||||
{
|
||||
handle_interrupt_in(18);
|
||||
}
|
||||
|
||||
void gpio1_irq3(void)
|
||||
{
|
||||
handle_interrupt_in(19);
|
||||
}
|
||||
|
||||
void gpio1_irq4(void)
|
||||
{
|
||||
handle_interrupt_in(20);
|
||||
}
|
||||
|
||||
void gpio1_irq5(void)
|
||||
{
|
||||
handle_interrupt_in(21);
|
||||
}
|
||||
|
||||
void gpio1_irq6(void)
|
||||
{
|
||||
handle_interrupt_in(22);
|
||||
}
|
||||
|
||||
void gpio1_irq7(void)
|
||||
{
|
||||
handle_interrupt_in(23);
|
||||
}
|
||||
|
||||
void gpio1_irq8(void)
|
||||
{
|
||||
handle_interrupt_in(24);
|
||||
}
|
||||
|
||||
void gpio1_irq9(void)
|
||||
{
|
||||
handle_interrupt_in(25);
|
||||
}
|
||||
|
||||
void gpio1_irq10(void)
|
||||
{
|
||||
handle_interrupt_in(26);
|
||||
}
|
||||
|
||||
void gpio1_irq11(void)
|
||||
{
|
||||
handle_interrupt_in(27);
|
||||
}
|
||||
|
||||
void gpio1_irq12(void)
|
||||
{
|
||||
handle_interrupt_in(28);
|
||||
}
|
||||
|
||||
void gpio1_irq13(void)
|
||||
{
|
||||
handle_interrupt_in(29);
|
||||
}
|
||||
|
||||
void gpio1_irq14(void)
|
||||
{
|
||||
handle_interrupt_in(30);
|
||||
}
|
||||
|
||||
void gpio1_irq15(void)
|
||||
{
|
||||
handle_interrupt_in(31);
|
||||
}
|
||||
|
||||
int gpio_irq_init(gpio_irq_t *obj, PinName pin,
|
||||
gpio_irq_handler handler, uint32_t id)
|
||||
{
|
||||
int found_free_channel = 0;
|
||||
int i = 0;
|
||||
|
||||
if (pin == NC) {
|
||||
return 0;
|
||||
} else {
|
||||
/* The pin is not concerned with GPIO IRQ */
|
||||
error("Pin %d is not a GPIO", pin);
|
||||
return -1;
|
||||
}
|
||||
|
||||
irq_handler = handler;
|
||||
|
||||
for (i=0; i<CHANNEL_NUM; i++) {
|
||||
if (channel_ids[i] == 0) {
|
||||
channel_ids[i] = id;
|
||||
obj->ch = i;
|
||||
found_free_channel = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_free_channel) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* To select a pin for any of the eight pin interrupts, write the pin number
|
||||
* as 0 to 23 for pins PIO0_0 to PIO0_23 and 24 to 55.
|
||||
* @see: mbed_capi/PinNames.h
|
||||
*/
|
||||
if (pin <16) {
|
||||
CMSDK_GPIO_0->INTENSET |= (0x1 << pin);
|
||||
}
|
||||
|
||||
if (pin >= 16) {
|
||||
CMSDK_GPIO_1->INTENSET |= (0x1 << pin);
|
||||
}
|
||||
|
||||
void (*channels_irq)(void) = NULL;
|
||||
switch (obj->ch) {
|
||||
case 0:
|
||||
channels_irq = &gpio0_irq0;
|
||||
break;
|
||||
case 1:
|
||||
channels_irq = &gpio0_irq1;
|
||||
break;
|
||||
case 2:
|
||||
channels_irq = &gpio0_irq2;
|
||||
break;
|
||||
case 3:
|
||||
channels_irq = &gpio0_irq3;
|
||||
break;
|
||||
case 4:
|
||||
channels_irq = &gpio0_irq4;
|
||||
break;
|
||||
case 5:
|
||||
channels_irq = &gpio0_irq5;
|
||||
break;
|
||||
case 6:
|
||||
channels_irq = &gpio0_irq6;
|
||||
break;
|
||||
case 7:
|
||||
channels_irq = &gpio0_irq7;
|
||||
break;
|
||||
case 8:
|
||||
channels_irq = &gpio0_irq8;
|
||||
break;
|
||||
case 9:
|
||||
channels_irq = &gpio0_irq9;
|
||||
break;
|
||||
case 10:
|
||||
channels_irq = &gpio0_irq10;
|
||||
break;
|
||||
case 11:
|
||||
channels_irq = &gpio0_irq11;
|
||||
break;
|
||||
case 12:
|
||||
channels_irq = &gpio0_irq12;
|
||||
break;
|
||||
case 13:
|
||||
channels_irq = &gpio0_irq13;
|
||||
break;
|
||||
case 14:
|
||||
channels_irq = &gpio0_irq14;
|
||||
break;
|
||||
case 15:
|
||||
channels_irq = &gpio0_irq15;
|
||||
break;
|
||||
case 16:
|
||||
channels_irq = &gpio1_irq0;
|
||||
break;
|
||||
case 17:
|
||||
channels_irq = &gpio1_irq1;
|
||||
break;
|
||||
case 18:
|
||||
channels_irq = &gpio1_irq2;
|
||||
break;
|
||||
case 19:
|
||||
channels_irq = &gpio1_irq3;
|
||||
break;
|
||||
case 20:
|
||||
channels_irq = &gpio1_irq4;
|
||||
break;
|
||||
case 21:
|
||||
channels_irq = &gpio1_irq5;
|
||||
break;
|
||||
case 22:
|
||||
channels_irq = &gpio1_irq6;
|
||||
break;
|
||||
case 23:
|
||||
channels_irq = &gpio1_irq7;
|
||||
break;
|
||||
case 24:
|
||||
channels_irq = &gpio1_irq8;
|
||||
break;
|
||||
case 25:
|
||||
channels_irq = &gpio1_irq9;
|
||||
break;
|
||||
case 26:
|
||||
channels_irq = &gpio1_irq10;
|
||||
break;
|
||||
case 27:
|
||||
channels_irq = &gpio1_irq11;
|
||||
break;
|
||||
case 28:
|
||||
channels_irq = &gpio1_irq12;
|
||||
break;
|
||||
case 29:
|
||||
channels_irq = &gpio1_irq13;
|
||||
break;
|
||||
case 30:
|
||||
channels_irq = &gpio1_irq14;
|
||||
break;
|
||||
case 31:
|
||||
channels_irq = &gpio1_irq15;
|
||||
break;
|
||||
}
|
||||
|
||||
NVIC_SetVector((IRQn_Type)(PININT_IRQ + obj->ch), (uint32_t)channels_irq);
|
||||
NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ + obj->ch));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gpio_irq_free(gpio_irq_t *obj)
|
||||
{
|
||||
channel_ids[obj->ch] = 0;
|
||||
/* Not implemented because the device can not be uninitialized. */
|
||||
}
|
||||
|
||||
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
|
||||
{
|
||||
unsigned int ch_bit = (1 << obj->ch);
|
||||
/* Interrupt is set on an input pin on rising or falling edge */
|
||||
uint32_t flags = ARM_GPIO_PIN_ENABLE | ARM_GPIO_INPUT | ARM_GPIO_IRQ |
|
||||
ARM_GPIO_IRQ_EDGE;
|
||||
|
||||
if (obj->ch <16) {
|
||||
/* Clear interrupt */
|
||||
if (!(CMSDK_GPIO_0->INTTYPESET & ch_bit)) {
|
||||
CMSDK_GPIO_0->INTCLEAR = ch_bit;
|
||||
}
|
||||
CMSDK_GPIO_0->INTTYPESET &= ch_bit;
|
||||
switch (event) {
|
||||
case IRQ_RISE:
|
||||
flags |= ARM_GPIO_IRQ_ACTIVE_HIGH;
|
||||
break;
|
||||
case IRQ_FALL:
|
||||
flags |= ARM_GPIO_IRQ_ACTIVE_LOW;
|
||||
break;
|
||||
case IRQ_NONE:
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set interrupt */
|
||||
if (event == IRQ_RISE) {
|
||||
CMSDK_GPIO_0->INTPOLSET |= ch_bit;
|
||||
if (enable) {
|
||||
CMSDK_GPIO_0->INTENSET |= ch_bit;
|
||||
} else {
|
||||
CMSDK_GPIO_0->INTENCLR |= ch_bit;
|
||||
}
|
||||
} else {
|
||||
CMSDK_GPIO_0->INTPOLCLR |= ch_bit;
|
||||
if (enable) {
|
||||
CMSDK_GPIO_0->INTENSET |= ch_bit;
|
||||
} else {
|
||||
CMSDK_GPIO_0->INTENCLR |= ch_bit;
|
||||
}
|
||||
}
|
||||
(void)arm_gpio_config(obj->gpio_dev, ARM_GPIO_ACCESS_PIN, obj->pin_number,
|
||||
flags);
|
||||
|
||||
/* Record the event type of this pin */
|
||||
gpio_irq[obj->exp_pin_number].event = event;
|
||||
|
||||
NVIC_EnableIRQ(obj->irq_number);
|
||||
|
||||
if (enable) {
|
||||
gpio_irq_enable(obj);
|
||||
} else {
|
||||
/* Clear interrupt */
|
||||
if (!(CMSDK_GPIO_1->INTTYPESET & ch_bit)) {
|
||||
CMSDK_GPIO_1->INTCLEAR = ch_bit;
|
||||
}
|
||||
CMSDK_GPIO_1->INTTYPESET &= ch_bit;
|
||||
|
||||
/* Set interrupt */
|
||||
if (event == IRQ_RISE) {
|
||||
CMSDK_GPIO_1->INTPOLSET |= ch_bit;
|
||||
if (enable) {
|
||||
CMSDK_GPIO_1->INTENSET |= ch_bit;
|
||||
} else {
|
||||
CMSDK_GPIO_1->INTENCLR |= ch_bit;
|
||||
}
|
||||
} else {
|
||||
CMSDK_GPIO_1->INTPOLCLR |= ch_bit;
|
||||
if (enable) {
|
||||
CMSDK_GPIO_1->INTENSET |= ch_bit;
|
||||
} else {
|
||||
CMSDK_GPIO_1->INTENCLR |= ch_bit;
|
||||
}
|
||||
}
|
||||
gpio_irq_disable(obj);
|
||||
}
|
||||
}
|
||||
|
||||
void gpio_irq_enable(gpio_irq_t *obj)
|
||||
{
|
||||
NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ + obj->ch));
|
||||
(void)arm_gpio_set_interrupt(obj->gpio_dev, ARM_GPIO_ACCESS_PIN,
|
||||
obj->pin_number, ARM_GPIO_IRQ_ENABLE);
|
||||
}
|
||||
|
||||
void gpio_irq_disable(gpio_irq_t *obj)
|
||||
{
|
||||
NVIC_DisableIRQ((IRQn_Type)(PININT_IRQ + obj->ch));
|
||||
(void)arm_gpio_set_interrupt(obj->gpio_dev, ARM_GPIO_ACCESS_PIN,
|
||||
obj->pin_number, ARM_GPIO_IRQ_DISABLE);
|
||||
}
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2017 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_GPIO_OBJECT_H
|
||||
#define MBED_GPIO_OBJECT_H
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "PortNames.h"
|
||||
#include "PeripheralNames.h"
|
||||
#include "PinNames.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
PinName pin;
|
||||
uint32_t mask;
|
||||
uint32_t pin_number;
|
||||
__IO uint32_t *reg_dir;
|
||||
__IO uint32_t *reg_dirclr;
|
||||
__IO uint32_t *reg_data;
|
||||
__I uint32_t *reg_in;
|
||||
} gpio_t;
|
||||
|
||||
static inline void gpio_write(gpio_t *obj, int value)
|
||||
{
|
||||
if (value) {
|
||||
*obj->reg_data |= (obj->mask);
|
||||
} else {
|
||||
*obj->reg_data &= ~(obj->mask);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int gpio_read(gpio_t *obj)
|
||||
{
|
||||
return ((*obj->reg_in & obj->mask) ? 1 : 0);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,56 @@
|
|||
/* 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_GPIO_OBJECTS_H__
|
||||
#define __MBED_GPIO_OBJECTS_H__
|
||||
|
||||
/*
|
||||
* GPIO device number, there are 16 pins per GPIO
|
||||
* equivalent: pin / 16
|
||||
*/
|
||||
#define GPIO_DEV_NUMBER(pin) ((pin) >> 4)
|
||||
/*
|
||||
* Pin number of this pin inside its GPIO
|
||||
* equivalent: pin % 16
|
||||
*/
|
||||
#define GPIO_PIN_NUMBER(pin) ((pin) & 0xF)
|
||||
|
||||
/* Number of the GPIO device */
|
||||
#define GPIO0_NUMBER 0
|
||||
#define GPIO1_NUMBER 1
|
||||
#define GPIO2_NUMBER 2
|
||||
#define GPIO3_NUMBER 3
|
||||
|
||||
/* Base EXP pin number for the corresponding GPIO */
|
||||
#define EXP_PIN_BASE0 EXP0
|
||||
#define EXP_PIN_BASE1 EXP16
|
||||
#define EXP_PIN_BASE2 EXP32
|
||||
#define EXP_PIN_BASE3 EXP48
|
||||
|
||||
#define GPIO_DEVICES 4
|
||||
#define PINS_PER_GPIO 16
|
||||
/* Pins 4 to 15 of GPIO3 are not used */
|
||||
#define PINS_NOT_USED 12
|
||||
#define PINS_NUMBER (GPIO_DEVICES * PINS_PER_GPIO - PINS_NOT_USED)
|
||||
|
||||
/* GPIO3 port only uses first 4 pins */
|
||||
#define GPIO3_PIN_NUMBER 4
|
||||
|
||||
/* When doing a port access, the pin number argument is useless */
|
||||
#define ARG_NOT_USED 0
|
||||
|
||||
#endif /* __MBED_GPIO_OBJECTS_H__ */
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2017 ARM Limited
|
||||
* 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.
|
||||
|
@ -13,29 +13,37 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef MBED_OBJECTS_H
|
||||
#define MBED_OBJECTS_H
|
||||
#ifndef __MBED_OBJECTS_H__
|
||||
#define __MBED_OBJECTS_H__
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "PortNames.h"
|
||||
#include "PeripheralNames.h"
|
||||
#include "PinNames.h"
|
||||
#include "platform_devices.h"
|
||||
#include "gpio_objects.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct gpio_s {
|
||||
struct arm_gpio_dev_t *gpio_dev;
|
||||
struct arm_mps2_io_dev_t *mps2_io_dev;
|
||||
uint32_t pin_number;
|
||||
PinDirection direction;
|
||||
} gpio_t;
|
||||
|
||||
struct gpio_irq_s {
|
||||
uint32_t ch;
|
||||
struct arm_gpio_dev_t *gpio_dev;
|
||||
uint32_t pin_number; /* Pin number inside the GPIO */
|
||||
uint32_t exp_pin_number; /* Pin number on the expension port */
|
||||
IRQn_Type irq_number; /* IRQ number of the GPIO interrupt of
|
||||
this pin */
|
||||
};
|
||||
|
||||
struct port_s {
|
||||
__IO uint32_t *reg_dir;
|
||||
__IO uint32_t *reg_dirclr;
|
||||
__IO uint32_t *reg_out;
|
||||
__IO uint32_t *reg_in;
|
||||
PortName port;
|
||||
uint32_t mask;
|
||||
struct arm_gpio_dev_t *gpio_dev;
|
||||
};
|
||||
|
||||
struct serial_s {
|
||||
|
@ -69,10 +77,8 @@ struct analogin_s {
|
|||
uint16_t ctrl_register; /* Control bits with the channel identifier */
|
||||
};
|
||||
|
||||
#include "gpio_object.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* __MBED_OBJECTS_H__ */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2017 ARM Limited
|
||||
* 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.
|
||||
|
@ -16,40 +16,64 @@
|
|||
#include "mbed_assert.h"
|
||||
#include "pinmap.h"
|
||||
#include "mbed_error.h"
|
||||
|
||||
#define GET_GPIO_PIN_POS(pin) (pin & 0x0F) /* pin % 16 */
|
||||
#define GET_GPIO_MAP_NUM(pin) (pin >> 4) /* pin / 16 */
|
||||
#define GPIO_NUM 4
|
||||
|
||||
static CMSDK_GPIO_TypeDef* GPIO_MAP[GPIO_NUM] = {
|
||||
CMSDK_GPIO0,
|
||||
CMSDK_GPIO1,
|
||||
CMSDK_GPIO2,
|
||||
CMSDK_GPIO3
|
||||
};
|
||||
#include "objects.h"
|
||||
|
||||
void pin_function(PinName pin, int function)
|
||||
{
|
||||
CMSDK_GPIO_TypeDef* p_gpio_map = 0;
|
||||
struct arm_gpio_dev_t *gpio_dev;
|
||||
uint32_t flags;
|
||||
|
||||
MBED_ASSERT(pin != (PinName)NC);
|
||||
MBED_ASSERT(pin != NC);
|
||||
|
||||
/* The pin has to be a GPIO pin */
|
||||
if (pin >= EXP0 && pin <= EXP51) {
|
||||
if (function == ALTERNATE_FUNC) {
|
||||
p_gpio_map = GPIO_MAP[GET_GPIO_MAP_NUM(pin)];
|
||||
p_gpio_map->ALTFUNCSET = (1 << GET_GPIO_PIN_POS(pin));
|
||||
} else if(function == GPIO_FUNC) {
|
||||
p_gpio_map = GPIO_MAP[GET_GPIO_MAP_NUM(pin)];
|
||||
p_gpio_map->ALTFUNCCLR = (1 << GET_GPIO_PIN_POS(pin));
|
||||
} else {
|
||||
error("Invalid pin_function value %d", function);
|
||||
switch (function) {
|
||||
case ALTERNATE_FUNC:
|
||||
flags = ARM_GPIO_PIN_DISABLE;
|
||||
break;
|
||||
case GPIO_FUNC:
|
||||
flags = ARM_GPIO_PIN_ENABLE;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
switch (GPIO_DEV_NUMBER(pin)) {
|
||||
#ifdef ARM_GPIO0
|
||||
case GPIO0_NUMBER:
|
||||
gpio_dev = &ARM_GPIO0_DEV;
|
||||
break;
|
||||
#endif /* ARM_GPIO0 */
|
||||
#ifdef ARM_GPIO1
|
||||
case GPIO1_NUMBER:
|
||||
gpio_dev = &ARM_GPIO1_DEV;
|
||||
break;
|
||||
#endif /* ARM_GPIO1 */
|
||||
#ifdef ARM_GPIO2
|
||||
case GPIO2_NUMBER:
|
||||
gpio_dev = &ARM_GPIO2_DEV;
|
||||
break;
|
||||
#endif /* ARM_GPIO2 */
|
||||
#ifdef ARM_GPIO3
|
||||
case GPIO3_NUMBER:
|
||||
gpio_dev = &ARM_GPIO3_DEV;
|
||||
break;
|
||||
#endif /* ARM_GPIO3 */
|
||||
default:
|
||||
error("GPIO %d, associated with expansion pin %d, is disabled",
|
||||
pin, GPIO_DEV_NUMBER(pin));
|
||||
return;
|
||||
}
|
||||
|
||||
arm_gpio_init(gpio_dev);
|
||||
(void)arm_gpio_config(gpio_dev, ARM_GPIO_ACCESS_PIN,
|
||||
GPIO_PIN_NUMBER(pin), flags);
|
||||
}
|
||||
}
|
||||
|
||||
void pin_mode(PinName pin, PinMode mode)
|
||||
{
|
||||
MBED_ASSERT(pin != (PinName)NC);
|
||||
MBED_ASSERT(pin != NC);
|
||||
|
||||
/* Pin modes configuration is not supported */
|
||||
/* PinMode is not supported */
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2017 ARM Limited
|
||||
* 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.
|
||||
|
@ -13,86 +13,90 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include "port_api.h"
|
||||
#include "pinmap.h"
|
||||
#include "gpio_api.h"
|
||||
|
||||
#define MAX_GPIO_PINS 16
|
||||
#include "objects.h"
|
||||
#include "mbed_error.h"
|
||||
|
||||
PinName port_pin(PortName port, int pin_n)
|
||||
{
|
||||
if (pin_n < 0 || pin_n > MAX_GPIO_PINS) {
|
||||
error("Invalid GPIO pin number %d", pin_n);
|
||||
if (pin_n < 0 || pin_n >= PINS_PER_GPIO ||
|
||||
((port == Port3) && (pin_n >= GPIO3_PIN_NUMBER))) {
|
||||
return NC;
|
||||
}
|
||||
|
||||
return (PinName)((port << PORT_SHIFT) | pin_n);
|
||||
return (PINS_PER_GPIO * port + pin_n);
|
||||
}
|
||||
|
||||
void port_init(port_t *obj, PortName port, int mask, PinDirection dir)
|
||||
{
|
||||
uint32_t i;
|
||||
CMSDK_GPIO_TypeDef *port_reg;
|
||||
struct arm_gpio_dev_t *gpio_dev;
|
||||
uint32_t flags = ARM_GPIO_PIN_ENABLE;
|
||||
|
||||
switch (port) {
|
||||
case Port0:
|
||||
port_reg = (CMSDK_GPIO_TypeDef *)(CMSDK_GPIO0_BASE);
|
||||
break;
|
||||
case Port1:
|
||||
port_reg = (CMSDK_GPIO_TypeDef *)(CMSDK_GPIO1_BASE);
|
||||
break;
|
||||
case Port2:
|
||||
port_reg = (CMSDK_GPIO_TypeDef *)(CMSDK_GPIO2_BASE);
|
||||
break;
|
||||
case Port3:
|
||||
port_reg = (CMSDK_GPIO_TypeDef *)(CMSDK_GPIO3_BASE);
|
||||
break;
|
||||
#ifdef ARM_GPIO0
|
||||
case Port0:
|
||||
gpio_dev = &ARM_GPIO0_DEV;
|
||||
break;
|
||||
#endif /* ARM_GPIO0 */
|
||||
#ifdef ARM_GPIO1
|
||||
case Port1:
|
||||
gpio_dev = &ARM_GPIO1_DEV;
|
||||
break;
|
||||
#endif /* ARM_GPIO1 */
|
||||
#ifdef ARM_GPIO2
|
||||
case Port2:
|
||||
gpio_dev = &ARM_GPIO2_DEV;
|
||||
break;
|
||||
#endif /* ARM_GPIO2 */
|
||||
#ifdef ARM_GPIO3
|
||||
case Port3:
|
||||
gpio_dev = &ARM_GPIO3_DEV;
|
||||
break;
|
||||
#endif /* ARM_GPIO3 */
|
||||
default:
|
||||
error("Port%d is not enabled", port);
|
||||
return;
|
||||
}
|
||||
|
||||
obj->port = port;
|
||||
obj->mask = mask;
|
||||
obj->reg_in = &port_reg->DATAOUT;
|
||||
obj->reg_dir = &port_reg->OUTENABLESET;
|
||||
obj->reg_dirclr = &port_reg->OUTENABLECLR;
|
||||
arm_gpio_init(gpio_dev);
|
||||
obj->gpio_dev = gpio_dev;
|
||||
|
||||
/* The function is set per pin: reuse gpio logic */
|
||||
for (i=0; i < MAX_GPIO_PINS; i++) {
|
||||
if (obj->mask & (1<<i)) {
|
||||
gpio_set(port_pin(obj->port, i));
|
||||
}
|
||||
arm_gpio_set_port_mask(gpio_dev, mask);
|
||||
|
||||
switch (dir) {
|
||||
case PIN_INPUT:
|
||||
flags |= ARM_GPIO_INPUT;
|
||||
break;
|
||||
case PIN_OUTPUT:
|
||||
flags |= ARM_GPIO_OUTPUT;
|
||||
break;
|
||||
/* default: not added to force to cover all enumeration cases */
|
||||
}
|
||||
|
||||
port_dir(obj, dir);
|
||||
(void)arm_gpio_config(gpio_dev, ARM_GPIO_ACCESS_PORT, ARG_NOT_USED, flags);
|
||||
}
|
||||
|
||||
void port_mode(port_t *obj, PinMode mode)
|
||||
{
|
||||
uint32_t i;
|
||||
/* The mode is set per pin: reuse pinmap logic */
|
||||
for (i=0; i < MAX_GPIO_PINS; i++) {
|
||||
if (obj->mask & (1 << i)) {
|
||||
pin_mode(port_pin(obj->port, i), mode);
|
||||
}
|
||||
}
|
||||
/* PinMode is not supported */
|
||||
}
|
||||
|
||||
void port_dir(port_t *obj, PinDirection dir)
|
||||
{
|
||||
switch (dir) {
|
||||
case PIN_INPUT:
|
||||
*obj->reg_dir &= ~obj->mask;
|
||||
break;
|
||||
case PIN_OUTPUT:
|
||||
*obj->reg_dir |= obj->mask;
|
||||
break;
|
||||
}
|
||||
uint32_t flags = (dir == PIN_OUTPUT) ? ARM_GPIO_OUTPUT : ARM_GPIO_INPUT;
|
||||
(void)arm_gpio_config(obj->gpio_dev, ARM_GPIO_ACCESS_PORT, ARG_NOT_USED,
|
||||
flags);
|
||||
}
|
||||
|
||||
void port_write(port_t *obj, int value)
|
||||
{
|
||||
*obj->reg_in = value;
|
||||
(void)arm_gpio_write(obj->gpio_dev, ARM_GPIO_ACCESS_PORT, ARG_NOT_USED,
|
||||
(uint32_t)value);
|
||||
}
|
||||
|
||||
int port_read(port_t *obj)
|
||||
{
|
||||
return (*obj->reg_in);
|
||||
return (int)arm_gpio_read(obj->gpio_dev, ARM_GPIO_ACCESS_PORT,
|
||||
ARG_NOT_USED);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2017 ARM Limited
|
||||
* 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.
|
||||
|
@ -124,8 +124,8 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
|
|||
* The CMSDK APB UART doesn't have support for flow control.
|
||||
* Ref. DDI0479C_cortex_m_system_design_kit_r1p0_trm.pdf
|
||||
*/
|
||||
uart_data[obj->index].sw_rts.pin = NC;
|
||||
uart_data[obj->index].sw_cts.pin = NC;
|
||||
uart_data[obj->index].sw_rts.pin_number = NC;
|
||||
uart_data[obj->index].sw_cts.pin_number = NC;
|
||||
|
||||
if (uart == STDIO_UART) {
|
||||
stdio_uart_inited = 1;
|
||||
|
@ -220,7 +220,7 @@ static inline void uart_irq(uint32_t intstatus, uint32_t index,
|
|||
return;
|
||||
}
|
||||
|
||||
if ((RxIrq == irq_type) && (NC != uart_data[index].sw_rts.pin)) {
|
||||
if ((RxIrq == irq_type) && (NC != uart_data[index].sw_rts.pin_number)) {
|
||||
gpio_write(&uart_data[index].sw_rts, 1);
|
||||
/* Disable interrupt if it wasn't enabled by the application */
|
||||
if (!uart_data[index].rx_irq_set_api) {
|
||||
|
|
Loading…
Reference in New Issue