📄 skyeye_mach_lpc2210.c
字号:
/* skyeye_mach_lpc2210.c - define machine lpc2210 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 *//* * 10/02/2007 Add support for RTEMS/lpc2210 bsp. Be care that the clock in * skyeye lpc2210 support is 1000 times faster than the real hardware * clock * rayx <rayx.cn@gmail.com> * 3/24/2003 init this file. * add machine lpc's function.Most taken from original armio.c * include: lpc_mach_init, lpc_io_do_cycle * lpc_io_read_word, lpc_io_write_word * walimis <walimi@peoplemail.com.cn> * *3/24/2003 chenyu <chenyu-tmlinux@hpclab.cs.tsinghua.edu.cn> has done the * necessary work to armio.c * */#include "armdefs.h"#include "lpc.h"//#include "skyeye-ne2k.h"/* 2007-01-18 added by Anthony Lee : for new uart device frame */#include "skyeye_uart.h"#define TC_DIVISOR (50) /* Set your BogoMips here :) may move elsewhere*/#define DEBUG 0#if DEBUG#define DBG_PRINT(a...) fprintf(stderr,##a)#else#define DBG_PRINT(a...)#endiftypedef struct timer{ ARMword ir; ARMword tcr; ARMword tc; ARMword pr; ARMword pc; ARMword mcr; ARMword mr0; ARMword mr1; ARMword mr2; ARMword mr3; ARMword ccr; ARMword cr0; ARMword cr1; ARMword cr2; ARMword cr3; ARMword emr;} lpc2210_timer_t;typedef struct uart{ ARMword rbr; ARMword thr; ARMword ier; ARMword iir; ARMword fcr; ARMword lcr; ARMword lsr; ARMword msr; ARMword scr; ARMword dll; ARMword dlm; char t_fifo[16]; char r_fifo[16];} lpc2210_uart_t;typedef struct pll{ ARMword con; ARMword cfg; ARMword stat; ARMword feed;} lpc2210_pll_t;typedef struct vic{ ARMword IRQStatus; ARMword FIQStatus; ARMword RawIntr; ARMword IntSelect; ARMword IntEnable; ARMword IntEnClr; ARMword SoftInt; ARMword SoftIntClear; ARMword Protection; ARMword Vect_Addr; ARMword DefVectAddr; ARMword VectAddr[15]; ARMword VectCntl[15];} lpc2210_vic_t;typedef struct lpc2210_io { ARMword syscon; /* System control */ ARMword sysflg; /* System status flags */ lpc2210_pll_t pll; lpc2210_timer_t timer[2]; lpc2210_vic_t vic; ARMword pinsel0; /*Pin Select Register*/ ARMword pinsel1; ARMword pinsel2; ARMword bcfg[4]; /*BCFG Extend Mem control*/ ARMword vpbdiv; /*VPB Divider control*/ int tc_prescale; lpc2210_uart_t uart[2]; /* Receive data register */ ARMword mmcr; /*Memory mapping control register*/ ARMword vibdiv; /*real time regs*/ ARMword sec; ARMword min; ARMword hour; ARMword dom; ARMword dow; ARMword doy; ARMword month; ARMword year; ARMword preint; ARMword prefrac; ARMword ccr; /*mam accelerator module*/ ARMword mamcr; ARMword mamtim; } lpc2210_io_t;static lpc2210_io_t lpc2210_io;#define io lpc2210_iovoid lpc2210_io_write_word(ARMul_State *state, ARMword addr, ARMword data);static void lpc2210_update_int(ARMul_State *state){ u32 irq = 0; int i; //state->NfiqSig = (~(io.vic.RawIntr&io.vic.IntEnable& io.vic.)) ? LOW : HIGH; irq = io.vic.RawIntr & io.vic.IntEnable ; //add by linxz //printf("SKYEYE:RawIntr:0x%x,IntEnable:0x%x\n", io.vic.RawIntr, io.vic.IntEnable); io.vic.IRQStatus = irq & ~io.vic.IntSelect; io.vic.FIQStatus = irq & io.vic.IntSelect; //here only deals some important int: //uart0 and timer0, other peripheral's int reqs are ignored. //added and rmked by linxz //UART0, Int src: 6 if(io.vic.IRQStatus &IRQ_UART0){ for ( i = 0; i<=15; i++ ) { if ( ((io.vic.VectCntl[i] & 0xf) == 6 ) && (io.vic.VectCntl[i] & 0x20) ) break; } if ( ((io.vic.VectCntl[i] & 0xf) == 6 ) && (io.vic.VectCntl[i] & 0x20) ) io.vic.Vect_Addr = io.vic.VectAddr[i]; } //TIMER0, Int src: 4 if(io.vic.IRQStatus &IRQ_TC0){ for ( i = 0; i<=15; i++ ) { if ( ((io.vic.VectCntl[i] & 0xf) == 4 ) && (io.vic.VectCntl[i] & 0x20) ) break; } if ( ((io.vic.VectCntl[i] & 0xf) == 4 ) && (io.vic.VectCntl[i] & 0x20) ) { io.vic.Vect_Addr = io.vic.VectAddr[i]; //printf("VicVect load vectaddr%d:%08x", i, io.vic.Vect_Addr); } } state->NirqSig = io.vic.IRQStatus ? LOW:HIGH; state->NfiqSig = io.vic.FIQStatus ? LOW:HIGH;}static void lpc2210_io_reset(ARMul_State *state){ //io.timer[0].pr = 500000;/*prescale value*/ //rmked by linxz io.timer[0].pr = 0; io.pll.stat |= 1<<10; /*PLL state register should be 1<<10 when hardware ready*/ io.vic.IRQStatus = 0; io.vic.FIQStatus = 0; io.vic.RawIntr = 0; //added by linxz io.vic.IntSelect = 0; io.uart[0].lsr |= 0x60; io.uart[0].iir = 0x01; io.pinsel0 = 0; io.pinsel1 = 0x15400000; //io.pinsel2 = FIX ME io.bcfg[0] = 0x0000fbef; io.bcfg[1] = 0x2000fbef; io.bcfg[2] = 0x1000fbef; io.bcfg[3] = 0x0000fbef; io.vibdiv = 0;}/*lpc2210 io_do_cycle*/void lpc2210_io_do_cycle(ARMul_State *state){ int t; io.timer[0].pc++; io.timer[1].pc++; //add by linxz //printf("SKYEYE:Timer0 PC:%d, TC:%d\n", io.timer[0].pc, io.timer[0].tc); //printf(",MR0:%d,PR:%d,RISR:%d,IER:%d,ISLR:%d,ISR:%d\n", io.timer[0].mr0, io.timer[0].pr, io.vic.RawIntr, io.vic.IntEnable, io.vic.IntSelect, io.vic.IRQStatus); if (!(io.vic.RawIntr & IRQ_TC0)) { //no timer0 int yet if (io.timer[0].pc >= io.timer[0].pr+1) { io.timer[0].tc++; io.timer[0].pc = 0; if(io.timer[0].tc >= io.timer[0].mr0/1000) /*Skyeye's clock is far more slow than the real Ocs. I have to make the clock interrupt come quicker*/{ // if(io.timer[0].tc == 20){ io.vic.RawIntr |= IRQ_TC0; io.timer[0].tc = 0; //add by linxz //printf("\r\nI\r\n"); } lpc2210_update_int(state); } } if(io.timer[0].pc == 0){ if (!(io.vic.RawIntr & IRQ_UART0)) { /* 2007-01-18 modified by Anthony Lee : for new uart device frame */ struct timeval tv; unsigned char buf; tv.tv_sec = 0; tv.tv_usec = 0; if(skyeye_uart_read(-1, &buf, 1, &tv, NULL) > 0) { //printf("SKYEYE:get input is %c\n",buf); io.uart[0].rbr = buf; io.uart[0].lsr |= 0x1; io.vic.RawIntr |= IRQ_UART0; lpc2210_update_int(state); } }/* if (rcr > 0 && ...*/ }}ARMword lpc2210_fix_int(ARMword val){/* ARMword ret = 0; if (val & (1 << 2)) ret |= URXINT; if (val & (1 << 5)) ret |= TC1OI; if (val & (1 << 6)) ret |= TC2OI; if (val & (1 << 16)) ret |= AT91_EXT0;*/ return(val);}ARMword lpc2210_unfix_int(ARMword val){/* ARMword ret = 0; if (val & URXINT) ret |= (1 << 2); if (val & TC1OI) ret |= (1 << 5); if (val & TC2OI) ret |= (1 << 6); if (val & AT91_EXT0) ret |= (1 << 16); */ return(val);}ARMwordlpc2210_uart_read(ARMul_State *state, ARMword addr,int i){ ARMword data; //printf("lpc2210_uart_read,addr=%x\n",addr); switch ((addr & 0xfff) >> 2) { case 0x0: // RbR io.uart[i].lsr &= ~0x1; if(i==0) io.vic.RawIntr &= ~IRQ_UART0; else io.vic.RawIntr &= ~IRQ_UART1; lpc2210_update_int(state); data = io.uart[i].rbr; break; case 0x1: // ier data = io.uart[i].ier; break; case 0x2: // iir data = io.uart[i].iir; break; case 0x3: // IDR case 0x4: // IMR case 0x5: // LSR data = io.uart[i].lsr; break; case 0x6: // MSR data = io.uart[i].msr; break; case 0x7: // SCR data = io.uart[i].scr; break; default: DBG_PRINT("uart_read(%s=0x%08x)\n", "uart_reg", addr); break; } return(data);}voidlpc2210_uart_write(ARMul_State *state, ARMword addr, ARMword data,int i){ static ARMword tx_buf = 0; //DBG_PRINT("uart_write(0x%x, 0x%x)\n", (addr & 0xfff) >> 2, data); switch ((addr & 0xfff) >> 2) { case 0x0: // THR { char c = data; /* 2007-01-18 modified by Anthony Lee : for new uart device frame */ skyeye_uart_write(-1, &c, 1, NULL); //io.uart[0].lsr |= 0x40; io.uart[0].lsr |= 0x20; } case 0x2: //FCR { io.uart[i].fcr = data; break; } case 0x7: // SCR io.uart[i].scr = data; break; default: //printf("%c", data); fflush(stdout); DBG_PRINT("uart_write(%s=0x%08x)\n", "uart_reg", addr); break; }}ARMword lpc2210_io_read_word(ARMul_State *state, ARMword addr){ /* * * The lpc2210 system registers * */ ARMword data = -1; static ARMword current_ivr = 0; /* mega hack, 2.0 needs this */ int i; ARMword dataimr = 0; switch (addr) { case 0xfffff000: /* ISR */// data = unfix_int(io.intsr);// dataimr = unfix_int(io.intmr); data = io.vic.IRQStatus; DBG_PRINT("read ISR=%d\n", data); break; case 0xfffff004: /* interrupt status register */ data = io.vic.FIQStatus; DBG_PRINT("SKYEYE:read ISR=%x,%x\n", data, io.vic.FIQStatus); break; case 0xfffff008: /* IMR */ data = io.vic.RawIntr; break; case 0xfffff00c: /* CORE interrupt status register */ data = io.vic.IntSelect; break; case 0xfffff010: /* IER */ data = io.vic.IntEnable; DBG_PRINT("read IER=%x,after update IntEnable=%x\n", data,io.vic.IntEnable); break; case 0xfffff014: /* Int Enable Clr Reg */ data = io.vic.IntEnClr; lpc2210_update_int(state); break; case 0xfffff034: /* Default Vector Addr Reg */ data = io.vic.DefVectAddr ; break; case 0xfffff030: /* VAR */ data = io.vic.Vect_Addr ; break; case 0xfffff100: /* VicVectAddr0*/ data = io.vic.VectAddr[0] ; break; case 0xfffff200: /*VicVectCntl0*/ data = io.vic.VectCntl[0]; break; /*Timer0 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -