eCos GPIO读写及其中断处理

#include "oem_portmisc.h"

#include <cyg/hal/hal_intr.h>

#include <cyg/hal/drv_api.h>

#define GINT_FEDGE_0 0x10000660

#define GINT_STAT_0 0x10000690

typedef union gpio1mode_data {

u32 d32;

struct {

u32 gpio_mode:2;

u32 rsvd2_5:4;

u32 i2s_mode:2;

u32 rsvd8_19:12;

u32 i2c_mode:2;

u32 rsvd22_23:2;

u32 uart1_mode:2;

u32 rsvd26_31:6;

} b;

} gpio1mode_data_t;

typedef union gpio2mode_data {

u32 d32;

struct {

u32 rsvd0_19:20;

u32 p1_led_kn_mode:2;

u32 p2_led_kn_mode:2;

u32 p3_led_kn_mode:2;

u32 p4_led_kn_mode:2;

u32 rsvd28_31:4;

} b;

} gpio2mode_data_t;

#if defined(CONFIG_GPIO_INTR_MODE)

typedef struct gpio_intr_info {

CYG_WORD int_num;

cyg_interrupt gpio_interrupt;

cyg_handle_t gpio_interrupt_handle;

} gpio_intr_info_t;

static gpio_intr_info_t gii_1 = {

.int_num = CYGNUM_HAL_INTERRUPT_PIO,

};

static u32 va(u32 addr);

static void toggle_relay_gpio(uint8_t gpio)

{

if (gpio_get_value(gpio) > 0) {

gpio_set_value(gpio, 0);

// TODO: save it to nv

} else {

gpio_set_value(gpio, 1);

// TODO: save it to nv

}

}

static cyg_uint32 gpio_isr(cyg_vector_t vector, cyg_addrword_t data)

{

gpio_intr_info_t * gii = (gpio_intr_info_t *)data;

cyg_drv_interrupt_mask(gii->int_num);

cyg_drv_interrupt_acknowledge(gii->int_num);

// Cause DSR to be run

return CYG_ISR_CALL_DSR;

}

static void gpio_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)

{

gpio_intr_info_t * gii = (gpio_intr_info_t *)data;

u32 val = HAL_REG32(va(GINT_STAT_0));

if ((val >> SUMPWR_KEY_GPIO) & 0x1) {

toggle_relay_gpio(RELAY1_GPIO);

}

if ((val >> KEY2_GPIO) & 0x1) {

toggle_relay_gpio(RELAY2_GPIO);

}

if ((val >> KEY3_GPIO) & 0x1) {

toggle_relay_gpio(RELAY3_GPIO);

}

if ((val >> KEY4_GPIO) & 0x1) {

toggle_relay_gpio(RELAY4_GPIO);

}

cyg_drv_interrupt_unmask(gii->int_num);

diag_printf("%p\n", gii);

}

#endif

static inline u32 va(u32 addr)

{

u32 phy_addr = addr;

// kseg1: 0xA000 0000 - 0xBFFF FFFF(512M)

phy_addr &= 0x0FFFFFFC;

//phy_addr &= 0x0FFFFFFF;

phy_addr |= 0xb0000000;

return phy_addr;

}

static int8_t gpio_direction_input(uint8_t gpio)

{

mem_data_t reg_val;

u32 ctrl_addr;

if (gpio > 95) {

return -1;

}

if (gpio <= 31) {

// GPIO_CTRL_0

ctrl_addr = va(0x10000600);

} else if (gpio >= 32 && gpio <= 63) {

// GPIO_CTRL_1

ctrl_addr = va(0x10000604);

gpio = gpio - 32;

} else {

// 64 ... 95

// GPIO_CTRL_2

ctrl_addr = va(0x10000608);

gpio = gpio - 64;;

}

reg_val.d32 = HAL_REG32(ctrl_addr);

reg_val.d32 &= ~(1 << gpio);

HAL_REG32(ctrl_addr) = reg_val.d32;

return 0;

}

int8_t gpio_get_value(uint8_t gpio)

{

mem_data_t reg_val;

u32 ctrl_addr;

u32 data_addr;

if (gpio > 95) {

return -1;

}

if (gpio <= 31) {

// GPIO_CTRL_0

//ctrl_addr = va(0x10000600);

// GPIO_DATA_0

data_addr = va(0x10000620);

} else if (gpio >= 32 && gpio <= 63) {

// GPIO_CTRL_1

//ctrl_addr = va(0x10000604);

// GPIO_DATA_1

data_addr = va(0x10000624);

gpio = gpio - 32;

} else {

// 64 ... 95

// GPIO_CTRL_2

//ctrl_addr = va(0x10000608);

// GPIO_DATA_2

data_addr = va(0x10000628);

gpio = gpio - 64;;

}

// reg_val.d32 = HAL_REG32(ctrl_addr);

// reg_val.d32 &= ~(1 << gpio);

// HAL_REG32(ctrl_addr) = reg_val.d32;

reg_val.d32 = HAL_REG32(data_addr);

return ((reg_val.d32 >> gpio) & 0x1);

}

void gpio_set_value(uint8_t gpio, uint8_t value)

{

mem_data_t reg_val;

u32 ctrl_addr;

u32 data_addr;

if (gpio > 95) {

return;

}

if (gpio <= 31) {

// GPIO_CTRL_0

ctrl_addr = va(0x10000600);

if (value > 0) {

// GPIO_DSET_0

data_addr = va(0x10000630);

} else {

// GPIO_DCLR_0

data_addr = va(0x10000640);

}

} else if (gpio >= 32 && gpio <= 63) {

// GPIO_CTRL_1

ctrl_addr = va(0x10000604);

if (value > 0) {

// GPIO_DSET_1

data_addr = va(0x10000634);

} else {

// GPIO_DCLR_1

data_addr = va(0x10000644);

}

gpio = gpio - 32;

} else {

// 64 ... 95

// GPIO_CTRL_2

ctrl_addr = va(0x10000608);

if (value > 0) {

// GPIO_DSET_2

data_addr = va(0x10000638);

} else {

// GPIO_DCLR_2

data_addr = va(0x10000648);

}

gpio = gpio - 64;

}

reg_val.d32 = HAL_REG32(ctrl_addr);

reg_val.d32 |= 1 << gpio;

HAL_REG32(ctrl_addr) = reg_val.d32;

reg_val.d32 = HAL_REG32(data_addr);

reg_val.d32 |= 1 << gpio;

HAL_REG32(data_addr) = reg_val.d32;

}

void gpio_init(void)

{

#if defined(CONFIG_GPIO_INTR_MODE)

gpio_intr_info_t *gii;

#endif

gpio1mode_data_t gpio1mode;

gpio2mode_data_t gpio2mode;

u32 addr, val;

// pin mux

// Reference to "MT7628 PROGRAMMING GUIDE", p15 of System Control

// GPIO1_MODE 0x10000060

// GPIO2_MODE 0x10000064

// GPIO00,02,03,04,05,11, key4,key3,key2,sumpwr_led1,sumpwr_key,zero

addr = va(0x10000060);

gpio1mode.d32 = HAL_REG32(addr);

// GPIO11

gpio1mode.b.gpio_mode = 0;

// GPIO00,02,03

gpio1mode.b.i2s_mode = 1;

// GPIO04,05

gpio1mode.b.i2c_mode = 1;

//gpio1mode.b.uart1_mode = 0;

HAL_REG32(addr) = gpio1mode.d32;

/* falling edge */

gpio_direction_input(SUMPWR_KEY_GPIO);

gpio_direction_input(KEY2_GPIO);

gpio_direction_input(KEY3_GPIO);

gpio_direction_input(KEY4_GPIO);

// GPIO30,31,32,33, r4,r3,r2,r1

addr = va(0x10000064);

gpio2mode.d32 = HAL_REG32(addr);

// GPIO33

gpio2mode.b.p1_led_kn_mode = 1;

// GPIO32

gpio2mode.b.p2_led_kn_mode = 1;

// GPIO31

gpio2mode.b.p3_led_kn_mode = 1;

// GPIO30

gpio2mode.b.p4_led_kn_mode = 1;

HAL_REG32(addr) = gpio2mode.d32;

/* relay on: LOW, relay off: HIGH */

gpio_set_value(RELAY1_GPIO, 1);

gpio_set_value(RELAY2_GPIO, 1);

gpio_set_value(RELAY3_GPIO, 1);

gpio_set_value(RELAY4_GPIO, 1);

#if defined(CONFIG_GPIO_INTR_MODE)

val = HAL_REG32(va(GINT_FEDGE_0));

val |= (1 << SUMPWR_KEY_GPIO) | (1 << KEY2_GPIO) | (1 << KEY3_GPIO) | (1 << KEY4_GPIO);

HAL_REG32(va(GINT_FEDGE_0)) = val;

gii = &gii_1;

cyg_drv_interrupt_create(gii->int_num,

5, // can change IRQ0 priority

(cyg_addrword_t)gii, // Data item passed to interrupt handler

gpio_isr,

gpio_dsr,

&gii->gpio_interrupt_handle,

&gii->gpio_interrupt);

cyg_drv_interrupt_attach(gii->gpio_interrupt_handle);

cyg_drv_interrupt_unmask(gii->int_num);

#endif

}

module_init(gpio_init);

相关推荐
SEP50101 年前
eCos flash模拟EEPROM实现NV系统
ecos·cyg_flash_read