Mercurial > ecos
diff packages/hal/mn10300/stdeval1/current/src/hal_diag.c @ 0:3111d98ba7b3 ecos-v1_1-release
Initial commit of eCos version 1.1
| author | jlarmour |
|---|---|
| date | Tue, 11 May 1999 11:16:07 +0000 |
| parents | |
| children | 443894e2e912 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/packages/hal/mn10300/stdeval1/current/src/hal_diag.c @@ -0,0 +1,509 @@ +/*============================================================================= +// +// hal_diag.c +// +// HAL diagnostic output code +// +//============================================================================= +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Cygnus eCos Public License +// Version 1.0 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://sourceware.cygnus.com/ecos +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Cygnus Operating System, released +// September 30, 1998. +// +// The Initial Developer of the Original Code is Cygnus. Portions created +// by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//============================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): nickg +// Contributors: nickg +// Date: 1998-03-02 +// Purpose: HAL diagnostic output +// Description: Implementations of HAL diagnostic output support. +// +//####DESCRIPTIONEND#### +// +//===========================================================================*/ + +#include <pkgconf/hal.h> + +#include <cyg/infra/cyg_type.h> // base types +#include <cyg/infra/cyg_trac.h> // tracing macros +#include <cyg/infra/cyg_ass.h> // assertion macros + +#include <cyg/hal/hal_diag.h> +#include <cyg/hal/hal_intr.h> + +/*---------------------------------------------------------------------------*/ +/* Select default diag channel to use */ + +//#define CYG_KERNEL_DIAG_ROMART +//#define CYG_KERNEL_DIAG_SERIAL1 +//#define CYG_KERNEL_DIAG_SERIAL2 +//#define CYG_KERNEL_DIAG_GDB + +#if !defined(CYG_KERNEL_DIAG_SERIAL1) && \ + !defined(CYG_KERNEL_DIAG_SERIAL2) && \ + !defined(CYG_KERNEL_DIAG_ROMART) + +# if defined(CYG_HAL_MN10300_STDEVAL1) + +# if defined(CYG_HAL_STARTUP_RAM) + +# if defined(CYG_HAL_USE_ROM_MONITOR_CYGMON) + + // If loaded into RAM via CYGMON we diag via + // serial 2 using GDB protocol + +# define CYG_KERNEL_DIAG_SERIAL2 +# define CYG_KERNEL_DIAG_GDB + +# elif defined(CYG_HAL_USE_ROM_MONITOR_SLOAD) + + // If loaded into RAM via SLOAD we diag via + // serial 1 + +# define CYG_KERNEL_DIAG_SERIAL1 + +# elif defined(CYG_HAL_USE_ROM_MONITOR_GDB_STUBS) + + // If loaded into RAM via GDB STUB ROM we diag via + // serial 1 using GDB protocol + +# define CYG_KERNEL_DIAG_SERIAL1 +# define CYG_KERNEL_DIAG_GDB + +# endif // defined(CYG_HAL_USE_ROM_MONITOR_CYGMON) + +# elif defined(CYG_HAL_STARTUP_ROM) + + // If we are ROM resident, we diag via serial 1 + +# define CYG_KERNEL_DIAG_SERIAL1 + +# endif // defined(CYG_HAL_STARTUP_RAM) + +# endif // defined(CYG_HAL_MN10300_STDEVAL1) + +#endif // if ... + +/*---------------------------------------------------------------------------*/ +// PromICE AI interface + +#if defined(CYG_HAL_MN10300_STDEVAL1_ROMART) || defined(CYG_KERNEL_DIAG_ROMART) + +#ifdef CYG_HAL_MN10300_STDEVAL1 +#define PROMICE_AILOC 0x40008000 +#endif + +#define PROMICE_BUS_SIZE 16 +#define PROMICE_BURST_SIZE 1 + +#if PROMICE_BUS_SIZE == 16 + +typedef volatile struct +{ + volatile cyg_uint16 zero; +// cyg_uint16 pad1[PROMICE_BURST_SIZE]; + volatile cyg_uint16 one; +// cyg_uint16 pad2[PROMICE_BURST_SIZE]; + volatile cyg_uint16 data; +// cyg_uint16 pad3[PROMICE_BURST_SIZE]; + volatile cyg_uint16 status; + +} AISTRUCT; + +#endif + +AISTRUCT *AI = (AISTRUCT *)PROMICE_AILOC; + +#define PROMICE_STATUS_TDA 0x01 +#define PROMICE_STATUS_HDA 0x02 +#define PROMICE_STATUS_OVR 0x04 + + +void ai_diag_init() +{ + volatile cyg_uint8 junk; + + while( AI->status == 0xCC ) + continue; + + junk = AI->data; +} + +static void ai_write_char(cyg_uint8 data) +{ + volatile cyg_uint8 junk; + int i; + + // Wait for tda == 0 + while( (AI->status & PROMICE_STATUS_TDA) == PROMICE_STATUS_TDA ) + continue; + + // Send start bit + junk = AI->one; + + for( i = 0; i < 8; i++ ) + { + // send ls bit of data + if( (data & 1) == 1 ) + junk = AI->one; + else + junk = AI->zero; + + // shift down for next bit + data >>= 1; + } + + // Send stop bit + junk = AI->one; + + // all done +} + +void ai_diag_write_char(char c) +{ + ai_write_char((cyg_uint8)c); +} + +void ai_diag_drain() {} + +void ai_diag_read_char(char *c) { *c = '\n'; } + +void ai_writes(char *s) +{ + while( *s ) ai_write_char( *s++ ); +} + +void ai_write_hex( cyg_uint32 x) +{ + int i; + ai_writes("0x"); + for( i = 28; i >=0 ; i-=4 ) + { + char *d = "0123456789ABCDEF"; + ai_write_char( d[(x>>i)&0xf] ); + } + ai_write_char(' '); +} + +#if defined(CYG_KERNEL_DIAG_ROMART) + +#define hal_diag_init_serial ai_diag_init +#define hal_diag_write_char_serial ai_diag_write_char +#define hal_diag_drain_serial ai_diag_drain +#define hal_diag_read_char_serial ai_diag_read_char + +#endif + +#endif + +/*---------------------------------------------------------------------------*/ +// MN10300 Serial line + +#if defined(CYG_HAL_MN10300_STDEVAL1_SERIAL1) || defined(CYG_KERNEL_DIAG_SERIAL1) + +// We use serial1 on MN103002 +#define SERIAL1_CR ((volatile cyg_uint16 *)0x34000810) +#define SERIAL1_ICR ((volatile cyg_uint8 *) 0x34000814) +#define SERIAL1_TXR ((volatile cyg_uint8 *) 0x34000818) +#define SERIAL1_RXR ((volatile cyg_uint8 *) 0x34000819) +#define SERIAL1_SR ((volatile cyg_uint16 *)0x3400081c) + +// Timer 1 provided baud rate divisor +#define TIMER1_MD ((volatile cyg_uint8 *)0x34001001) +#define TIMER1_BR ((volatile cyg_uint8 *)0x34001011) +#define TIMER1_CR ((volatile cyg_uint8 *)0x34001021) + +#define PORT3_MD ((volatile cyg_uint8 *)0x36008025) + +// Mystery register +#define TMPSCNT ((volatile cyg_uint8 *)0x34001071) + +#define SIO1_LSTAT_TRDY 0x20 +#define SIO1_LSTAT_RRDY 0x10 + +void hal_diag_init_serial1(void) +{ + // 48 translates to 38400 baud. + *TIMER1_BR = 48; + + // Timer1 sourced from IOCLK + *TIMER1_MD = 0x80; + + // Mode on PORT3, used for serial line controls. + *PORT3_MD = 0x01; + + // No interrupts for now. + *SERIAL1_ICR = 0x00; + + // Source from timer 1, 8bit chars, enable tx and rx + *SERIAL1_CR = 0xc084; +} + +void hal_diag_write_char_serial1(char c) +{ + register volatile cyg_uint16 *volatile tty_status = SERIAL1_SR; + register volatile cyg_uint8 *volatile tty_tx = SERIAL1_TXR; + + while( (*tty_status & SIO1_LSTAT_TRDY) != 0 ) continue; + + *tty_tx = c; +} + +void hal_diag_drain_serial1(void) +{ + register volatile cyg_uint16 *volatile tty_status = SERIAL1_SR; + + while( (*tty_status & SIO1_LSTAT_TRDY) != 0 ) continue; +} + +void hal_diag_read_char_serial1(char *c) +{ + register volatile cyg_uint16 *volatile tty_status = SERIAL1_SR; + register volatile cyg_uint8 *volatile tty_rx = SERIAL1_RXR; + + while( (*tty_status & SIO1_LSTAT_RRDY) == 0 ) continue; + + *c = *tty_rx; + +} + +#if defined(CYG_KERNEL_DIAG_SERIAL1) + +#define hal_diag_init_serial hal_diag_init_serial1 +#define hal_diag_write_char_serial hal_diag_write_char_serial1 +#define hal_diag_drain_serial hal_diag_drain_serial1 +#define hal_diag_read_char_serial hal_diag_read_char_serial1 + +#endif + +#endif + +#if defined(CYG_HAL_MN10300_STDEVAL1) + +void led(int x) +{ + *((cyg_uint8 *)0x36008004) = x<<4; +} + +#endif + + +/*---------------------------------------------------------------------------*/ + +#if defined(CYG_HAL_MN10300_STDEVAL1_SERIAL2) || defined(CYG_KERNEL_DIAG_SERIAL2) + +// We use serial2 on MN103002 +#define SERIAL2_CR ((volatile cyg_uint16 *)0x34000820) +#define SERIAL2_ICR ((volatile cyg_uint8 *) 0x34000824) +#define SERIAL2_TXR ((volatile cyg_uint8 *) 0x34000828) +#define SERIAL2_RXR ((volatile cyg_uint8 *) 0x34000829) +#define SERIAL2_SR ((volatile cyg_uint8 *)0x3400082c) +#define SERIAL2_TR ((volatile cyg_uint8 *)0x3400082d) + +// Timer 2 provided baud rate divisor +#define TIMER2_MD ((volatile cyg_uint8 *)0x34001002) +#define TIMER2_BR ((volatile cyg_uint8 *)0x34001012) +#define TIMER2_CR ((volatile cyg_uint8 *)0x34001022) + +#define PORT3_MD ((volatile cyg_uint8 *)0x36008025) + +// Mystery register +#define TMPSCNT ((volatile cyg_uint8 *)0x34001071) + +#define SIO2_LSTAT_TRDY 0x20 +#define SIO2_LSTAT_RRDY 0x10 + +void hal_diag_init_serial2(void) +{ +#if !defined(CYG_HAL_USE_ROM_MONITOR_CYGMON) + + // 16 and 22 translate to 38400 baud. + *TIMER2_BR = 16; + *SERIAL2_TR = 22; + + // Timer2 sourced from IOCLK + *TIMER2_MD = 0x80; + + // Mode on PORT3, used for serial line controls. + *PORT3_MD = 0x01; + + // No interrupts for now. + *SERIAL2_ICR = 0x00; + + // Source from timer 2, 8bit chars, enable tx and rx + *SERIAL2_CR = 0xc081; + +#endif +} + +void hal_diag_write_char_serial2(char c) +{ + register volatile cyg_uint8 *volatile tty_status = SERIAL2_SR; + register volatile cyg_uint8 *volatile tty_tx = SERIAL2_TXR; + + while( (*tty_status & SIO2_LSTAT_TRDY) != 0 ) continue; + + *tty_tx = c; +} + +void hal_diag_drain_serial2(void) +{ + register volatile cyg_uint8 *volatile tty_status = SERIAL2_SR; + + while( (*tty_status & SIO2_LSTAT_TRDY) != 0 ) continue; +} + +void hal_diag_read_char_serial2(char *c) +{ + register volatile cyg_uint8 *volatile tty_status = SERIAL2_SR; + register volatile cyg_uint8 *volatile tty_rx = SERIAL2_RXR; + + while( (*tty_status & SIO2_LSTAT_RRDY) == 0 ) continue; + + *c = *tty_rx; +} + +#if defined(CYG_KERNEL_DIAG_SERIAL2) + +#define hal_diag_init_serial hal_diag_init_serial2 +#define hal_diag_write_char_serial hal_diag_write_char_serial2 +#define hal_diag_drain_serial hal_diag_drain_serial2 +#define hal_diag_read_char_serial hal_diag_read_char_serial2 + +#endif + +#endif + +/*---------------------------------------------------------------------------*/ + +void hal_diag_init(void) +{ + hal_diag_init_serial(); +} + +void hal_diag_write_char(char c) +{ +#ifdef CYG_KERNEL_DIAG_GDB + + static char line[100]; + static int pos = 0; + + // No need to send CRs + if( c == '\r' ) return; + + line[pos++] = c; + + if( c == '\n' || pos == sizeof(line) ) + { + CYG_INTERRUPT_STATE old; + + // Disable interrupts. This prevents GDB trying to interrupt us + // while we are in the middle of sending a packet. The serial + // receive interrupt will be seen when we re-enable interrupts + // later. + + HAL_DISABLE_INTERRUPTS(old); + + while(1) + { + static char hex[] = "0123456789ABCDEF"; + cyg_uint8 csum = 0; + int i; + + hal_diag_write_char_serial('$'); + hal_diag_write_char_serial('O'); + csum += 'O'; + for( i = 0; i < pos; i++ ) + { + char ch = line[i]; + char h = hex[(ch>>4)&0xF]; + char l = hex[ch&0xF]; + hal_diag_write_char_serial(h); + hal_diag_write_char_serial(l); + csum += h; + csum += l; + } + hal_diag_write_char_serial('#'); + hal_diag_write_char_serial(hex[(csum>>4)&0xF]); + hal_diag_write_char_serial(hex[csum&0xF]); + +#if 0 + { + char c1; + + hal_diag_read_char_serial( &c1 ); + + // We must ack the interrupt caused by that read to avoid + // confusing the GDB stub ROM. + HAL_INTERRUPT_ACKNOWLEDGE( CYG_VECTOR_EXTERNAL_2 ); + + if( c1 == '+' ) break; + + ai_writes("hal_diag_read_char_serial("); + ai_write_char(c1); + ai_writes(")\r\n"); + ai_writes("retry\r\n"); + +#if defined(CYG_HAL_USE_ROM_MONITOR) && defined(CYG_HAL_USE_ROM_MONITOR_CYGMON) + if( c1 == 3 ) + { + // Ctrl-C: breakpoint. +// HAL_BREAKPOINT(_breakinst); + typedef void bpt_fn(); + bpt_fn *bfn = ((bpt_fn **)0x80000100)[61]; + + bfn(); + + break; + } +#endif + + } +#else + break; +#endif + } + + pos = 0; + + // Wait for tx buffer to drain + hal_diag_drain_serial(); + + // And re-enable interrupts + HAL_RESTORE_INTERRUPTS(old); + + } + +#else + hal_diag_write_char_serial(c); +#endif +} + + + + +void hal_diag_read_char(char *c) +{ + hal_diag_read_char_serial(c); +} + + +/*---------------------------------------------------------------------------*/ +/* End of hal_diag.c */
