iTOP4412裸机开发——按键(轮巡方式)

开发环境:

itop-4412平民版,ubuntu 14.04 64位,交叉编译工具版本:gcc version 4.4.1 (Sourcery G++ Lite 2009q3-67)

start.S:

.global main
.word 0x0
.word 0x0
.word 0x0
.word 0x0
_start:
ldr r0, =0x1002330C
ldr r1, [r0]
orr r1, r1, #0x300
str r1, [r0]
ldr r0, =0x11000C08
ldr r1, =0x0
str r1, [r0]
ldr sp, =0x02060000
bl main
halt:
b halt

main.c:

#include "s3c4412_gpio.h"
typedef volatile unsigned long regtype;
#define led2_on(on) do { gpio_config(GPL2DAT, (0x1 << 0), (on << 0)); } while(0)
#define led3_on(on) do { gpio_config(GPK1DAT, (0x1 << 1), (on << 1)); } while(0)
enum key_val {
HOME,
BACK,
SLEEP,
VOLUP,
VOLDW,
};
void gpio_config(int addr, int mask, int val)
{
unsigned long value = 0;
if (val & ~(mask))
return;
regtype *gpio = (regtype *)addr;
value = ((*gpio & ~(mask)) | val);
*gpio = value;
}
unsigned long gpio_getval(int addr, int mask)
{
unsigned long value = 0;
regtype *gpio = (regtype *)addr;
value = *gpio & mask;
return value;
}
void led_init(void)
{
gpio_config(GPL2CON, (0xF << 0), (0x1 << 0));
gpio_config(GPL2PUD, (0x3 << 0), (0x0 << 0));
gpio_config(GPK1CON, (0xF << 4), (0x1 << 4));
gpio_config(GPK1PUD, (0x3 << 2), (0x0 << 2));
}
void key_init(void)
{
gpio_config(GPX1CON, (0xF << 4), (0x0 << 4));
gpio_config(GPX1PUD, (0x3 << 2), (0x0 << 2));
gpio_config(GPX1CON, (0xF << 8), (0x0 << 8));
gpio_config(GPX1PUD, (0x3 << 4), (0x0 << 4));
gpio_config(GPX3CON, (0xF << 12), (0x0 << 12));
gpio_config(GPX3PUD, (0x3 << 6), (0x0 << 6));
gpio_config(GPX2CON, (0xF << 0), (0x0 << 0));
gpio_config(GPX2PUD, (0x3 << 0), (0x0 << 0));
gpio_config(GPX2CON, (0xF << 4), (0x0 << 4));
gpio_config(GPX2PUD, (0xF << 2), (0x0 << 2));
}
int get_key(void)
{
if (!gpio_getval(GPX1DAT, (1 << 1)))
return HOME;
if (!gpio_getval(GPX1DAT, (1 << 2)))
return BACK;
if (!gpio_getval(GPX3DAT, (1 << 3)))
return SLEEP;
if (!gpio_getval(GPX2DAT, (1 << 1)))
return VOLUP;
if (!gpio_getval(GPX2DAT, (1 << 0)))
return VOLDW;
return -1;
}
void delay(int loop)
{
volatile int k;
for (k = 0; k < loop; ++k)
;
}
void main(void)
{
int i = 0;
int key = -1;
led_init();
key_init();
while(1) {
key = get_key();
if (key == HOME) {
led3_on(1);
delay(0x20000);
led3_on(0);
}
if (key == BACK) {
led2_on(1);
delay(0x20000);
led2_on(0);
}
if (key == SLEEP) {
led2_on(1);
led3_on(1);
delay(0x20000);
led2_on(0);
led3_on(0);
}
if (key == VOLUP) {
led2_on(1);
delay(0x10000);
led2_on(0);
delay(0x10000);
}
if (key == VOLDW) {
led3_on(1);
delay(0x10000);
led3_on(0);
delay(0x10000);
}
}
}

s3c4412_gpio.h:

#ifndef S3C4412_GPIO_H
#define S3C4412_GPIO_H
#define GPX1CON (0x11000000 + 0x0C20)
#define GPX1DAT (0x11000000 + 0x0C24)
#define GPX1PUD (0x11000000 + 0x0C28)
#define GPX1DRV (0x11000000 + 0x0C2C)
#define GPX2CON (0x11000000 + 0x0C40)
#define GPX2DAT (0x11000000 + 0x0C44)
#define GPX2PUD (0x11000000 + 0x0C48)
#define GPX2DRV (0x11000000 + 0x0C4C)
#define GPX3CON (0x11000000 + 0x0C60)
#define GPX3DAT (0x11000000 + 0x0C64)
#define GPX3PUD (0x11000000 + 0x0C68)
#define GPX3DRV (0x11000000 + 0x0C6C)
#define GPK1CON (0x11000000 + 0x0060)
#define GPK1DAT (0x11000000 + 0x0064)
#define GPK1PUD (0x11000000 + 0x0068)
#define GPK1DRV (0x11000000 + 0x006C)
#define GPL2CON (0x11000000 + 0x0100)
#define GPL2DAT (0x11000000 + 0x0104)
#define GPL2PUD (0x11000000 + 0x0108)
#define GPL2DRV (0x11000000 + 0x010C)
#endif

link.lds:

SECTIONS {
. = 0x0;
.text ALIGN(4) : { *(.text) }
.rodata ALIGN(4) : { *(.rodata*) } 
.data ALIGN(4) : { *(.data*) } 
.bss ALIGN(4) : { *(.bss) *(COMMON) }
}

Makefile:

CFLAGS := -nostdlib -O0
TARGET := led.bin
$(TARGET) : start.o main.o
$(CROSS_COMPILE)ld -T link.lds -o led.elf $^
$(CROSS_COMPILE)objcopy -O binary led.elf $@
$(CROSS_COMPILE)objdump -D led.elf > led.dis
%.o : %.S
$(CROSS_COMPILE)gcc -o $@ $< -c
%.o : %.c
$(CROSS_COMPILE)gcc $(CFLAGS) -o $@ $< -c
.PHONY:clean flash
clean:
rm -rf *.o *.elf *.bin *.dis
flash:
mk4412 $(TARGET)
# sudo mkfs.vfat -F 32 -I /dev/sdc
sudo dd if=/dev/zero of=/dev/sdc bs=512 seek=1 iflag=dsync oflag=dsync count=2048
sudo dd if=./$(TARGET) of=/dev/sdc bs=512 seek=1 iflag=dsync oflag=dsync

mk4412见上一篇LED裸机程序。

你可能感兴趣的:(iTOP4412裸机开发——按键(轮巡方式))