📄 skyeye_mach_at91.c
字号:
/* skyeye_mach_at91.c - define machine at91 for skyeye Copyright (C) 2003 Skyeye Develop Group for help please send mail to <skyeye-developer@lists.gro.clinux.org> 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 *//* * 06/15/2005 rewrite interrupt simulation * walimis <wlm@student.dlut.edu.cn> * * 3/24/2003 init this file. * add machine at91's function.Most taken from original armio.c * include: at91_mach_init, at91_io_do_cycle * at91_io_read_word, at91_io_write_word * walimis <wlm@student.dlut.edu.cn> * *3/24/2003 chenyu <chenyu-tmlinux@hpclab.cs.tsinghua.edu.cn> has done the * necessary work to armio.c * */#include "armdefs.h"#include "at91.h"#define DEBUG 0#if DEBUG#define DBG_PRINT(a...) fprintf(stderr, ##a)#else#define DBG_PRINT(a...)#endif//chy 2005-07-28//zzc:2005-1-1#ifdef __CYGWIN__#include <time.h>//teawater add DBCT_TEST_SPEED 2005.10.04---------------------------------------/*struct timeval{ int tv_sec; int tv_usec;};*///AJ2D--------------------------------------------------------------------------#endif/* 2007-01-18 added by Anthony Lee : for new uart device frame */#include "skyeye_uart.h"extern unsigned int Pen_buffer[8];typedef struct at91_timer_s{ ARMword ccr; ARMword cmr; ARMword cv; ARMword ra; ARMword rb; ARMword rc; ARMword sr; ARMword ier; ARMword idr; ARMword imr;}at91_timer_t;typedef struct at91_io{ ARMword syscon; /* System control */ ARMword sysflg; /* System status flags */ /* rewrite interrupt code. * */ u32 ivr; u32 fvr; u32 isr; u32 ipr; u32 imr; u32 cisr; u32 iecr; u32 idcr; u32 iccr; u32 iscr; u32 eoicr; u32 spu; ARMword tcd[3]; /* Timer/counter data */ ARMword tcd_reload[3]; /* Last value written */ at91_timer_t tc_channel[3]; ARMword uartdr; /* Receive data register */ ARMword lcdcon; /* LCD control */ ARMword lcd_limit; /* 0xc0000000 <= LCD buffer < lcd_limi t */ ARMword ts_buffer[8]; ARMword ts_addr_begin; ARMword ts_addr_end;} at91_io_t;static at91_io_t at91_io;#define io at91_iostatic voidat91_update_int (ARMul_State * state){ ARMword requests = io.ipr & io.imr; state->NfiqSig = (requests & 0x00001) ? LOW : HIGH; state->NirqSig = (requests & 0x3fffe) ? LOW : HIGH;}/* new added functions * */static voidat91_set_intr (u32 interrupt){ io.ipr |= (1 << interrupt);}static intat91_pending_intr (u32 interrupt){ return ((io.ipr & (1 << interrupt)));}static voidat91_update_intr (void *mach){ struct machine_config *mc = (struct machine_config *) mach; ARMul_State *state = (ARMul_State *) mc->state; ARMword requests = io.ipr & io.imr; state->NfiqSig = (requests & 0x00001) ? LOW : HIGH; state->NirqSig = (requests & 0x3fffe) ? LOW : HIGH;}static intat91_mem_read_byte (void *mach, u32 addr, u32 * data){ struct machine_config *mc = (struct machine_config *) mach; ARMul_State *state = (ARMul_State *) mc->state; *data = (u32) mem_read_char (state, addr);}static intat91_mem_write_byte (void *mach, u32 addr, u32 data){ struct machine_config *mc = (struct machine_config *) mach; ARMul_State *state = (ARMul_State *) mc->state; mem_write_char (state, addr, (char) data);}static voidat91_io_reset (void * curr_state){ ARMul_State * state = (ARMul_State *)curr_state; io.syscon = 0; io.sysflg = URXFE; io.tcd[0] = 0xffff; io.tcd[1] = 0xffff; io.tcd[2] = 0xffff; io.tcd_reload[0] = 0xffff; io.tcd_reload[1] = 0xffff; io.tcd_reload[2] = 0xffff; io.uartdr = 0; io.lcdcon = 0; io.lcd_limit = 0; io.ts_addr_begin = 0xff00b000; io.ts_addr_end = 0xff00b01f;}static ARMword rpr;int rcr;/*at91 io_do_cycle*/voidat91_io_do_cycle (void * curr_state){ int t; ARMul_State * state = curr_state; for (t = 0; t < 3; t++) { if (io.tcd[t] == 0) { if (io.syscon & (t ? TC2M : TC1M)) { io.tcd[t] = io.tcd_reload[t]; } else { io.tcd[t] = 0xffff; } at91_set_intr (t ? IRQ_TC2 : IRQ_TC1); at91_update_int (state); io.tc_channel[2].sr |= 0x10; /* Set CPCS bit of SR */ } else { io.tcd[t]--; if(io.tcd[t] == 0x1000){ io.tc_channel[t].sr |= 0x10; /* Set CPCS bit of SR */ } } } if (rcr > 0 && !(io.ipr & IRQ_USART0)) { /* 2007-01-18 modified by Anthony Lee : for new uart device frame */ struct timeval tv; unsigned char buf[16]; int n, i; tv.tv_sec = 0; tv.tv_usec = 0; if((n = skyeye_uart_read(-1, buf, rcr > sizeof (buf) ? sizeof (buf) : rcr, &tv, NULL)) > 0) { for (i = 0; i < n; i++, rcr--, rpr++) mem_write_char (state, rpr, buf[i]); if (rcr == 0) io.sysflg &= ~URXFE; at91_set_intr (IRQ_USART0); at91_update_int (state); } } /* if (rcr > 0 && ... */#ifndef NO_LCD if (!(io.ipr & IRQ_EXT1)) { //if now has no ts interrupt,then query if (Pen_buffer[6] == 1) { //should trigger a interrupt *(io.ts_buffer + 0) = Pen_buffer[0]; *(io.ts_buffer + 1) = Pen_buffer[1]; *(io.ts_buffer + 4) = Pen_buffer[4]; *(io.ts_buffer + 6) = Pen_buffer[6]; at91_set_intr (IRQ_EXT1); Pen_buffer[6] = 0; } }#endif at91_update_int (state);}/* * * Atmel serial support for uClinux console. * */static char *uart_reg[] = { "CR", "MR", "IER", "IDR", "IMR", "CSR", "RHR", "THR", "BRGR", "RTOR", "TTGR", "RES1", "RPR", "RCR", "TPR", "TCR",};static ARMworduart_read (ARMul_State * state, ARMword addr){ ARMword data; switch ((addr & 0xfff) >> 2) { case 0xd: // RCR data = rcr; break; case 0xf: // TCR data = 0; break; case 0x5: // CSR data = (1 << 9) | (1 << 1) | /* always empty and ready */ (rcr ? ((1 << 3) | (1 << 0)) : 0); break; case 0x0: // CR case 0x1: // MR case 0x2: // IER case 0x3: // IDR case 0x4: // IMR case 0x6: // RHR case 0x7: // THR case 0x8: // BRGR case 0x9: // RTOR case 0xa: // TTGR case 0xb: // RES1 case 0xc: // RPR case 0xe: // TPR DBG_PRINT ("uart_read(%s=0x%08x)\n", uart_reg[(addr & 0xfff) >> 2], addr); break; default: fprintf(stderr, "IO erro in %s, addr=0x%x\n", __FUNCTION__, addr);// skyeye_exit(-1); } return (data);}static voiduart_write (ARMul_State * state, ARMword addr, ARMword data){ static ARMword tx_buf = 0; DBG_PRINT ("uart_write(0x%x, 0x%x)\n", (addr & 0xfff) >> 2, data); switch ((addr & 0xfff) >> 2) { case 0x0: // CR case 0x3: // IDR case 0x9: // RTOR case 0x2: // IER break; case 0x1: // MR case 0x4: // IMR case 0x5: // CSR case 0x6: // RHR DBG_PRINT ("uart_write(%s=0x%x) = 0x%08x\n", uart_reg[(addr & 0xfff) >> 2], addr, data); break; case 0x7: // THR { char c = data; /* 2007-01-18 modified by Anthony Lee : for new uart device frame */ skyeye_uart_write(-1, &c, 1, NULL); } //printf("%c", data); fflush(stdout); break; case 0x8: // BRGR case 0xa: // TTGR case 0xb: // RES1 DBG_PRINT ("uart_write(%s=0x%x) = 0x%08x\n", uart_reg[(addr & 0xfff) >> 2], addr, data); break; case 0xd: // RCR rcr = data; if (rcr == 0) io.sysflg &= ~URXFE; else io.sysflg |= URXFE; break; case 0xc: // RPR DBG_PRINT ("uart_write(%s=0x%x) = 0x%08x\n", uart_reg[(addr & 0xfff) >> 2], addr, data);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -