LS1046ACPU ARM架构点灯小程序

#include <stdint.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <arpa/inet.h> 

#define OK          0
#define ERROR       -1

#define GPIO1_BASE_PHY_ADDR 0x2300000
#define GPIO_GROUP_SIZE     0x10000


#define GPDIR_OFFSET 0x0
#define GPODR_OFFSET 0x4
#define GPDAT_OFFSET 0x8


#define GPIO_DIR_IN 0
#define GPIO_DIR_OUT 1

static void *gpio_vir_base_addr = NULL;


void *phy_addr_to_virt(int32_t phy_base_addr, int32_t size)
{
    int fd = open("/dev/mem", O_RDWR | O_SYNC);
    if(fd < 0)
        return NULL;
    void *virt_addr = (void *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, phy_base_addr);
    close(fd);
    return virt_addr;
}

uint32_t set_bit_to_high(int32_t pin_num)
{
    uint32_t mask = (uint32_t)(1U << (31 - pin_num));
    return mask;
}

uint32_t set_bit_to_low(int32_t pin_num)
{
    uint32_t mask = (uint32_t)(1U << (31 - pin_num));
    return ~mask;
}

int32_t led_on(int32_t group, int32_t pin_num)
{
    uint64_t addr = (group - 1) * GPIO_GROUP_SIZE + GPDAT_OFFSET + gpio_vir_base_addr;
    uint32_t mask = set_bit_to_low(pin_num);
    uint32_t src = (ntohl)(*(volatile uint32_t *)addr);
    uint32_t dst = src & mask;
    *(volatile uint32_t *)addr = (htonl)(dst);
    return OK;
}

int32_t led_off(int32_t group, int32_t pin_num)
{
    uint64_t addr = (group - 1) * GPIO_GROUP_SIZE + GPDAT_OFFSET + gpio_vir_base_addr;
    uint32_t mask = (set_bit_to_high(pin_num));
    uint32_t src = (ntohl)(*(volatile uint32_t *)addr);
    uint32_t dst = src | mask;
    *(volatile uint32_t *)addr = (htonl)(dst);
    return OK;
}

int32_t gpio_dir_set(int32_t group, int32_t pin_num, int32_t dir)
{
    uint64_t addr = (group - 1) * GPIO_GROUP_SIZE + GPDIR_OFFSET + gpio_vir_base_addr;
    uint32_t src = (ntohl)(*(volatile uint32_t *)addr);
    if(dir == GPIO_DIR_OUT){
        *(volatile uint32_t *)addr = (htonl)(set_bit_to_high(pin_num) | src);
    }
    else if(dir == GPIO_DIR_IN){
        *(volatile uint32_t *)addr = (htonl)(set_bit_to_low(pin_num));
    }
    else
        return ERROR;
    return OK;
}

int32_t gpio_dir_get(int32_t group, int32_t pin_num)
{
    uint64_t addr = (group - 1) * GPIO_GROUP_SIZE + GPDIR_OFFSET + gpio_vir_base_addr;
    uint32_t src = (ntohl)(*(volatile uint32_t *)addr);
    /*未来得及测试*/
    return OK;
}


void gpio_test()
{
    int32_t i = 20;
    gpio_vir_base_addr = phy_addr_to_virt(GPIO1_BASE_PHY_ADDR, GPIO_GROUP_SIZE * 4);
    printf("gpio_vir_base_addr %#lx\n", gpio_vir_base_addr);
    if(gpio_vir_base_addr == NULL)
        printf("mmap error\n");
    
    gpio_dir_set(3, 15, GPIO_DIR_OUT);
    while(i-- > 0){
        led_on(3, 15);
        usleep(100000);
        led_off(3,15);
        usleep(100000);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值