📄 cpuio.c
字号:
/* cpuio.c: General notice: This code is part of a boot-monitor package developed as a generic base platform for embedded system designs. As such, it is likely to be distributed to various projects beyond the control of the original author. Please notify the author of any enhancements made or bugs found so that all may benefit from the changes. In addition, notification back to the author will allow the new user to pick up changes that may have been made by other users after this version of the code was distributed. Author: Ed Sutter email: esutter@lucent.com (home: lesutter@worldnet.att.net) phone: 908-582-2351 (home: 908-889-5161)*/#include "config.h"#include "cpu.h"#include "cpuio.h"#include "ether.h"#include "genlib.h"#include "stddefs.h"struct bd *rxbd;uchar xbuf[8], rbuf[8];int (*remoteputchar)();int (*remotegetchar)();int (*remoterawon)();int (*remoterawoff)();int (*remotegotachar)();int ConsoleBaudRate;void CSSetup(void);extern int getreg(), putreg();/* InitUART(): This function is called at startup, application exit, or by the mstat -b BAUD command. For startup and mstat, the baud rate will be specified and used; for application exit, it will be 0 to indicate that whatever baud rate was used prior by mstat or startup should be used again.*/voidInitUART(int baud){ if (baud == 0) baud = ConsoleBaudRate; /* Keep track of the last baud rate, so that it can be used if the */ /* incoming baudrate is NULL. */ ConsoleBaudRate = baud; /* Set up SCC1... */ /* SIMODE: See page 4-23 */ *(ushort *)SIMODE = 0x0000; /* Non-muxed Serial Interface Mode */ /* SCON: See page 4-28 */ switch(baud) { /* Baud rate options with 20Mhz xtal */ case 9600: /* CD = (20000000/(9600*16)) - 1 */ *(ushort *)SCON1 = (0|(129<<1)); break; case 38400: /* CD = (20000000/(38400*16)) - 1 */ *(ushort *)SCON1 = (0|(32<<1)); break; case 19200: /* CD = (20000000/(19200*16)) - 1 */ default: *(ushort *)SCON1 = (0|(64<<1)); break; } /* SCM: See pages 4-31 and 4-64. */ *(ushort *)SCM1 = 0x01b1; /* Software CTS&CD, Async mode. */ /* No parity, 1 stop bit */ *(uchar *)RFCR1 = 0; /* Transmit & receive function codes. */ *(uchar *)TFCR1 = 0; /* RCCR: page 4-59 */ *(ushort *)RCCR1C1 = 0x8000; /* Clear UART Control char regs...*/ *(ushort *)RCCR1C8 = 0x0000; *(ushort *)PAREC1 = 0; /* Clear error counts */ *(ushort *)FRMEC1 = 0; *(ushort *)NOSEC1 = 0; *(ushort *)BRKEC1 = 0; *(ushort *)UADR11 = 0; /* Clear UART address (not used) */ *(ushort *)UADR21 = 0; *(ushort *)MRBLR1 = 1; /* Maximum rcv buffer length */ *(uchar *)RBDNM1 = 0x00; /* Rcv buffer descriptor number */ *(uchar *)TBDNM1 = 0x40; /* Xmt buffer descriptor number */ /* UART xmtbuf descriptors: pg 4-71 */ *(ushort *)TXBD0_0 = 0x6000; /* Status and control */ *(ushort *)TXBD0_1 = 0x0001; /* Data length */ *(uchar **)TXBD0_2 = &xbuf[0]; /* Buffer pointer */ /* UART rcvbuf descriptors: pg 4-66 */ /* Set up a 4-byte fifo. */#if 0 /* Uses external memory for data: */ *(ushort *)RXBD0_0 = 0xd000; /* Status and control */ *(ushort *)RXBD0_1 = 0x0001; /* Data length */ *(uchar **)RXBD0_2 = &rbuf[0]; /* Buffer pointer */ *(ushort *)RXBD1_0 = 0xd000; /* Repeat for 3 more BDs... */ *(ushort *)RXBD1_1 = 0x0001; *(uchar **)RXBD1_2 = &rbuf[1]; *(ushort *)RXBD2_0 = 0xd000; *(ushort *)RXBD2_1 = 0x0001; *(uchar **)RXBD2_2 = &rbuf[2]; *(ushort *)RXBD3_0 = 0xf000; *(ushort *)RXBD3_1 = 0x0001; *(uchar **)RXBD3_2 = &rbuf[3];#else /* Uses internal memory for data: */ *(ushort *)RXBD0_0 = 0x9000; /* Status and control */ *(ushort *)RXBD0_1 = 0x0001; /* Data length */ *(uchar **)RXBD0_2 = (uchar *)0;/* Buffer pointer */ *(ushort *)RXBD1_0 = 0x9000; /* Repeat for 3 more BDs... */ *(ushort *)RXBD1_1 = 0x0001; *(uchar **)RXBD1_2 = (uchar *)1; *(ushort *)RXBD2_0 = 0x9000; *(ushort *)RXBD2_1 = 0x0001; *(uchar **)RXBD2_2 = (uchar *)2; *(ushort *)RXBD3_0 = 0xb000; *(ushort *)RXBD3_1 = 0x0001; *(uchar **)RXBD3_2 = (uchar *)3;#endif rxbd = (struct bd *)RXBD0_0; /* SCCM: page 4-76 */ *(uchar *)SCCM1 = 0xff; /* Enable all events */ /* SCCE: page 4-73 */ *(uchar *)SCCE1 = 0xff; /* Clear all events */ *(ushort *)SCM1 = 0x01b1 | 0x000c; /* Enable transmit and receive */ *(uchar *)SCCE1 = *(uchar *)SCCE1; InitRemoteIO();}/* The common version of start.c calls devInit(baud) instead of the older * InitUART(baud). To become compatible with this, we encapsulate InitUART() * with devInit() here... */intdevInit(int baud){ InitUART(baud); return(0);}/* Enable/Disable BreakInterrupt(): Called by monitor to simply enable or disable the processor's ability to generate an interrupt when a break condition is detected on SCC1 which is used as the debug port.*/voidEnableBreakInterrupt(){ *(ushort *)IMR |= 0x2000; /* IMR: page 3-30 */ *(uchar *)SCCM1 |= 0x10; /* SCCM1: page 4-76 */}voidDisableBreakInterrupt(){ *(uchar *)SCCE1 = 0x10; *(uchar *)SCCM1 &= ~0x10; *(ushort *)IMR &= ~0x2000;}#if SYSTEM_PPAFAXROUTER/* PIO Pin Assignments: PA2-0: SLIC-B[2-0] PA3: SLIC-BR PA4: DSP_RESET (active low, output) PA5: CodecPowerDown (Powerdown = 1, output) PA6: Unused PA7: Dedicated PA8: CtrlRelay (active low, output) PA9: SerialEEPROM_CS (active low, output) PA10-11:Unused PA12: Dedicated PA13-14:Unused PA15: Dedicated PB0-2: Dedicated PB3: Line-OnHook (low=offhook, output) PB4: Fax-OffHook (input) PB5: Ethernet ctrl LOOP (output) PB6: Ethernet ctrl TPFULDL (output) PB7: Ethernet ctrl TPSQEL (output) PB8: Ethernet ctrl TPAPCE (output) PB9: Ethernet ctrl APORT (output) PB10: Ethernet ctrl TPEN (output) PB11: Ethernet ctrl CS2 (output)*/voidinitCPUio(){ int i, j; /* PIO is configured specific to the PPA hardware: */ /* PA7, PA12, and PA15 are dedicated: */ *(ushort *)PACNT = 0x9080; /* PB0-2 are dedicated: */ *(ushort *)PBCNT = 0x0007; *(ushort *)MOBAR = 0x0710; /* reinit MOBAR */ /* Set PM6 to 1 to allow PB4 to be input */ *(ushort *)MBCTL = 0x5040; *(ushort *)PCSR = 0x0000; /* PA0-5, PA8-9 are outputs */ *(ushort *)PADDR = 0x033f; /* PB3, PB5-11 are outputs */ *(ushort *)PBDDR = 0x0fe8; DRAMSetup(); CSSetup();}/* DRAM Controller setup (bank 0) ... Precharge = 2 clocks WaitStates = 0 Refresh = 9 Bank 0 starts at 0x40000*/voidDRAMSetup(){ *(ushort *)DRFRSH = 0x0009; /* 0x710012 */#if 0 /* This works for mapping DRAM space from 0x40000 .. 0x7ffff */ /* This puts DRAM contiguous just above SRAM, but limits the space */ /* to .25 Mg. */ *(ushort *)DBA0 = 0x047d; /* 0x710014 */#else /* This works for mapping DRAM space from 0x100000 .. 0x1fffff */ /* This puts DRAM not-contiguous above SRAM, but gives me 1Mg. */ *(ushort *)DBA0 = 0x1071; /* 0x710014 */#endif *(ushort *)DCR = 0x0401; /* 0x710010 */}#elif SYSTEM_PPA68K/* PIO Pin Assignments: PA2-0: SLIC-B[2-0] PA3: SLIC-BR PA4: DSP_RESET (active low, output) PA5: CodecPowerDown (Powerdown = 1, output) PA6: Unused PA7: Dedicated PA8: CtrlRelay (active low, output) PA9-11: SLIC-B[2-0] (line 2) (modified 8/19/98) PA12: SLIC_BR (line 2) (modified 8/19/98) PA13-14:Unused PA15: Dedicated PB0-2: Dedicated PB3-6: Unused PB7: Ethernet ctrl TPSQEL (output) PB8: Test Bulb (output) PB9: Fax OHN2 (input) PB10: Line OHN (input) PB11: Line OHN2 (input)*/voidinitCPUio(){ /* PIO is configured specific to the PPA hardware: */ /* PA7 and PA15 are dedicated: */ *(ushort *)PACNT = 0x8080; /* PB0-2 are dedicated: */ *(ushort *)PBCNT = 0x0007; *(ushort *)MOBAR = 0x0710; /* reinit MOBAR */ /* Set PM6 to 1 to allow PB4 to be input */ *(ushort *)MBCTL = 0x5040; *(ushort *)PCSR = 0x0000;#if 1 /* Changed on 8/19/98 to support second phone line */ /* PA0-5, PA8-12 are outputs */ *(ushort *)PADDR = 0x1f3f;#else /* PA0-5, PA8-9 are outputs */ *(ushort *)PADDR = 0x033f;#endif /* PB7-8 are outputs */ *(ushort *)PBDDR = 0x0180; /* Activate control relay */ *(ushort *)PADAT &= 0xfeff; /* Put DSP in reset */ *(ushort *)PADAT &= 0xffef; CSSetup(); /* Note that there is no call to DRAMsetup() here. This is because */ /* the new version of the PPA has ONLY DRAM, so it must be initialized */ /* in reset.s. */}#elseError: cpuio invalid configuration.#endifstruct cs { ushort *br; ushort *or;} cstbl[] = { { (ushort *)BR0, (ushort *)OR0 }, { (ushort *)BR1, (ushort *)OR1 }, { (ushort *)BR2, (ushort *)OR2 }, { (ushort *)BR3, (ushort *)OR3 }};char *rw(br,or)ushort or,br;{ if (or & 0x0002) return((br & 0x0002) ? "write-only" : "read-only"); else return("read/write");}voidCSInfo(){ int csnum, i; ushort br, or; printf("\nCurrent Chip Select Ctrl-Regs:\n"); printf(" BR0: 0x%04x, BR1: 0x%04x, BR2: 0x%04x, BR3: 0x%04x\n", *(ushort *)BR0,*(ushort *)BR1,*(ushort *)BR2,*(ushort *)BR3); printf(" OR0: 0x%04x, OR1: 0x%04x, OR2: 0x%04x, OR3: 0x%04x\n", *(ushort *)OR0,*(ushort *)OR1,*(ushort *)OR2,*(ushort *)OR3); printf("\nCurrent Chip Select Config:\n"); for(i=0;i<4;i++) { csnum = i; br = *(cstbl[i].br); or = *(cstbl[i].or); printf(" CS%d base: 0x%06lx %s, Mask: 0x%04lx, FC: %d%d%d%s, %s\n", i, (ulong)(br & 0x1ffc) << 11, (br & 0x0001) ? " (enabled)" : "(disabled)", (ulong)(or & 0x1ffc) << 11, (br & 0x8000) ? 1 : 0, (br & 0x4000) ? 1 : 0, (br & 0x2000) ? 1 : 0, (or & 0x0001) ? "" : " (ignored)", rw(br,or)); /* Assumes 68000 bus cycle description (pg 5-32). */ if ((or & 0xe000) == 0xe000) printf(" (external DTACK, "); else printf(" (%d wait states",(or & 0xe000) >> 13); /* printf(", %d bit interface", *(ushort *)SCRHI & (0x0008 >> i) ? 16 : 8); */ printf(")\n"); }}voidCSSetup(){ /* Chip selects 0 and 1 are already programmed (reset.s). */ /* CS0: FLASH 1Mbyte (512Kx16) start @ 0x400000 */ /* CS1: SRAM 128K (64Kx16) start @ 0x000000 */ /* CS2: SRAM 128K (64Kx16) start @ 0x020000 */ /* CS3: DualPortRam 4K (2Kx16) start # 0x800000 */#if SYSTEM_PPAFAXROUTER *(ushort *)BR2 = 0x0041; *(ushort *)OR2 = 0xdfc0;#endif *(ushort *)BR3 = 0x1001; *(ushort *)OR3 = 0xdf00;}/* rawon() & rawoff(): Used primarily by xmodem. When xmodem runs, it must be assured that the interface is in RAW mode. For the case of the monitor alone, it will always be in a raw mode. These functions are primarily for use when an application has re-loaded the serial driver and may have put it in a non-raw mode. The mon_con() calls CHARFUNC_RAWMODEON and CHARFUNC_RAWMODEOFF establish these pointers.*/voidrawon(void){ if (remoterawon) remoterawon();}voidrawoff(void){ if (remoterawoff) remoterawoff();}/* rputchar(): Raw put char.*/intrputchar(char c){ /* First check to see if the default rputchar() function has */ /* been overridden... */ if (remoteputchar) { return(remoteputchar(c)); } /* Wait for ready bit to clear... */ while(1) { if (!(*(ushort *)TXBD0_0 & 0x8000)) break; }#if INCLUDE_ETHERNET SendIPMonChar(c,0);#endif xbuf[0] = (uchar)c; *(ushort *)TXBD0_0 |= 0x8000; return((int)c);}/* getchar(): Block on the Uart's status until a byte is available in the receive buffer, then return with it.*/int getchar(void){ extern struct bd *rxbd; char c; /* First check to see if the default getchar() function has */ /* been overridden... */ if (remotegetchar) return(remotegetchar()); /* Wait for character present: */ while(rxbd->stat & 0x8000) {#if INCLUDE_ETHERNET pollethernet();#endif } /* Retrieve character and clear status bit: */ if (rxbd->stat & 0x4000) /* If internal, then add BASE. */ c = *(rxbd->ptr); else c = *(rxbd->ptr+BASE); rxbd->stat |= 0x8000; /* If WRAP bit is set in descriptor, reset pointer; else increment: */ if (rxbd->stat & 0x2000) rxbd = (struct bd *)RXBD0_0; else rxbd++; return((int)c);}intgotachar(void){ if (rxbd->stat & 0x8000) return(0); else return(1);}voidsetTraceBit(void){ ulong reg; getreg("SR",®); reg |= SR_TRACE; putreg("SR",reg);}voidclrTraceBit(void){ ulong reg; getreg("SR",®); reg &= ~SR_TRACE; putreg("SR",reg);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -