1
0
mirror of git://projects.qi-hardware.com/nn-usb-fpga.git synced 2025-04-21 12:27:27 +03:00

Adding PS2, capacitive keyboard examples

This commit is contained in:
carlos
2010-11-30 19:26:56 -05:00
parent 2efe106cf3
commit 62d0edf217
275 changed files with 1696660 additions and 23991 deletions

View File

@@ -0,0 +1,88 @@
DESIGN = uart_peripheral
PINS = $(DESIGN).ucf
DEVICE = xc3s500e-VQ100-4
BGFLAGS = -g TdoPin:PULLNONE -g DonePin:PULLUP \
-g CRC:enable -g StartUpClk:CCLK
SIM_CMD = vsim
SIM_COMP_SCRIPT = simulation/$(DESIGN)_TB.do
SIMGEN_OPTIONS = -p $(FPGA_ARCH) -lang $(LANGUAGE)
IVERILOG = iverilog
SAKC_IP = 192.168.254.101
SRC = uart_peripheral.v \
uart.v
SIM_SRC =uart_peripheral.v\
all: bits
remake: clean-build all
clean:
rm -rf *~ */*~ a.out *.log *.key *.edf *.ps trace.dat
rm -rf *.bit build
cleanall: clean
rm -rf build simulation/work simulation/transcript simulation/vsim.wlf simulation/blink_TB.vvp simulation/blink_TB.vcd
bits: $(DESIGN).bit
#
# Synthesis
#
build/project.src:
@[ -d build ] || mkdir build
@rm -f $@
for i in $(SRC); do echo verilog work ../$$i >> $@; done
for i in $(SRC_HDL); do echo VHDL work ../$$i >> $@; done
build/project.xst: build/project.src
echo "run" > $@
echo "-top $(DESIGN) " >> $@
echo "-p $(DEVICE)" >> $@
echo "-opt_mode Area" >> $@
echo "-opt_level 1" >> $@
echo "-ifn project.src" >> $@
echo "-ifmt mixed" >> $@
echo "-ofn project.ngc" >> $@
echo "-ofmt NGC" >> $@
echo "-rtlview yes" >> $@
build/project.ngc: build/project.xst $(SRC)
cd build && xst -ifn project.xst -ofn project.log
build/project.ngd: build/project.ngc $(PINS)
cd build && ngdbuild -p $(DEVICE) project.ngc -uc ../$(PINS)
build/project.ncd: build/project.ngd
cd build && map -pr b -p $(DEVICE) project
build/project_r.ncd: build/project.ncd
cd build && par -w project project_r.ncd
build/project_r.twr: build/project_r.ncd
cd build && trce -v 25 project_r.ncd project.pcf
$(DESIGN).bit: build/project_r.ncd build/project_r.twr
cd build && bitgen project_r.ncd -l -w $(BGFLAGS)
@mv -f build/project_r.bit $@
build/project_r.v: build/project_r.ncd
cd build && ngd2ver project.ngd -w project.v
modelsim:
cd simulation; $(SIM_CMD) -do $(DESIGN)_TB.do
timesim: build/project_r.v
cd simulation; $(SIM_CMD) -do $(DESIGN)_TIMING_TB.do
iversim:
$(IVERILOG) -o simulation/$(DESIGN)_TB.vvp $(VINCDIR) $(SRC) $(SIM_SRC) -s $(DESIGN)_TB
vvp simulation/$(DESIGN)_TB.vvp; mv $(DESIGN)_TB.vcd simulation/
gtkwave simulation/$(DESIGN)_TB.vcd&
upload: $(DESIGN).bit
scp $(DESIGN).bit root@$(SAKC_IP):binaries

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,35 @@
NET clk LOC = "P38";
NET reset LOC = "P30";
NET led LOC = "P44";
NET TxD LOC = "p67";#To MAX-232
NET RxD LOC = "P70";
NET irq_pin LOC = "P71";
#ADDRESS BUS
NET "addr<2>" LOC = "P79";
NET "addr<1>" LOC = "P83";
NET "addr<0>" LOC = "P84";
#DATA BUS
NET "sram_data<7>" LOC = "P4";
NET "sram_data<6>" LOC = "P5";
NET "sram_data<5>" LOC = "P9";
NET "sram_data<4>" LOC = "P10";
NET "sram_data<3>" LOC = "P11";
NET "sram_data<2>" LOC = "P12";
NET "sram_data<1>" LOC = "P15";
NET "sram_data<0>" LOC = "P16";
#CONTROL BUS
NET "nwe" LOC = "P88";
NET "noe" LOC = "P86";
NET "ncs" LOC = "P69";
#ADC
#NET "ADC_EOC" LOC = "P17";
#NET "ADC_SCLK" LOC = "P18";
#NET "ADC_SDIN" LOC = "P22";
#NET "ADC_SDOUT" LOC = "P23";
#NET "ADC_CS" LOC = "P24";
#NET "ADC_CSTART" LOC = "P26";

View File

@@ -0,0 +1,87 @@
`timescale 1ns / 1ps
module uart_peripheral(clk, sram_data, addr, nwe, ncs, noe, reset, led, RxD,TxD,irq_pin);
parameter B = (7);
input clk, nwe, ncs, noe, reset,RxD;
input [2:0] addr;
inout [B:0] sram_data;
output led,TxD;
output irq_pin;
// synchronize signals
reg sncs, snwe;
reg [2:0] buffer_addr;
reg [B:0] buffer_data;
reg [24:0] counter;
// interfaz fpga signals
// wire [12:0] addr;
// bram interfaz signals
reg we;
reg w_st;
wire [7:0] RD;
reg [B:0] wdBus;
wire [B:0] rdBus;
// interefaz signals assignments
wire T = ~noe | ncs;
assign sram_data = T?8'bZ:rdBus;
//--------------------------------------------------------------------------
// synchronize assignment
always @(negedge clk)
begin
sncs <= ncs;
snwe <= nwe;
buffer_data <= sram_data;
buffer_addr <= addr;
end
// write access cpu to bram
always @(posedge clk)
if(~reset) {w_st, we, wdBus} <= 0;
else begin
wdBus <= buffer_data;
case (w_st)
0: begin
we <= 0;
if(sncs | snwe) w_st <= 1;
end
1: begin
if(~(sncs | snwe)) begin
we <= 1;
w_st <= 0;
end
else we <= 0;
end
endcase
end
//the UART Module
UART UART(
.CLK(clk),
.reset(~reset),
.CS(~sncs),
.nRW(we),
.data_in(wdBus),
.data_out(rdBus),
.RxD(RxD),
.TxD(TxD),
.add(buffer_addr),
.nIRQ(irq_pin)
);
always @(posedge clk) begin
if (~reset)
counter <= {25{1'b0}};
else
counter <= counter + 1;
end
assign led = counter[24];
endmodule

View File

@@ -0,0 +1,185 @@
/* Driver Para UART tipo 8250 Implementada en FPGA.
* Autor: amasprillav - Basado en 'Tiny TTY driver * * Copyright (C) 2002 Greg Kroah-Hartman' y algunas funciones de xuart7350 de la página
* http://www.embeddedarm.com, también de http://lkml.org/lkml/2008/8/5/295 y de http://en.wikibooks.org/wiki/Serial_Programming/termios
* Fecha: 6/11/2010
* Sistemas Embebidos - UNAL 2010-II
*/
#define DEBUG 1
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <asm/mach-jz4740/gpio.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <linux/delay.h>
#define FPGA_BASE 0xB5000000
/*Registros de la UART*/
#define RHR 0x00
#define THR 0x00
#define IER 0x01
#define FCR 0x02
#define ISR 0x02
#define LCR 0x03
#define MCR 0x04
#define LSR 0x05
#define MSR 0x06
#define SCR 0x07
/*Registros para la velocidad de transmisión*/
#define DIVLSB 0x00 //latch de las cifras más significativas
#define DIVMSB 0x01 //latch de las cifras menos significativas
#define FPGA_IRQ_PIN JZ_GPIO_PORTC(15)
#define CS2_PIN JZ_GPIO_PORTB(26)
struct uart_port port;
static const char driver_name[] = "ttyFPGA";
static const char tty_dev_name[] = "ttyFPGA";
static void fpga_putc(struct uart_port *port, unsigned char c){outb(c,FPGA_BASE);}
static irqreturn_t vuart_rxint(int irq,void *dev_id){
tty_insert_flip_char(port.state->port.tty, inb(FPGA_BASE), TTY_NORMAL);
tty_flip_buffer_push(port.state->port.tty);
return IRQ_HANDLED;
return IRQ_HANDLED;
}
static unsigned int fpga_tx_empty(struct uart_port *port){return 1;}
static void fpga_set_mctrl(struct uart_port *port, unsigned int mctrl){}
static unsigned int fpga_get_mctrl(struct uart_port *port){return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;}
static void fpga_stop_tx(struct uart_port *port){}
static void fpga_start_tx(struct uart_port *port){
while(1){
fpga_putc(port,port->state->xmit.buf[port->state->xmit.tail]);
printk("enviado: %c\n",port->state->xmit.buf[port->state->xmit.tail]);
//Ajustar la cola de la UART Al buffer
port->state->xmit.tail=(port->state->xmit.tail+1)&(UART_XMIT_SIZE-1);
port->icount.tx++;
if(uart_circ_empty(&port->state->xmit))break;
}
}
static void fpga_stop_rx(struct uart_port *port){}
static void fpga_enable_ms(struct uart_port *port){}
static void fpga_break_ctl(struct uart_port *port, int break_state){}
static int fpga_startup(struct uart_port *port){
int res;
printk("fpga_startup\n");
res = request_irq(port->irq, vuart_rxint,IRQF_TRIGGER_FALLING, "ttyFPGA",(void*)port);//IRQF_DISABLED |
if(res){
printk("No se pudo registrar el IRQ!\n");
return res;
}
//Envío los registros de inicialización para la velocidad de transmisión y recepción, también el formato de datos...
outb(0x80,FPGA_BASE+LCR);
//acá lo coloco a 9600 baudios porque es la velocidad de transmisión (esto es temporal).
outb(0x00,FPGA_BASE+DIVMSB);
outb(0x0c,FPGA_BASE+DIVLSB);
//registro para habilitar las interrupciones...
outb(0x03,FPGA_BASE+LCR);
outb(0xCF,FPGA_BASE+FCR);
outb(0x0B,FPGA_BASE+MCR);
outb(0x01,FPGA_BASE+IER);
return 0;
}
static void fpga_shutdown(struct uart_port *port){free_irq(port->irq, (void*)port);}
static void fpga_set_termios(struct uart_port *port,struct ktermios *termios,struct ktermios *old){}
static const char *fpga_type(struct uart_port *port){return "ttyfpga";}
static int fpga_request_port(struct uart_port *port){return 0;}
static void fpga_config_port(struct uart_port *port, int flags){
if (flags & UART_CONFIG_TYPE)
port->type = PORT_16550A;
}
static void fpga_release_port(struct uart_port *port){}
static int fpga_verify_port(struct uart_port *port, struct serial_struct *ser){return 0;}
static struct uart_ops fpga_uart_ops = {
.tx_empty = fpga_tx_empty,
.set_mctrl = fpga_set_mctrl,
.get_mctrl = fpga_get_mctrl,
.stop_tx = fpga_stop_tx,
.start_tx = fpga_start_tx,
.stop_rx = fpga_stop_rx,
.enable_ms = fpga_enable_ms,
.break_ctl = fpga_break_ctl,
.startup = fpga_startup,
.shutdown = fpga_shutdown,
.set_termios = fpga_set_termios,
.type = fpga_type,
.release_port = fpga_release_port,
.request_port = fpga_request_port,
.config_port = fpga_config_port,
.verify_port = fpga_verify_port,
};
static struct uart_driver fpga_driver = {
.owner = THIS_MODULE,
.driver_name = driver_name,
.dev_name = tty_dev_name,
.major = 240,
.minor = 0,
.nr = 2,
};
static int __init fpga_init (void){
int ret;
unsigned int irq;
// Set GPIOB26 as part of External Memory Controller
jz_gpio_set_function(CS2_PIN, JZ_GPIO_FUNC1);
//registrar el driver
ret = uart_register_driver(&fpga_driver);
if (ret) {
pr_err("%s: No se pudo registrar la UART!\n", driver_name);
return ret;
}
//asignar el pin de IRQ al que está conectado a la FPGA (IRQ_F en el esquemático)
irq = gpio_to_irq(FPGA_IRQ_PIN);
//insertar los valores del puerto
port.membase=(u8*)FPGA_BASE;
port.line = 0;
port.ops = &fpga_uart_ops;
port.flags = ASYNC_BOOT_AUTOCONF;
port.type = PORT_16550A;
port.irq = irq;
ret = uart_add_one_port(&fpga_driver, &port);
if (ret) {
pr_err("%s: No se pudo agregar el puerto ttyFPGA0!\n", driver_name);
uart_remove_one_port(&fpga_driver, &port);
uart_unregister_driver(&fpga_driver);
return ret;
}
printk ("%s: Modulo cargado...\n", driver_name);
return 0;
}
static void __exit fpga_exit (void){
uart_remove_one_port(&fpga_driver, &port);
uart_unregister_driver(&fpga_driver);
printk ("%s: Modulo descargado...\n", driver_name);
}
MODULE_AUTHOR("amasprillav <amasprillav@unal.edu.co>");
MODULE_DESCRIPTION("Driver para UART tipo 8250 implementada en Verilog");
MODULE_LICENSE("GPL");
module_init(fpga_init);
module_exit(fpga_exit);

