LS1046ACPU ARM架构点灯小程序
程序员文章站
2022-06-20 21:02:10
...
#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);
}
}
推荐阅读