Skip to content

Commit

Permalink
Merge pull request RT-Thread#805 from parai/master
Browse files Browse the repository at this point in the history
[bsp] x86: keyboad input bug fix
  • Loading branch information
BernardXiong authored Aug 16, 2017
2 parents a0ec48d + eb5ea94 commit 1bfdc7d
Show file tree
Hide file tree
Showing 10 changed files with 1,265 additions and 129 deletions.
1 change: 1 addition & 0 deletions bsp/x86/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ all:floppy.img

clean:
scons -c clean
rm -fr build rtthread*

floppy.img:
wget https://github.com/bajdcc/tinix/raw/master/floppy.img
Expand Down
78 changes: 37 additions & 41 deletions bsp/x86/drivers/console.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,13 @@

#include <bsp.h>


//#include "serial.h"

static unsigned addr_6845;
static rt_uint16_t *crt_buf;
static rt_int16_t crt_pos;

//extern void rt_serial_init(void);
extern char rt_keyboard_getc(void);
//extern char rt_serial_getc(void);
extern void init_keyboard();
extern void rt_keyboard_isr(void);
extern rt_bool_t rt_keyboard_getc(char* c);

static void rt_console_putc(int c);

Expand Down Expand Up @@ -217,39 +214,38 @@ static rt_size_t rt_console_read(rt_device_t dev, rt_off_t pos, void* buffer, rt
static void rt_console_isr(int vector, void* param)
{
char c;
rt_bool_t ret;
rt_base_t level;

while(1)
{
c = rt_keyboard_getc();

if(c == 0)
{
break;
}
else if(c > 0)
{
/* disable interrupt */
level = rt_hw_interrupt_disable();

/* save character */
rx_buffer[save_index] = c;
save_index ++;
if (save_index >= CONSOLE_RX_BUFFER_SIZE)
save_index = 0;

/* if the next position is read index, discard this 'read char' */
if (save_index == read_index)
{
read_index ++;
if (read_index >= CONSOLE_RX_BUFFER_SIZE)
read_index = 0;
}

/* enable interrupt */
rt_hw_interrupt_enable(level);
}
}
rt_keyboard_isr();

ret = rt_keyboard_getc(&c);
if(ret == RT_FALSE)
{
/* do nothing */
}
else
{
/* disable interrupt */
level = rt_hw_interrupt_disable();

/* save character */
rx_buffer[save_index] = c;
save_index ++;
if (save_index >= CONSOLE_RX_BUFFER_SIZE)
save_index = 0;

/* if the next position is read index, discard this 'read char' */
if (save_index == read_index)
{
read_index ++;
if (read_index >= CONSOLE_RX_BUFFER_SIZE)
read_index = 0;
}

/* enable interrupt */
rt_hw_interrupt_enable(level);
}

/* invoke callback */
if (console_device.rx_indicate != RT_NULL)
Expand All @@ -258,18 +254,17 @@ static void rt_console_isr(int vector, void* param)

/* get rx length */
rx_length = read_index > save_index ?
CONSOLE_RX_BUFFER_SIZE - read_index + save_index :
save_index - read_index;
CONSOLE_RX_BUFFER_SIZE - read_index + save_index :
save_index - read_index;

// rt_kprintf("\r\nrx_length %d\r\n", rx_length);
if(rx_length > 0)
{
console_device.rx_indicate(&console_device, rx_length);
}
}
else
{
// rt_kprintf("\r\nconsole_device.rx_indicate == RT_NULL\r\n");

}
}

Expand All @@ -280,6 +275,7 @@ static void rt_console_isr(int vector, void* param)
void rt_hw_console_init(void)
{
rt_cga_init();
init_keyboard();

/* install keyboard isr */
rt_hw_interrupt_install(INTKEYBOARD, rt_console_isr, RT_NULL, "kbd");
Expand Down
187 changes: 187 additions & 0 deletions bsp/x86/drivers/dma.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
#ifndef _DMA_H
#define _DMA_H


#define MAX_DMA_CHANNELS 8

/* 8237 DMA controllers */
#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */
#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */

/* DMA controller registers */
#define DMA1_CMD_REG 0x08 /* command register (w) */
#define DMA1_STAT_REG 0x08 /* status register (r) */
#define DMA1_REQ_REG 0x09 /* request register (w) */
#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */
#define DMA1_MODE_REG 0x0B /* mode register (w) */
#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */
#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */
#define DMA1_RESET_REG 0x0D /* Master Clear (w) */
#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */
#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */

#define DMA2_CMD_REG 0xD0 /* command register (w) */
#define DMA2_STAT_REG 0xD0 /* status register (r) */
#define DMA2_REQ_REG 0xD2 /* request register (w) */
#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */
#define DMA2_MODE_REG 0xD6 /* mode register (w) */
#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */
#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */
#define DMA2_RESET_REG 0xDA /* Master Clear (w) */
#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */
#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */

#define DMA_ADDR_0 0x00 /* DMA address registers */
#define DMA_ADDR_1 0x02
#define DMA_ADDR_2 0x04
#define DMA_ADDR_3 0x06
#define DMA_ADDR_4 0xC0
#define DMA_ADDR_5 0xC4
#define DMA_ADDR_6 0xC8
#define DMA_ADDR_7 0xCC

#define DMA_CNT_0 0x01 /* DMA count registers */
#define DMA_CNT_1 0x03
#define DMA_CNT_2 0x05
#define DMA_CNT_3 0x07
#define DMA_CNT_4 0xC2
#define DMA_CNT_5 0xC6
#define DMA_CNT_6 0xCA
#define DMA_CNT_7 0xCE

#define DMA_PAGE_0 0x87 /* DMA page registers */
#define DMA_PAGE_1 0x83
#define DMA_PAGE_2 0x81
#define DMA_PAGE_3 0x82
#define DMA_PAGE_5 0x8B
#define DMA_PAGE_6 0x89
#define DMA_PAGE_7 0x8A

#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */
#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */
#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */

/*
* 启用指定的DMA通道
*/
static __inline__ void EnableDma(unsigned int dmanr)
{
if (dmanr<=3)
outb(dmanr, DMA1_MASK_REG);
else
outb(dmanr & 3, DMA2_MASK_REG);
}

/*
* 禁用指定的DMA通道
*/
static __inline__ void DisableDma(unsigned int dmanr)
{
if (dmanr<=3)
outb(dmanr | 4, DMA1_MASK_REG);
else
outb((dmanr & 3) | 4, DMA2_MASK_REG);
}

/*
* 清空DMA 晶体计数器
*/
static __inline__ void ClearDmaFF(unsigned int dmanr)
{
if (dmanr<=3)
outb(0, DMA1_CLEAR_FF_REG);
else
outb(0, DMA2_CLEAR_FF_REG);
}

/*
* 清空DMA 晶体计数器
*/
static __inline__ void SetDmaMode(unsigned int dmanr, char mode)
{
if (dmanr<=3)
outb(mode | dmanr, DMA1_MODE_REG);
else
outb(mode | (dmanr&3), DMA2_MODE_REG);
}

/*
* 设定DMA 页面寄存器
*/
static __inline__ void SetDmaPage(unsigned int dmanr, char pagenr)
{
switch(dmanr) {
case 0:
outb(pagenr, DMA_PAGE_0);
break;
case 1:
outb(pagenr, DMA_PAGE_1);
break;
case 2:
outb(pagenr, DMA_PAGE_2);
break;
case 3:
outb(pagenr, DMA_PAGE_3);
break;
case 5:
outb(pagenr & 0xfe, DMA_PAGE_5);
break;
case 6:
outb(pagenr & 0xfe, DMA_PAGE_6);
break;
case 7:
outb(pagenr & 0xfe, DMA_PAGE_7);
break;
}
}


/*
* 设定DMA 传输高速缓冲区地址
*/
static __inline__ void SetDmaAddr(unsigned int dmanr, unsigned int a)
{
SetDmaPage(dmanr, a>>16);
if (dmanr <= 3) {
outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
} else {
outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
}
}


/*
* 设定DMA 传输块数
*/
static __inline__ void SetDmaCount(unsigned int dmanr, unsigned int count)
{
count--;
if (dmanr <= 3) {
outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
} else {
outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
}
}


/*
* 获得DMA 传输剩余块数
*/
static __inline__ int GetDmaResidue(unsigned int dmanr)
{
unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
: ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;

/* using short to get 16-bit wrap around */
unsigned short count;
count = 1 + inb(io_port);
count += inb(io_port) << 8;
return (dmanr<=3)? count : (count<<1);
}

#endif

Loading

0 comments on commit 1bfdc7d

Please sign in to comment.