View File

@@ -0,0 +1,23 @@
EXTRA_CFLAGS += -Wall
CC = mipsel-openwrt-linux-gcc
OPENWRT_BASE = /home/cain/Embedded/ingenic/sakc/openwrt-xburst/
KERNEL_SRC = $(OPENWRT_BASE)/build_dir/linux-xburst_qi_lb60/linux-2.6.32.16/
CROSS_COMPILE = mipsel-openwrt-linux-
obj-m += 8250_fpga.o
all: driver
driver:
make -C $(KERNEL_SRC) M=$(PWD) ARCH=mips CROSS_COMPILE=$(CROSS_COMPILE) modules
clean:
make -C $(KERNEL_SRC) M=$(PWD) ARCH=mips CROSS_COMPILE=$(CROSS_COMPILE) clean
rm -rf *.o main.o main irq.ko Modules.symvers irq_main
main: main.o
PREPROCESS.c = $(CC) $(CFLAGS) $(TARGET_ARCH) -E -Wp,-C,-dD,-dI
%.pp : %.c FORCE
$(PREPROCESS.c) $< > $@

View File

@@ -0,0 +1,21 @@
EXTRA_CFLAGS += -Wall
CC = mipsel-openwrt-linux-gcc
OPENWRT_BASE = /home/cain/Embedded/ingenic/sakc/openwrt-xburst/
KERNEL_SRC = $(OPENWRT_BASE)/build_dir/linux-xburst_qi_lb60/linux-2.6.32.16/
CROSS_COMPILE = mipsel-openwrt-linux-
obj-m += cap_keyboard.o
all: driver
driver:
make -C $(KERNEL_SRC) M=$(PWD) ARCH=mips CROSS_COMPILE=$(CROSS_COMPILE) modules
clean:
make -C $(KERNEL_SRC) M=$(PWD) ARCH=mips CROSS_COMPILE=$(CROSS_COMPILE) clean
rm -rf *.o main.o main irq.ko Modules.symvers irq_main
PREPROCESS.c = $(CC) $(CFLAGS) $(TARGET_ARCH) -E -Wp,-C,-dD,-dI
%.pp : %.c FORCE
$(PREPROCESS.c) $< > $@

View File

@@ -0,0 +1,283 @@
/*Atmel QT-60486 drivers
*Sistemas Embebidos
*UNAL
*Authors: amasprillav,jsbuendiag,jamonsalveh
*Year: 2010-II*/
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/interrupt.h> /* We want an interrupt */
#include <linux/irq.h> /* We want an interrupt */
#include <linux/platform_device.h>
#include <linux/fs.h>
#include <asm/delay.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/gpio.h>
#include <asm/mach-jz4740/gpio.h>
#include <linux/input.h>
#define FPGA_IRQ_PIN JZ_GPIO_PORTC(15) //pin del irq
#define FPGA_BASE 0xB5000000 //direccion virtual base de la FPGA
MODULE_AUTHOR("amasprillav <amasprillav at unal dot edu dot co");
MODULE_DESCRIPTION("Atmel QT60486 Capacitive Keyboard Driver");
MODULE_LICENSE("GPL");
static unsigned int fn=0, anterior;//variables globales para indicar si la tecla fn ha sido oprimida
//y para controlar que no se escriba una tecla mas de una vez respectivamente
//arreglo que posee el keycode de las teclas posibles
static unsigned int cap_keycode[] = {
KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_0,
KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U, KEY_I, KEY_O, KEY_P,
KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, KEY_H, KEY_J, KEY_K, KEY_L, KEY_BACKSPACE,
KEY_ESC, KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, KEY_N, KEY_M, KEY_EQUAL, KEY_ENTER,
KEY_TAB, KEY_LEFTBRACE, KEY_RIGHTBRACE, KEY_COMMA, KEY_DOT, KEY_BACKSLASH, KEY_SLASH, KEY_APOSTROPHE, KEY_UP, KEY_SEMICOLON,
KEY_LEFTSHIFT, KEY_RIGHTALT, KEY_LEFTALT, KEY_SPACE, KEY_RIGHTCTRL, KEY_LEFT, KEY_DOWN, KEY_RIGHT, KEY_MINUS, KEY_RIGHTALT
};
unsigned int irq;//variable global del numero del irq asignado
//funcion del codificador normal
static unsigned int keydecode(unsigned char valor){
unsigned int salida;//variable la cual tiene el valor del keycode para ser usada en las demas funciones
//codificador para cuando se oprime una tecla normalmente
switch(valor){
case 150:salida=KEY_Q;break;
case 200:salida=KEY_W;break;
case 170:salida=KEY_E;break;
case 244:salida=KEY_R;break;
case 22:salida=KEY_T;break;
case 72:salida=KEY_Y;break;
case 41:salida=KEY_U;break;
case 119:salida=KEY_I;break;
case 149:salida=KEY_O;break;
case 203:salida=KEY_P;break;
case 116:salida=KEY_A;break;
case 169:salida=KEY_S;break;
case 104:salida=KEY_D;break;
case 54:salida=KEY_F;break;
case 212:salida=KEY_G;break;
case 138:salida=KEY_H;break;
case 235:salida=KEY_J;break;
case 181:salida=KEY_K;break;
case 87:salida=KEY_L;break;
case 9:salida=KEY_BACKSPACE;break;
case 42:salida=KEY_ESC;break;
case 247:salida=KEY_Z;break;
case 55:salida=KEY_X;break;
case 105:salida=KEY_C;break;
case 139:salida=KEY_V;break;
case 213:salida=KEY_B;break;
case 180:salida=KEY_N;break;
case 234:salida=KEY_M;break;
case 8:salida=KEY_EQUAL;break;
case 86:salida=KEY_ENTER;break;
case 75:salida=KEY_TAB;break;
case 21:salida=KEY_LEFTBRACE;break;
case 245:salida=KEY_RIGHTBRACE;break;
case 171:salida=KEY_COMMA;break;
case 73:salida=KEY_DOT;break;
case 23:salida=KEY_BACKSLASH;break;
case 118:salida=KEY_SLASH;break;
case 40:salida=KEY_APOSTROPHE;break;
case 202:salida=KEY_UP;break;
case 137:salida=KEY_LEFTSHIFT;break;
case 215:salida=KEY_RIGHTALT;break;
case 53:salida=KEY_LEFTALT;break;
case 107:salida=KEY_SPACE;break;
case 10:salida=KEY_RIGHTCTRL;break;
case 84:salida=KEY_LEFT;break;
case 182:salida=KEY_DOWN;break;
case 232:salida=KEY_RIGHT;break;
default: salida=0;break;
}
return salida;
}
//funcion del codificador FN
static unsigned int keydecodefn(unsigned char valor){
unsigned int salida; //variable la cual tiene el valor del keycode para ser usada en las demas funciones
//codificador para cuando se oprime una tecla una vez se ha oprimida la tecla FN
switch(valor){
case 150:salida=KEY_1;break;
case 200:salida=KEY_2;break;
case 170:salida=KEY_3;break;
case 244:salida=KEY_4;break;
case 22:salida=KEY_5;break;
case 72:salida=KEY_6;break;
case 41:salida=KEY_7;break;
case 119:salida=KEY_8;break;
case 149:salida=KEY_9;break;
case 203:salida=KEY_P;break;
case 116:salida=KEY_7;break;
case 169:salida=KEY_8;break;
case 104:salida=KEY_9;break;
case 54:salida=KEY_0;break;
case 212:salida=KEY_MINUS;break;
case 138:salida=KEY_H;break;
case 235:salida=KEY_4;break;
case 181:salida=KEY_5;break;
case 87:salida=KEY_6;break;
case 9:salida=KEY_BACKSPACE;break;
case 42:salida=KEY_ESC;break;
case 247:salida=KEY_Z;break;
case 55:salida=KEY_X;break;
case 105:salida=KEY_C;break;
case 139:salida=KEY_V;break;
case 213:salida=KEY_B;break;
case 180:salida=KEY_1;break;
case 234:salida=KEY_2;break;
case 8:salida=KEY_3;break;
case 86:salida=KEY_ENTER;break;
case 75:salida=KEY_TAB;break;
case 21:salida=KEY_LEFTBRACE;break;
case 245:salida=KEY_RIGHTBRACE;break;
case 171:salida=KEY_COMMA;break;
case 73:salida=KEY_DOT;break;
case 23:salida=KEY_BACKSLASH;break;
case 118:salida=KEY_0;break;
case 40:salida=KEY_MINUS;break;
case 202:salida=KEY_UP;break;
case 137:salida=KEY_LEFTSHIFT;break;
case 215:salida=KEY_RIGHTALT;break;
case 53:salida=KEY_LEFTALT;break;
case 107:salida=KEY_SPACE;break;
case 10:salida=KEY_RIGHTCTRL;break;
case 84:salida=KEY_LEFT;break;
case 182:salida=KEY_DOWN;break;
case 232:salida=KEY_RIGHT;break;
default: salida=0;break;
}
return salida;
}
static struct input_dev *cap_keyboard;//estructura que define el dispositivo de entrada
static irqreturn_t irq_handler(int irq, void *dev_id){ //funcion que atiende las interrupciones y define las acciones a tomar
if(inb(FPGA_BASE)==anterior){ //condicional para deshabilitar la multiple lectura de una tecla
return IRQ_HANDLED;
}
else if(inb(FPGA_BASE)==85){ //condicional para evitar que se escriba algo del valor mandado por defecto del integrado
anterior=inb(FPGA_BASE);
return IRQ_HANDLED;
}
else if (inb(FPGA_BASE)==148){ //condicional para activacion de la tecla FN
input_sync(cap_keyboard);
anterior=inb(FPGA_BASE);
fn=1;
return IRQ_HANDLED;}
//condicional para evaluar la activacion de las teclas alt, alt gr, ctrl y shift
else if ((inb(FPGA_BASE)==137) || (inb(FPGA_BASE)==215) || (inb(FPGA_BASE)==10) || (inb(FPGA_BASE)==53)){
input_report_key(cap_keyboard,keydecode(inb(FPGA_BASE)),1);//funcion que detecta la tecla y la pone en 1 o 0 logico
input_sync(cap_keyboard); //sincronizar el buffer tty con la ultima tecla oprimida
anterior=inb(FPGA_BASE); //asignacion a la variable global de la ultima tecla oprimida
return IRQ_HANDLED; //retorno de interrupcion controlada
}
else if(fn!=1) { //condicional para detectar la tecla ya sea en modo normal o con combinacion de ctrl, alt o shift
input_report_key(cap_keyboard,keydecode(inb(FPGA_BASE)),1);
input_report_key(cap_keyboard,KEY_LEFTSHIFT,0);
input_report_key(cap_keyboard,KEY_RIGHTALT,0);
input_report_key(cap_keyboard,KEY_LEFTALT,0);
input_report_key(cap_keyboard,KEY_RIGHTCTRL,0);
input_report_key(cap_keyboard,keydecode(inb(FPGA_BASE)),0);
input_sync(cap_keyboard);
anterior=inb(FPGA_BASE);
return IRQ_HANDLED;}
//condicional que indica que hacer en el caso de haber oprimido FN y otra letra. La mayoria son numeros
else if ((inb(FPGA_BASE)==41) ||(inb(FPGA_BASE)==119) ||(inb(FPGA_BASE)==149) ||(inb(FPGA_BASE)==235) ||(inb(FPGA_BASE)==181) ||(inb(FPGA_BASE)==87) ||(inb(FPGA_BASE)==180) ||(inb(FPGA_BASE)==234) ||(inb(FPGA_BASE)==8) ||(inb(FPGA_BASE)==118) ||(inb(FPGA_BASE)==40)){
input_report_key(cap_keyboard,KEY_LEFTSHIFT,0);
input_report_key(cap_keyboard,KEY_RIGHTALT,0);
input_report_key(cap_keyboard,KEY_RIGHTCTRL,0);
input_report_key(cap_keyboard,KEY_LEFTALT,0);
input_report_key(cap_keyboard,keydecodefn(inb(FPGA_BASE)),1);
input_report_key(cap_keyboard,keydecodefn(inb(FPGA_BASE)),0);
input_sync(cap_keyboard);
fn=0;
anterior=inb(FPGA_BASE);
return IRQ_HANDLED;}
//condicional que indica que hacer en el caso de haber oprimido FN y otra letra. Estas son teclas que requieren de shift para ilustrarlas
else
{input_report_key(cap_keyboard,KEY_LEFTSHIFT,1);
input_report_key(cap_keyboard,KEY_RIGHTALT,0);
input_report_key(cap_keyboard,KEY_RIGHTCTRL,0);
input_report_key(cap_keyboard,KEY_LEFTALT,0);
input_report_key(cap_keyboard,keydecodefn(inb(FPGA_BASE)),1);
input_report_key(cap_keyboard,keydecodefn(inb(FPGA_BASE)),0);
input_report_key(cap_keyboard,KEY_LEFTSHIFT,0);
input_sync(cap_keyboard);
fn=0;
anterior=inb(FPGA_BASE);
return IRQ_HANDLED;}
return IRQ_HANDLED;
}
static int __init atakbd_init(void)//funcion de inicializacion del teclado
{
int i, error,res;
cap_keyboard = input_allocate_device(); // ubica memoria para el dispositivo de entrada
if (!cap_keyboard)
return -ENOMEM;
cap_keyboard->name = "CAP Keyboard"; //asignacion de datos del teclado
cap_keyboard->phys = "capkey/input0"; //direccion fisica
cap_keyboard->id.bustype = BUS_HOST;//tipo de bus
cap_keyboard->id.vendor = 0x0010;
cap_keyboard->id.product = 0x0001;
cap_keyboard->id.version = 0x001;
cap_keyboard->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
cap_keyboard->keycode = cap_keycode;//asignacion del arreglo del keycode
cap_keyboard->keycodesize = sizeof(unsigned char);
cap_keyboard->keycodemax = ARRAY_SIZE(cap_keycode);
for (i = 0; i <= 60; i++) { //funcion que ubica las 48 teclas (keycode) en memoria
set_bit(cap_keycode[i], cap_keyboard->keybit);
}
error = input_register_device(cap_keyboard);//indica al sistema el nuevo dispositivo de entrada
if (error) {
input_free_device(cap_keyboard);
return error;
}
irq = gpio_to_irq(FPGA_IRQ_PIN);//asigna el numero del irq al pin fisico del procesador
res = request_irq(irq, irq_handler, IRQF_DISABLED | IRQF_TRIGGER_RISING, "cap_keyboard", NULL); // asignar el valor del irq y la funcion que lo utiliza
return 0;
}
static void __exit atakbd_exit(void)
{
input_unregister_device(cap_keyboard);//libera los recursos utilizados por el dispositivo
free_irq(irq, NULL);
}
module_init(atakbd_init);
module_exit(atakbd_exit);

View File

@@ -0,0 +1,4 @@
#!/bin/sh
xc3sprog uart_teclado.bit
insmod cap_keyboard.ko
./daemon_keyboard &

View File

@@ -0,0 +1,49 @@
CC = mipsel-openwrt-linux-gcc
all: daemon_keyboard
DEBUG = -O3 -g0
COMMON_SOURCES = jz47xx_gpio.c jz47xx_mmap.c
H_SOURCES = jz47xx_gpio.h jz47xx_mmap.h
INCLUDE = -I.
WARNINGS= -Wcast-align -Wpacked -Wpadded -Wall
CCFLAGS = ${INCLUDE} ${DEBUG} ${WARNINGS}
LDFLAGS =
COMMON_OBJECTS = $(COMMON_SOURCES:.c=.o)
NANO_IP = 192.168.254.101
jz_init_sram: $(COMMON_OBJECTS)
$(CC) $(LDFLAGS) $(COMMON_OBJECTS) jz_init_sram.c -o jz_init_sram
daemon_keyboard: $(COMMON_OBJECTS)
$(CC) $(LDFLAGS) $(COMMON_OBJECTS) daemon_keyboard.c -o daemon_keyboard
jz_test_gpio: $(COMMON_OBJECTS)
$(CC) $(LDFLAGS) $(COMMON_OBJECTS) jz_test_gpio.c -o jz_test_gpio
enable_rx: $(COMMON_OBJECTS)
$(CC) $(LDFLAGS) $(COMMON_OBJECTS) enable_rx.c -o enable_rx
enable_irq: $(COMMON_OBJECTS)
$(CC) $(LDFLAGS) $(COMMON_OBJECTS) enable_irq.c -o enable_irq
.c.o:
$(CC) -c $(CCFLAGS) $< -o $@
upload: jz_init_sram jz_test_gpio
scp jz_test_gpio jz_init_sram root@$(NANO_IP):
clean:
rm -f *.o jz_init_sram jz_test_gpio enable_rx daemon_keyboard ${EXEC} *~ enable_irq
indent:
indent -bad -bap -nbc -bl -nce -i2 --no-tabs --line-length120 $(COMMON_SOURCES) $(H_SOURCES)

View File

@@ -0,0 +1,55 @@
#include <stdio.h>
#include <unistd.h>
#include "jz47xx_gpio.h"
#include "jz47xx_mmap.h"
#define CS2_PORT JZ_GPIO_PORT_B
#define CS2_PIN 26
#define RHR 0x00 /* Receive Holding Register */
#define THR 0x00 /* Receive Holding Register */
#define IER 0x01 /* Interrupt Enable Register */
#define FCR 0x02 /* FIFO control Register */
#define ISR 0x02 /* Interrupt Status Register */
#define LCR 0x03 /* Line control register */
#define MCR 0x04 /* Modem Control Register */
#define LSR 0x05 /* Line Status Register */
#define MSR 0x06 /* Modem Status Register */
#define SCR 0x07 /* Scratch pad Register */
/* This two offsets are used for defining the baud rate */
#define DIVLSB 0x00 /* Divisor LSB latch address */
#define DIVMSB 0x01 /* Divisor MSB Latch address */
int main () {
JZ_PIO *pio;
unsigned char *virt_addr, get_tecla, in, in2=0, in1=0;
int i;
pio = jz_gpio_map (CS2_PORT);
jz_gpio_as_func (pio, CS2_PIN, 0);
virt_addr = (int *) jz_mmap (0x13010000) + 0x18;
if (*virt_addr != 0xFFF7700)
{ // 0 WS, 8 bits
*virt_addr = 0xFFF7700;
// printf ("Configuring CS2 8 bits \n");
}
else
printf ("CS3, already configured\n");
virt_addr = (JZ_REG *) jz_mmap (0x15000000);
virt_addr[LCR]=0x80;//registros de configuracion de UART
virt_addr[DIVMSB]=0x00;
virt_addr[DIVLSB]=0x0C;
virt_addr[LCR]=0x03;
virt_addr[IER]= 0x01;
while (1){
virt_addr[THR]=0x06;
usleep(60000);
//printf("%d\n",virt_addr[RHR]);
usleep(60000);
}
}

View File

@@ -0,0 +1,142 @@
#include <stdio.h>
#include <unistd.h>
#include "jz47xx_gpio.h"
#include "jz47xx_mmap.h"
#define CS2_PORT JZ_GPIO_PORT_B
#define CS2_PIN 26
#define RHR 0x00 /* Receive Holding Register */
#define THR 0x00 /* Receive Holding Register */
#define IER 0x01 /* Interrupt Enable Register */
#define FCR 0x02 /* FIFO control Register */
#define ISR 0x02 /* Interrupt Status Register */
#define LCR 0x03 /* Line control register */
#define MCR 0x04 /* Modem Control Register */
#define LSR 0x05 /* Line Status Register */
#define MSR 0x06 /* Modem Status Register */
#define SCR 0x07 /* Scratch pad Register */
/* This two offsets are used for defining the baud rate */
#define DIVLSB 0x00 /* Divisor LSB latch address */
#define DIVMSB 0x01 /* Divisor MSB Latch address */
#include <stdio.h>
#include <unistd.h>
#include "jz47xx_gpio.h"
#include "jz47xx_mmap.h"
#define CS2_PORT JZ_GPIO_PORT_B
#define CS2_PIN 26
#define RHR 0x00 /* Receive Holding Register */
#define THR 0x00 /* Receive Holding Register */
#define IER 0x01 /* Interrupt Enable Register */
#define FCR 0x02 /* FIFO control Register */
#define ISR 0x02 /* Interrupt Status Register */
#define LCR 0x03 /* Line control register */
#define MCR 0x04 /* Modem Control Register */
#define LSR 0x05 /* Line Status Register */
#define MSR 0x06 /* Modem Status Register */
#define SCR 0x07 /* Scratch pad Register */
/* This two offsets are used for defining the baud rate */
#define DIVLSB 0x00 /* Divisor LSB latch address */
#define DIVMSB 0x01 /* Divisor MSB Latch address */
int main () {
JZ_PIO *pio;
char *virt_addr, get_tecla, in, in2=0, in1=0;
int i;
pio = jz_gpio_map (CS2_PORT);
jz_gpio_as_func (pio, CS2_PIN, 0);
virt_addr = (int *) jz_mmap (0x13010000) + 0x18;
if (*virt_addr != 0xFFF7700)
{ // 0 WS, 8 bits
*virt_addr = 0xFFF7700;
// printf ("Configuring CS2 8 bits \n");
}
else
printf ("CS3, already configured\n");
virt_addr = (JZ_REG *) jz_mmap (0x15000000);
virt_addr[LCR]=0x80;//registros de configuracion de UART
virt_addr[DIVMSB]=0x00;
virt_addr[DIVLSB]=0x0C;
virt_addr[LCR]=0x03;
virt_addr[IER]= 0x01;
virt_addr[THR]=0x0f;//inicio de estados
usleep(20000);
virt_addr[THR]=0x0E;
usleep(20000);
virt_addr[THR]=0x01;
usleep(20000);
virt_addr[THR]=0x01;
usleep(20000);
for (i=0;i<48;i++)//registros de configuracion
{virt_addr[THR]=0x28;
usleep(20000);}
for (i=0;i<48;i++)
{virt_addr[THR]=0x4A;
usleep(20000);}
for (i=0;i<48;i++)
{virt_addr[THR]=0x52;
usleep(20000);}
for (i=0;i<48;i++)
{virt_addr[THR]=0x14;
usleep(20000);}
for (i=0;i<48;i++)
{virt_addr[THR]=0xA6;
usleep(20000);}
virt_addr[THR]=0x11;
usleep(20000);
virt_addr[THR]=0x00;
usleep(20000);
virt_addr[THR]=0x64;
usleep(20000);
virt_addr[THR]=0x00;
usleep(20000);
virt_addr[THR]=0x6c;
usleep(20000);
virt_addr[THR]=0x00;
usleep(20000);
virt_addr[THR]=0x00;//fin de registros de configuracion
usleep(20000);
virt_addr[THR]=0x04;
usleep(20000);
virt_addr[THR]=0x04;
usleep(20000);
virt_addr[THR]=0x0f;
usleep(20000);
virt_addr[THR]=0x0e;//fin de estados finitos
while (1){
//recepcion de los registros enviados por el integrado
virt_addr[THR]=0x06;
in=virt_addr[THR];
usleep(120000);
}
}

