Add InterruptIn function.

Now we support InterruptIn.
pull/1178/head
hjjeon0608 2015-06-11 09:13:05 +09:00
parent f149bdad64
commit f34ee0d2a4
7 changed files with 274 additions and 70 deletions

View File

@ -53,9 +53,9 @@ extern "C" {
#define WIZ_GPIO_OPEN_DRAIN (3) /*!< Open Drain activation */
#define WIZ_AFNUM(X)(((uint32_t)(X) >> 8) & 0xF) // AF number (0=AF0, 1=AF1, 2=AF2, 3=AF3)
#define WIZ_PORT(X) (((uint32_t)(X) >> 4) & 0xF) // port number (0=A, 1=B, 2=C, 3=D)
#define WIZ_PIN(X) ((uint32_t)(X) & 0xF) // pin number
#define WIZ_PIN_NUM(X) ((uint32_t)(X) & 0xF) // pin number
#define WIZ_PIN_INDEX(X) (1 << ((uint32_t)(X) & 0xF)) // pin index : flag bit
typedef enum {
@ -100,25 +100,25 @@ typedef enum {
PB_13 = 0x01D,
PB_14 = 0x01E,
PB_15 = 0x01F,
PC_0 = 0x120, // 0xx:U_CTS1, 1xx:GPIOC_0, 2xx:PWM0
PC_1 = 0x121, // 0xx:U_RTS1, 1xx:GPIOC_1, 2xx:PWM1
PC_0 = 0x020, // 0xx:U_CTS1, 1xx:GPIOC_0, 2xx:PWM0
PC_1 = 0x021, // 0xx:U_RTS1, 1xx:GPIOC_1, 2xx:PWM1
PC_2 = 0x022,
PC_3 = 0x023,
PC_4 = 0x124, // 0xx:SDA1, 1xx:GPIOC_4, 2xx:PWM4
PC_4 = 0x024, // 0xx:SDA1, 1xx:GPIOC_4, 2xx:PWM4
PC_5 = 0x025,
PC_6 = 0x026,
PC_7 = 0x027,
PC_8 = 0x128, // 0xx:PWM0, 1xx:GPIOC_8, 2xx:SCL0, 3xx:AIN7
PC_9 = 0x129, // 0xx:PWM1, 1xx:GPIOC_9, 2xx:SDA0, 3xx:AIN6
PC_10 = 0x32A, // 0xx:U_TXD2, 1xx:GPIOC_10, 2xx:PWM2, 3xx:AIN5
PC_11 = 0x32B, // 0xx:U_RXD2, 1xx:GPIOC_11, 2xx:PWM3, 3xx:AIN4
PC_12 = 0x32C, // 0xx:AIN3, 1xx:GPIOC_12, 2xx:SSEL0, 3xx:AIN3
PC_13 = 0x32D, // 0xx:AIN2, 1xx:GPIOC_13, 2xx:SCLK0, 3xx:AIN2
PC_14 = 0x32E, // 0xx:AIN1, 1xx:GPIOC_14, 2xx:MISO0, 3xx:AIN1
PC_15 = 0x32F, // 0xx:AIN0, 1xx:GPIOC_15, 2xx:MOSI0, 3xx:AIN0
PC_8 = 0x028, // 0xx:PWM0, 1xx:GPIOC_8, 2xx:SCL0, 3xx:AIN7
PC_9 = 0x029, // 0xx:PWM1, 1xx:GPIOC_9, 2xx:SDA0, 3xx:AIN6
PC_10 = 0x02A, // 0xx:U_TXD2, 1xx:GPIOC_10, 2xx:PWM2, 3xx:AIN5
PC_11 = 0x02B, // 0xx:U_RXD2, 1xx:GPIOC_11, 2xx:PWM3, 3xx:AIN4
PC_12 = 0x02C, // 0xx:AIN3, 1xx:GPIOC_12, 2xx:SSEL0, 3xx:AIN3
PC_13 = 0x02D, // 0xx:AIN2, 1xx:GPIOC_13, 2xx:SCLK0, 3xx:AIN2
PC_14 = 0x02E, // 0xx:AIN1, 1xx:GPIOC_14, 2xx:MISO0, 3xx:AIN1
PC_15 = 0x02F, // 0xx:AIN0, 1xx:GPIOC_15, 2xx:MOSI0, 3xx:AIN0
PD_0 = 0x030,
PD_1 = 0x031,
PD_2 = 0x032,

View File

@ -43,9 +43,13 @@ extern "C" {
struct gpio_irq_s {
IRQn_Type irq_n;
uint32_t irq_index;
uint32_t event;
PinName pin;
uint32_t pin_index;
uint32_t pin_num;
uint32_t port_num;
uint32_t rise_null;
uint32_t fall_null;
};
struct port_s {

View File

@ -34,28 +34,25 @@
extern uint32_t Get_GPIO_BaseAddress(uint32_t port_idx);
uint32_t gpio_set(PinName pin)
{
MBED_ASSERT(pin != (PinName)NC);
//uint32_t gpio_set(PinName pin)
//{
// MBED_ASSERT(pin != (PinName)NC);
pin_function(pin, WIZ_PIN_DATA(WIZ_MODE_INPUT, WIZ_GPIO_NOPULL, 0));
// //pin_function(pin, WIZ_PIN_DATA(WIZ_MODE_INPUT, WIZ_GPIO_NOPULL, 1));
return (uint32_t)(1 << ((uint32_t)pin & 0xF)); // Return the pin mask
}
// return (uint32_t)(1 << ((uint32_t)pin & 0xF)); // Return the pin mask
//}
void gpio_init(gpio_t *obj, PinName pin)
{
obj->pin = pin;
if (pin == (PinName)NC) {
return;
}
uint32_t port_index = WIZ_PORT(pin);
GPIO_TypeDef *gpio = (GPIO_TypeDef *)Get_GPIO_BaseAddress(port_index);
// Fill GPIO object structure for future use
obj->mask = gpio_set(pin);
obj->port_num = WIZ_PORT(pin);
obj->pin_index = WIZ_PIN_INDEX(pin);
obj->pin = pin;
GPIO_TypeDef *gpio = (GPIO_TypeDef *)Get_GPIO_BaseAddress(obj->port_num);
obj->reg_data_in = &gpio->DATA;
}
@ -69,9 +66,9 @@ void gpio_dir(gpio_t *obj, PinDirection direction)
MBED_ASSERT(obj->pin != (PinName)NC);
obj->direction = direction;
if (direction == PIN_OUTPUT) {
pin_function(obj->pin, WIZ_PIN_DATA(WIZ_MODE_OUTPUT, WIZ_GPIO_NOPULL, 0));
if (direction == PIN_OUTPUT) {
pin_function(obj->pin, WIZ_PIN_DATA(WIZ_MODE_OUTPUT, WIZ_GPIO_NOPULL, 1));
} else { // PIN_INPUT
pin_function(obj->pin, WIZ_PIN_DATA(WIZ_MODE_INPUT, WIZ_GPIO_NOPULL, 0));
pin_function(obj->pin, WIZ_PIN_DATA(WIZ_MODE_INPUT, WIZ_GPIO_NOPULL, 1));
}
}

View File

@ -0,0 +1,210 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2015 WIZnet Co.,Ltd. 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.
*******************************************************************************
*/
#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)
#define EDGE_BOTH (3)
static gpio_irq_handler irq_handler;
//typedef struct {
// uint32_t port[4];
// uint32_t pin[16];
// uint32_t ids;
//} irq_channel;
static uint32_t channel_ids[4][16];
#ifdef __cplusplus
extern "C"{
#endif
void PORT0_Handler(void)
{
int i = 0;
for(i=0; i<16; i++)
{
if(GPIOA->Interrupt.INTSTATUS & (1 << i))
{
GPIOA->Interrupt.INTCLEAR |= (1 << i);
if(GPIOA->INTPOLSET >> i) //rising
irq_handler(channel_ids[0][i], IRQ_RISE);
else //falling
irq_handler(channel_ids[0][i], IRQ_FALL);
}
}
}
void PORT1_Handler(void)
{
int i = 0;
for(i=0; i<16; i++)
{
if(GPIOB->Interrupt.INTSTATUS & (1 << i))
{
GPIOB->Interrupt.INTCLEAR |= (1 << i);
if(GPIOB->INTPOLSET >> i) //rising
irq_handler(channel_ids[0][i], IRQ_RISE);
else //falling
irq_handler(channel_ids[0][i], IRQ_FALL);
}
}
}
void PORT2_Handler(void)
{
int i = 0;
for(i=0; i<16; i++)
{
if(GPIOC->Interrupt.INTSTATUS & (1 << i))
{
GPIOC->Interrupt.INTCLEAR |= (1 << i);
if(GPIOC->INTPOLSET >> i) //rising
irq_handler(channel_ids[0][i], IRQ_RISE);
else //falling
irq_handler(channel_ids[0][i], IRQ_FALL);
}
}
}
void PORT3_Handler(void)
{
int i;
for(i=0; i<5; i++)
{
if(GPIOD->Interrupt.INTSTATUS & (1 << i))
{
GPIOD->Interrupt.INTCLEAR |= (1 << i);
if(GPIOD->INTPOLSET >> i) //rising
irq_handler(channel_ids[0][i], IRQ_RISE);
else //falling
irq_handler(channel_ids[0][i], IRQ_FALL);
}
}
}
#ifdef __cplusplus
}
#endif
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
{
obj->port_num = WIZ_PORT(pin);
obj->pin_num = WIZ_PIN_NUM(pin);
obj->pin_index = WIZ_PIN_INDEX(pin);
if (pin == NC) return -1;
if(obj->port_num == 0)
obj->irq_n = PORT0_IRQn;
else if(obj->port_num == 1)
obj->irq_n = PORT1_IRQn;
else if(obj->port_num == 2)
obj->irq_n = PORT2_IRQn;
else
obj->irq_n = PORT3_IRQn;
//obj->event = EDGE_FALL;
obj->pin = pin;
// Enable EXTI interrupt
NVIC_EnableIRQ(obj->irq_n);
channel_ids[obj->port_num][obj->pin_num] = id;
irq_handler = handler;
return 0;
}
void gpio_irq_free(gpio_irq_t *obj)
{
channel_ids[obj->port_num][obj->pin_num] = 0;
obj->event = EDGE_NONE;
}
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
{
GPIO_TypeDef *gpio = (GPIO_TypeDef *)Get_GPIO_BaseAddress(obj->port_num);
if (enable) {
if (event == IRQ_RISE) {
gpio->INTPOLSET |= obj->pin_index;
obj->event = EDGE_RISE;
obj->rise_null = 0;
}
else if (event == IRQ_FALL) {
gpio->INTPOLSET &= ~obj->pin_index;
obj->event = EDGE_FALL;
obj->fall_null = 0;
}
gpio->INTTYPESET |= obj->pin_index;
gpio->INTENSET |= obj->pin_index;
} else {
if (event == IRQ_RISE) {
obj->rise_null = 1;
if(obj->fall_null)
gpio->INTENCLR |= obj->pin_index;
}
else if (event == IRQ_FALL) {
obj->fall_null = 1;
if(obj->rise_null)
gpio->INTENCLR |= obj->pin_index;
}
}
}
void gpio_irq_enable(gpio_irq_t *obj)
{
NVIC_EnableIRQ(obj->irq_n);
}
void gpio_irq_disable(gpio_irq_t *obj)
{
NVIC_DisableIRQ(obj->irq_n);
obj->event = EDGE_NONE;
}

View File

@ -39,7 +39,8 @@ extern "C" {
typedef struct {
PinName pin;
uint32_t mask;
uint32_t pin_index;
uint32_t port_num;
uint32_t direction;
__IO uint32_t *reg_data_in;
} gpio_t;
@ -51,20 +52,19 @@ extern uint32_t Get_GPIO_BaseAddress(uint32_t port_idx);
static inline void gpio_write(gpio_t *obj, int value) {
MBED_ASSERT(obj->pin != (PinName)NC);
uint32_t port_index = WIZ_PORT(obj->pin);
uint32_t pin_index = WIZ_PIN(obj->pin);
uint32_t gpio_add = Get_GPIO_BaseAddress(port_index);
GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add;
uint32_t port_num = WIZ_PORT(obj->pin);
uint32_t pin_index = WIZ_PIN_INDEX(obj->pin);
GPIO_TypeDef *gpio = (GPIO_TypeDef *)Get_GPIO_BaseAddress(port_num);
if (value)
{
HAL_GPIO_SetBits(gpio,(0x01 << pin_index));
HAL_GPIO_SetBits(gpio, pin_index);
}
else
{
HAL_GPIO_ResetBits(gpio,(0x01 << pin_index));
HAL_GPIO_ResetBits(gpio, pin_index);
}
}
@ -73,18 +73,17 @@ static inline int gpio_read(gpio_t *obj) {
MBED_ASSERT(obj->pin != (PinName)NC);
uint32_t port_index = WIZ_PORT(obj->pin);
uint32_t port_num = WIZ_PORT(obj->pin);
uint32_t gpio_add = Get_GPIO_BaseAddress(port_index);
GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add;
GPIO_TypeDef *gpio = (GPIO_TypeDef *)Get_GPIO_BaseAddress(port_num);
if(obj->direction == PIN_OUTPUT)
{
ret = ( HAL_GPIO_ReadOutputData(gpio) & obj->mask ) ? 1 : 0;
ret = ( HAL_GPIO_ReadOutputData(gpio) & obj->pin_index ) ? 1 : 0;
}
else
{
ret = ((*obj->reg_data_in & obj->mask) ? 1 : 0);
ret = ((*obj->reg_data_in & obj->pin_index) ? 1 : 0);
}
return ret;

View File

@ -75,34 +75,28 @@ void pin_function(PinName pin, int data) {
// Get the pin informations
uint32_t mode = WIZ_PIN_MODE(data);
uint32_t pupd = WIZ_PIN_PUPD(data);
uint32_t afnum;
uint32_t afnum = WIZ_PIN_AFNUM(data);
uint32_t port_num = WIZ_PORT(pin);
uint32_t pin_index = WIZ_PIN_INDEX(pin);
if( mode == WIZ_MODE_AF )
afnum = WIZ_PIN_AFNUM(data);
else
afnum = WIZ_AFNUM(pin);
uint32_t port_index = WIZ_PORT(pin);
uint32_t pin_index = WIZ_PIN(pin);
uint32_t gpio_add = Get_GPIO_BaseAddress(port_index);
uint32_t gpio_add = Get_GPIO_BaseAddress(port_num);
GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add;
// Configure Alternate Function
// Warning: Must be done before the GPIO is initialized
switch (afnum) {
case 0:
HAL_PAD_AFConfig(port_index,(uint32_t)(1 << pin_index),Px_AFSR_AF0);
HAL_PAD_AFConfig(port_num, pin_index,Px_AFSR_AF0);
break;
case 1:
HAL_PAD_AFConfig(port_index,(uint32_t)(1 << pin_index),Px_AFSR_AF1);
HAL_PAD_AFConfig(port_num, pin_index,Px_AFSR_AF1);
break;
case 2:
HAL_PAD_AFConfig(port_index,(uint32_t)(1 << pin_index),Px_AFSR_AF2);
HAL_PAD_AFConfig(port_num, pin_index,Px_AFSR_AF2);
break;
case 3:
HAL_PAD_AFConfig(port_index,(uint32_t)(1 << pin_index),Px_AFSR_AF3);
HAL_PAD_AFConfig(port_num, pin_index,Px_AFSR_AF3);
break;
default:
break;
@ -113,7 +107,7 @@ void pin_function(PinName pin, int data) {
// Configure GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = (uint32_t)(1 << pin_index);
GPIO_InitStructure.GPIO_Pin = pin_index;
GPIO_InitStructure.GPIO_Mode = mode;
GPIO_InitStructure.GPIO_Pad = gpio_pupd[pupd];
HAL_GPIO_Init(gpio, &GPIO_InitStructure);
@ -128,9 +122,9 @@ void pin_mode(PinName pin, PinMode pupd)
P_Port_Def *px_pcr;
uint32_t port_index = WIZ_PORT(pin);
uint32_t port_num = WIZ_PORT(pin);
switch(port_index) {
switch(port_num) {
case PortA:
px_pcr = PA_PCR;
break;
@ -148,7 +142,7 @@ void pin_mode(PinName pin, PinMode pupd)
return;
}
px_pcr->Port[port_index] &= ~(Px_PCR_PUPD_DOWN|Px_PCR_PUPD_UP|Px_PCR_DS_HIGH| \
px_pcr->Port[port_num] &= ~(Px_PCR_PUPD_DOWN|Px_PCR_PUPD_UP|Px_PCR_DS_HIGH| \
Px_PCR_OD | Px_PCR_IE | Px_PCR_CS_SUMMIT);
px_pcr->Port[port_index] |= gpio_pupd[pupd];
px_pcr->Port[port_num] |= gpio_pupd[pupd];
}

View File

@ -53,11 +53,11 @@ PinName port_pin(PortName port, int pin_n)
void port_init(port_t *obj, PortName port, int mask, PinDirection dir)
{
uint32_t port_index = (uint32_t)port;
uint32_t port_num = (uint32_t)port;
// Enable GPIO clock
uint32_t gpio_add = Get_GPIO_BaseAddress(port_index);
GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add;
GPIO_TypeDef *gpio = (GPIO_TypeDef *)Get_GPIO_BaseAddress(port_num);
// Fill PORT object structure for future use
obj->port = port;