eCos读写GPIO

来源:互联网 发布:商城html源码 编辑:程序博客网 时间:2024/06/11 11:29
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(GPIO_INTR)
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: 3
};

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;

    cyg_drv_interrupt_unmask(gii->int_num);
    diag_printf("%p\n", gii);
}
#endif

static 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;
}

API void gpio_config(void)
{
#if defined(GPIO_INTR)
    gpio_intr_info_t *gii;
#endif
    gpio1mode_data_t gpio1mode;
    gpio2mode_data_t gpio2mode;
    u32 base;

    // 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
    base = 0x10000060;
    base = va(base);

    gpio1mode.d32 = HAL_REG32(base);
    // 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(base) = gpio1mode.d32;
 
    // GPIO30,31,32,33, r4,r3,r2,r1
    base = 0x10000064;
    base = va(base);

    gpio2mode.d32 = HAL_REG32(base);
    // 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(base) = gpio2mode.d32;

#if defined(GPIO_INTR)
    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
}

API int gpio_get_value(int gpio)
{
    int gpio_num;
    mem_data_t reg_val;
    u32 base_ctrl;
    u32 base_data;

    if (gpio < 0 || gpio > 95) {
        return -1;
    }

    if (gpio <= 31) {
        // GPIO_CTRL_0
        base_ctrl = 0x10000600;
        // GPIO_DATA_0
        base_data = 0x10000620;
        gpio_num = gpio;
    } else if (gpio >= 32 && gpio <= 63) {
        // GPIO_CTRL_1
        base_ctrl = 0x10000604;
        // GPIO_DATA_1
        base_data = 0x10000624;
        gpio_num = gpio - 32;
    } else {
        // 64 ... 95
        // GPIO_CTRL_2
        base_ctrl = 0x10000608;
        // GPIO_DATA_2
        base_data = 0x10000628;
        gpio_num = gpio - 64;;
    }

    base_ctrl = va(base_ctrl);
    reg_val.d32 = HAL_REG32(base_ctrl);
    reg_val.d32 &= ~(1 << gpio_num);
    HAL_REG32(base_ctrl) = reg_val.d32;

    base_data = va(base_data);
    reg_val.d32 = HAL_REG32(base_data);
    return ((reg_val.d32 >> gpio_num) & 0x1);
}

API int gpio_set_value(int gpio, int value)
{
    int gpio_num;
    mem_data_t reg_val;
    u32 base_ctrl;
    u32 base_data;

    if (gpio < 0 || gpio > 95) {
        return -1;
    }

    if (gpio <= 31) {
        // GPIO_CTRL_0
        base_ctrl = 0x10000600;
        if (value > 0) {
            // GPIO_DSET_0
            base_data = 0x10000630;
        } else {
            // GPIO_DCLR_0
            base_data = 0x10000640;
        }
        gpio_num = gpio;
    } else if (gpio >= 32 && gpio <= 63) {
        // GPIO_CTRL_1
        base_ctrl = 0x10000604;
        if (value > 0) {
            // GPIO_DSET_1
            base_data = 0x10000634;
        } else {
            // GPIO_DCLR_1
            base_data = 0x10000644;
        }
        gpio_num = gpio - 32;
    } else {
        // 64 ... 95
        // GPIO_CTRL_2
        base_ctrl = 0x10000608;
        if (value > 0) {
            // GPIO_DSET_2
            base_data = 0x10000638;
        } else {
            // GPIO_DCLR_2
            base_data = 0x10000648;
        }
        gpio_num = gpio - 64;
    }

    base_ctrl = va(base_ctrl);
    reg_val.d32 = HAL_REG32(base_ctrl);
    reg_val.d32 |= 1 << gpio_num;
    HAL_REG32(base_ctrl) = reg_val.d32;
    
    base_data = va(base_data);
    reg_val.d32 = HAL_REG32(base_data);
    reg_val.d32 |= 1 << gpio_num;
    HAL_REG32(base_data) = reg_val.d32;

    return 0;
}
原创粉丝点击