View File

@@ -0,0 +1,40 @@
/*
JZ47xx test gpio
Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com
Carlos Camargo cicamargoba@unal.edu.co
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <stdio.h>
#include <unistd.h>
#include "jz47xx_gpio.h"
#define IRQ_PORT JZ_GPIO_PORT_C
#define IRQ_PIN 15
int
main ()
{
JZ_PIO *pio = jz_gpio_map (IRQ_PORT);
if (!pio)
return -1;
jz_gpio_as_irq (pio, IRQ_PIN);
return 0;
}

View File

@@ -0,0 +1,40 @@
/*
JZ47xx test gpio
Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com
Carlos Camargo cicamargoba@unal.edu.co
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <stdio.h>
#include <unistd.h>
#include "jz47xx_gpio.h"
#define RXD_PORT JZ_GPIO_PORT_D
#define RXD_PIN 26
int
main ()
{
JZ_PIO *pio = jz_gpio_map (RXD_PORT);
if (!pio)
return -1;
jz_gpio_as_func (pio, RXD_PIN, 1);
return 0;
}

View File

@@ -0,0 +1,119 @@
/*
JZ47xx GPIO at userspace
Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <jz47xx_gpio.h>
#include <jz47xx_mmap.h>
#define JZ_GPIO_BASE 0x10010000
void
jz_gpio_as_output (JZ_PIO * pio, unsigned int o)
{
pio->PXFUNC = (1 << (o));
pio->PXSELC = (1 << (o));
pio->PXDIRS = (1 << (o));
}
void
jz_gpio_as_input (JZ_PIO * pio, unsigned int o)
{
pio->PXFUNC = (1 << (o));
pio->PXSELC = (1 << (o));
pio->PXDIRC = (1 << (o));
}
void
jz_gpio_as_irq (JZ_PIO * pio, unsigned int o)
{
pio->PXFUNC = (1 << (o));
pio->PXSELS = (1 << (o));
pio->PXDIRC = (1 << (o));
}
void
jz_gpio_set_pin (JZ_PIO * pio, unsigned int o)
{
pio->PXDATS = (1 << (o));
}
void
jz_gpio_clear_pin (JZ_PIO * pio, unsigned int o)
{
pio->PXDATC = (1 << (o));
}
void
jz_gpio_out (JZ_PIO * pio, unsigned int o, unsigned int val)
{
if (val == 0)
pio->PXDATC = (1 << (o));
else
pio->PXDATS = (1 << (o));
}
unsigned int
jz_gpio_get_pin (JZ_PIO * pio, unsigned int o)
{
return (pio->PXPIN & (1 << o)) ? 1 : 0;
}
int
jz_gpio_as_func (JZ_PIO * pio, unsigned int o, int func)
{
switch (func)
{
case 0:
pio->PXFUNS = (1 << o);
pio->PXTRGC = (1 << o);
pio->PXSELC = (1 << o);
pio->PXPES = (1 << o);
return 1;
case 1:
pio->PXFUNS = (1 << o);
pio->PXTRGC = (1 << o);
pio->PXSELS = (1 << o);
pio->PXPES = (1 << o);
return 1;
case 2:
pio->PXFUNS = (1 << o);
pio->PXTRGS = (1 << o);
pio->PXSELC = (1 << o);
pio->PXPES = (1 << o);
return 1;
}
return 0;
}
JZ_PIO *
jz_gpio_map (int port)
{
JZ_PIO *pio;
pio = (JZ_PIO *) jz_mmap (JZ_GPIO_BASE);
pio = (JZ_PIO *) ((unsigned int) pio + port * 0x100);
return pio;
}

View File

@@ -0,0 +1,84 @@
/*
JZ47xx GPIO at userspace
Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef __jz47xx_gpio_h__
#define __jz47xx_gpio_h__
#define JZ_GPIO_PORT_A 0
#define JZ_GPIO_PORT_B 1
#define JZ_GPIO_PORT_C 2
#define JZ_GPIO_PORT_D 3
typedef volatile unsigned int JZ_REG; /* Hardware register definition */
typedef struct _JZ_PIO
{
JZ_REG PXPIN; /* PIN Level Register */
JZ_REG Reserved0;
JZ_REG Reserved1;
JZ_REG Reserved2;
JZ_REG PXDAT; /* Port Data Register */
JZ_REG PXDATS; /* Port Data Set Register */
JZ_REG PXDATC; /* Port Data Clear Register */
JZ_REG Reserved3;
JZ_REG PXIM; /* Interrupt Mask Register */
JZ_REG PXIMS; /* Interrupt Mask Set Reg */
JZ_REG PXIMC; /* Interrupt Mask Clear Reg */
JZ_REG Reserved4;
JZ_REG PXPE; /* Pull Enable Register */
JZ_REG PXPES; /* Pull Enable Set Reg. */
JZ_REG PXPEC; /* Pull Enable Clear Reg. */
JZ_REG Reserved5;
JZ_REG PXFUN; /* Function Register */
JZ_REG PXFUNS; /* Function Set Register */
JZ_REG PXFUNC; /* Function Clear Register */
JZ_REG Reserved6;
JZ_REG PXSEL; /* Select Register */
JZ_REG PXSELS; /* Select Set Register */
JZ_REG PXSELC; /* Select Clear Register */
JZ_REG Reserved7;
JZ_REG PXDIR; /* Direction Register */
JZ_REG PXDIRS; /* Direction Set Register */
JZ_REG PXDIRC; /* Direction Clear Register */
JZ_REG Reserved8;
JZ_REG PXTRG; /* Trigger Register */
JZ_REG PXTRGS; /* Trigger Set Register */
JZ_REG PXTRGC; /* Trigger Set Register */
JZ_REG Reserved9;
JZ_REG PXFLG; /* Port Flag Register */
JZ_REG PXFLGC; /* Port Flag clear Register */
} JZ_PIO, *PJZ_PIO;
void jz_gpio_as_output (JZ_PIO * pio, unsigned int o);
void jz_gpio_as_input (JZ_PIO * pio, unsigned int o);
void jz_gpio_set_pin (JZ_PIO * pio, unsigned int o);
void jz_gpio_clear_pin (JZ_PIO * pio, unsigned int o);
void jz_gpio_out (JZ_PIO * pio, unsigned int o, unsigned int val);
unsigned int jz_gpio_get_pin (JZ_PIO * pio, unsigned int o);
int jz_gpio_as_func (JZ_PIO * pio, unsigned int o, int func);
JZ_PIO *jz_gpio_map (int port);
#endif

