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:
88
cap_keyboard/logic/UART/Makefile
Normal file
88
cap_keyboard/logic/UART/Makefile
Normal 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
|
||||
1319
cap_keyboard/logic/UART/uart.v
Normal file
1319
cap_keyboard/logic/UART/uart.v
Normal file
File diff suppressed because it is too large
Load Diff
35
cap_keyboard/logic/UART/uart_peripheral.ucf
Normal file
35
cap_keyboard/logic/UART/uart_peripheral.ucf
Normal 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";
|
||||
87
cap_keyboard/logic/UART/uart_peripheral.v
Normal file
87
cap_keyboard/logic/UART/uart_peripheral.v
Normal 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
|
||||
185
cap_keyboard/src/8250/8250_fpga.c
Normal file
185
cap_keyboard/src/8250/8250_fpga.c
Normal 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);
|
||||
23
cap_keyboard/src/8250/Makefile
Normal file
23
cap_keyboard/src/8250/Makefile
Normal 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) $< > $@
|
||||
|
||||
|
||||
|
||||
21
cap_keyboard/src/teclado/Makefile
Normal file
21
cap_keyboard/src/teclado/Makefile
Normal 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) $< > $@
|
||||
|
||||
|
||||
|
||||
283
cap_keyboard/src/teclado/cap_keyboard.c
Normal file
283
cap_keyboard/src/teclado/cap_keyboard.c
Normal 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);
|
||||
4
cap_keyboard/src/teclado/script.sh
Normal file
4
cap_keyboard/src/teclado/script.sh
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
xc3sprog uart_teclado.bit
|
||||
insmod cap_keyboard.ko
|
||||
./daemon_keyboard &
|
||||
49
cap_keyboard/src/user_space/Makefile
Normal file
49
cap_keyboard/src/user_space/Makefile
Normal 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)
|
||||
55
cap_keyboard/src/user_space/daemon_keyboard.c
Normal file
55
cap_keyboard/src/user_space/daemon_keyboard.c
Normal 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);
|
||||
}
|
||||
}
|
||||
142
cap_keyboard/src/user_space/daemons_keyboard.c
Normal file
142
cap_keyboard/src/user_space/daemons_keyboard.c
Normal 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);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
40
cap_keyboard/src/user_space/enable_irq.c
Normal file
40
cap_keyboard/src/user_space/enable_irq.c
Normal 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;
|
||||
}
|
||||
40
cap_keyboard/src/user_space/enable_rx.c
Normal file
40
cap_keyboard/src/user_space/enable_rx.c
Normal 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;
|
||||
}
|
||||
119
cap_keyboard/src/user_space/jz47xx_gpio.c
Normal file
119
cap_keyboard/src/user_space/jz47xx_gpio.c
Normal 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;
|
||||
}
|
||||
84
cap_keyboard/src/user_space/jz47xx_gpio.h
Normal file
84
cap_keyboard/src/user_space/jz47xx_gpio.h
Normal 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
|
||||
64
cap_keyboard/src/user_space/jz47xx_mmap.c
Normal file
64
cap_keyboard/src/user_space/jz47xx_mmap.c
Normal 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;
|
||||
}
|
||||
|
||||
17
cap_keyboard/src/user_space/jz47xx_mmap.h
Normal file
17
cap_keyboard/src/user_space/jz47xx_mmap.h
Normal 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
|
||||
72
cap_keyboard/src/user_space/jz_test_gpio.c
Normal file
72
cap_keyboard/src/user_space/jz_test_gpio.c
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user