View File

@@ -0,0 +1,64 @@
/*
* JZ47xx GPIO lines
*
* Written 2010 by Andres Calderon andres.calderon@emqbit.com
*/
#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <jz47xx_mmap.h>
void *
jz_mmap (off_t address)
{
int fd;
void *pio;
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC)) == -1)
{
fprintf (stderr, "Cannot open /dev/mem.\n");
return 0;
}
pio = (void *) mmap (0, getpagesize (), PROT_READ | PROT_WRITE, MAP_SHARED, fd, address);
if (pio == (void *) -1)
{
fprintf (stderr, "Cannot mmap.\n");
return 0;
}
return pio;
}
void *
jz_fpga_map (off_t address)
{
int fd;
void *fpga;
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC)) == -1)
{
fprintf (stderr, "Cannot open /dev/mem.\n");
return 0;
}
fpga = (void *) mmap (0, FPGA_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, address);
if (fpga == (void *) -1)
{
fprintf (stderr, "Cannot mmap.\n");
return 0;
}
return fpga;
}

View File

@@ -0,0 +1,17 @@
/*
* JZ47xx GPIO lines
*
* Written 2010 by Andres Calderon andres.calderon@emqbit.com
*/
#ifndef __jz47xx_mmap_h__
#define __jz47xx_mmap_h__
#include <sys/mman.h>
#define FPGA_SIZE (1 << 15)
void *jz_mmap (off_t address);
void *jz_fpga_map (off_t address);
#endif

View File

@@ -0,0 +1,72 @@
/*
JZ47xx test gpio
Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com
Carlos Camargo cicamargoba@unal.edu.co
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <stdio.h>
#include <unistd.h>
#include "jz47xx_gpio.h"
//#define TEST_PORT JZ_GPIO_PORT_C
//#define TEST_PIN 17
int
main (int argc,char *argv[])
{
int TEST_PORT, TEST_PIN;
if(argc != 3){
fprintf(stderr,"\nUsage: %s TEST_PIN_PORT(A=0, B=1, C=2, D=3) TEST_PIN \n",argv[0]);
}
TEST_PORT = ;
TEST_PIN = ;
JZ_PIO *pio = jz_gpio_map (TEST_PORT);//declara un puntero que mapea la dirección fisica del controlador que está dentro del chip. (mapeo de la memoria fisica)
if (!pio)
return -1;
jz_gpio_as_output (pio, TEST_PIN);//define el pin, para que sea una salida, pasa la direccion de memoria en donde está el controlador y el pin. Está declarado en el archivojz47xx_gpio.c la función as_func es similar a la que se asigna en el kernel. Sin necesidad del driver. (Espacio de usuario). Utilizan interfaces diferentes. Los registros tienen que moverse físicamente. En el espacio de usuario es más complicado y pueden tener mucha latencia. En el kernel se ejecuta sin tanta latencia.
//mirar diferencias entre espacio de kernel y espacio de usuario.
//otra forma es hacerlo por parte de un intérprete.
// tener una librería básica que haga las funciones y a través de un lenguaje de muy alto nivel se puede interpretar los comandos...
//Lenguaje -LUA-
/*
intérprete de alto nivel desarrollado por unos brasileros.
*/
int tg = 1;
while (1)
{
jz_gpio_out (pio, TEST_PIN, tg);
printf ("[%d]", jz_gpio_get_pin (pio, TEST_PIN));
fflush (stdout);
usleep (500 * 1000);
tg = !tg;
}
return 0;
}