From 7ae512513f37ccce1d5beeb4807b5b4b765025d7 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 16 Aug 2001 21:08:28 +0000 Subject: 2001-08-10 Radzislaw Galler * score/cpu_asm.c (sh_set_irq_priority): Changed interrupt vector number range check and handling of interrupt priority regs to conform SH2 specs. * sci/sci_termios.c: New file. * include/sci_termios.h: New file. * include/Makefile.am (EXTRA_DIST): Added sci_termios.h. (include_sh_HEADERS): Added sci_termios.h. * score/ispsh7045.c (isp): Calling an ISR with immediate argument casued negative sign extension for vector numbers of 128 and above. This was fixed. * sci/sci.c: Cleaned initialization of SCI registers; added necessary setup for new TERMIOS console cooperation --- c/src/lib/libcpu/sh/sh7045/ChangeLog | 15 +++ c/src/lib/libcpu/sh/sh7045/include/Makefile.am | 4 +- c/src/lib/libcpu/sh/sh7045/include/sci.h | 7 ++ c/src/lib/libcpu/sh/sh7045/sci/Makefile.am | 4 +- c/src/lib/libcpu/sh/sh7045/sci/sci.c | 143 ++++++++++++++++++++++--- c/src/lib/libcpu/sh/sh7045/score/cpu_asm.c | 5 +- c/src/lib/libcpu/sh/sh7045/score/ispsh7045.c | 7 +- 7 files changed, 161 insertions(+), 24 deletions(-) (limited to 'c/src/lib') diff --git a/c/src/lib/libcpu/sh/sh7045/ChangeLog b/c/src/lib/libcpu/sh/sh7045/ChangeLog index 3c83377e0e..717ea7082f 100644 --- a/c/src/lib/libcpu/sh/sh7045/ChangeLog +++ b/c/src/lib/libcpu/sh/sh7045/ChangeLog @@ -1,3 +1,18 @@ +2001-08-10 Radzislaw Galler + + * score/cpu_asm.c (sh_set_irq_priority): Changed interrupt vector + number range check and handling of interrupt priority regs to + conform SH2 specs. + * sci/sci_termios.c: New file. + * include/sci_termios.h: New file. + * include/Makefile.am (EXTRA_DIST): Added sci_termios.h. + (include_sh_HEADERS): Added sci_termios.h. + * score/ispsh7045.c (isp): Calling an ISR with immediate argument + casued negative sign extension for vector numbers of 128 and + above. This was fixed. + * sci/sci.c: Cleaned initialization of SCI registers; added + necessary setup for new TERMIOS console cooperation + 2001-02-18 Ralf Corsepiu * include/Makefile.am: Apply include_*HEADERS instead of H_FILES. diff --git a/c/src/lib/libcpu/sh/sh7045/include/Makefile.am b/c/src/lib/libcpu/sh/sh7045/include/Makefile.am index 4e9db26cd1..6a45a1cc36 100644 --- a/c/src/lib/libcpu/sh/sh7045/include/Makefile.am +++ b/c/src/lib/libcpu/sh/sh7045/include/Makefile.am @@ -9,7 +9,7 @@ AUTOMAKE_OPTIONS = foreign 1.4 include_shdir = $(includedir)/sh include_rtems_scoredir = $(includedir)/rtems/score -include_sh_HEADERS = io_types.h sci.h sh7_pfc.h sh7_sci.h +include_sh_HEADERS = io_types.h sci.h sh7_pfc.h sh7_sci.h sci_termios.h include_rtems_score_HEADERS = ispsh7045.h iosh7045.h $(PROJECT_INCLUDE)/sh: @@ -27,6 +27,6 @@ TMPINSTALL_FILES += $(PROJECT_INCLUDE)/sh \ all-local: $(TMPINSTALL_FILES) -EXTRA_DIST = io_types.h sci.h sh7_pfc.h sh7_sci.h +EXTRA_DIST = io_types.h sci.h sh7_pfc.h sh7_sci.h sci_termios.h include $(top_srcdir)/../../../../../../automake/local.am diff --git a/c/src/lib/libcpu/sh/sh7045/include/sci.h b/c/src/lib/libcpu/sh/sh7045/include/sci.h index e9c133fd32..e4160f9ca6 100644 --- a/c/src/lib/libcpu/sh/sh7045/include/sci.h +++ b/c/src/lib/libcpu/sh/sh7045/include/sci.h @@ -25,6 +25,8 @@ #ifndef _sh_sci_h #define _sh_sci_h +#include + #ifdef __cplusplus extern "C" { #endif @@ -77,6 +79,11 @@ extern rtems_device_driver sh_sci_control( rtems_device_minor_number, void * ); + +extern const rtems_termios_callbacks * sh_sci_get_termios_handlers( + rtems_boolean poll +); + #ifdef __cplusplus } diff --git a/c/src/lib/libcpu/sh/sh7045/sci/Makefile.am b/c/src/lib/libcpu/sh/sh7045/sci/Makefile.am index 77471af08e..c6b70f7e5e 100644 --- a/c/src/lib/libcpu/sh/sh7045/sci/Makefile.am +++ b/c/src/lib/libcpu/sh/sh7045/sci/Makefile.am @@ -6,7 +6,7 @@ AUTOMAKE_OPTIONS = foreign 1.4 PGM = $(ARCH)/sci.rel -C_FILES = sci.c +C_FILES = sci.c sci_termios.c C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o) OBJS = $(C_O_FILES) @@ -26,6 +26,6 @@ all-local: $(ARCH) $(OBJS) $(PGM) .PRECIOUS: $(PGM) -EXTRA_DIST = sci.c +EXTRA_DIST = sci.c sci_termios.c include $(top_srcdir)/../../../../../../automake/local.am diff --git a/c/src/lib/libcpu/sh/sh7045/sci/sci.c b/c/src/lib/libcpu/sh/sh7045/sci/sci.c index 5cfef8a585..33ee6ef411 100644 --- a/c/src/lib/libcpu/sh/sh7045/sci/sci.c +++ b/c/src/lib/libcpu/sh/sh7045/sci/sci.c @@ -42,6 +42,7 @@ #include + #include #include @@ -212,6 +213,14 @@ rtems_boolean rdSCI0(unsigned char *ch) /* Clear RDRF flag */ temp = read8(SCI_SSR0) & ~SCI_RDRF; write8(temp, SCI_SSR0); + /* Check for transmission errors */ + if(temp & (SCI_ORER | SCI_FER | SCI_PER)){ + /* TODO: report to RTEMS transmission error */ + + /* clear error flags*/ + temp &= ~(SCI_ORER | SCI_FER | SCI_PER); + write8(temp, SCI_SSR0); + } result = TRUE; } return result; @@ -228,8 +237,16 @@ rtems_boolean rdSCI1(unsigned char *ch) /* Clear RDRF flag */ temp= read8(SCI_SSR1) & ~SCI_RDRF; write8(temp, SCI_SSR1); - result = TRUE; + /* Check for transmission errors */ + if(temp & (SCI_ORER | SCI_FER | SCI_PER)){ + /* TODO: report to RTEMS transmission error */ + + /* clear error flags*/ + temp &= ~(SCI_ORER | SCI_FER | SCI_PER); + write8(temp, SCI_SSR1); } + result = TRUE; + } return result; } /* rdSCI1 */ @@ -278,21 +295,33 @@ rtems_device_driver sh_sci_initialize( void *arg ) { rtems_device_driver status ; - rtems_device_minor_number i; + rtems_device_minor_number i; + rtems_driver_name_t *driver = NULL; + /* * register all possible devices. * the initialization of the hardware is done by sci_open + * + * One of devices could be previously registered by console + * initialization therefore we check it everytime */ for ( i = 0 ; i < SCI_MINOR_DEVICES ; i++ ) { - status = rtems_io_register_name( - sci_device[i].name, - major, - sci_device[i].minor ); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); + status = rtems_io_lookup_name( + sci_device[i].name, + &driver); + if( status != RTEMS_SUCCESSFUL ) + { + /* OK. We assume it is not registered yet. */ + status = rtems_io_register_name( + sci_device[i].name, + major, + sci_device[i].minor ); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + } } /* non-default hardware setup occurs in sh_sci_open() */ @@ -304,7 +333,6 @@ rtems_device_driver sh_sci_initialize( /* * Open entry point * Sets up port and pins for selected sci. - * SCI0 setup is conditional on STANDALONE_EVB == 1 */ rtems_device_driver sh_sci_open( @@ -332,7 +360,7 @@ rtems_device_driver sh_sci_open( /* set PFC registers to enable I/O pins */ - if ((minor == 0) && (STANDALONE_EVB == 1)) { + if ((minor == 0)) { temp16 = read16(PFC_PACRL2); /* disable SCK0, DMA, IRQ */ temp16 &= ~(PA2MD1 | PA2MD0); temp16 |= (PA_TXD0 | PA_RXD0); /* enable pins for Tx0, Rx0 */ @@ -347,8 +375,7 @@ rtems_device_driver sh_sci_open( } /* add other devices and pins as req'd. */ /* set up SCI registers */ - if ((minor != 0) || (STANDALONE_EVB == 1)) { - write8(0x00, sci_device[minor].addr + SCI_SCR); /* Clear SCR */ + write8(0x00, sci_device[minor].addr + SCI_SCR); /* Clear SCR */ /* set SMR and BRR */ _sci_set_cflags( &sci_device[minor], sci_device[minor].cflags ); @@ -358,10 +385,17 @@ rtems_device_driver sh_sci_open( write8((SCI_RE | SCI_TE), /* enable async. Tx and Rx */ sci_device[minor].addr + SCI_SCR); - temp8 = read8(sci_device[minor].addr + SCI_RDR); /* flush input */ + + /* clear error flags */ + temp8 = read8(sci_device[minor].addr + SCI_SSR); + while(temp8 & (SCI_RDRF | SCI_ORER | SCI_FER | SCI_PER)){ + temp8 = read8(sci_device[minor].addr + SCI_RDR); /* flush input */ + temp8 = read8(sci_device[minor].addr + SCI_SSR); /* clear some flags */ + write8(temp8 & ~(SCI_RDRF | SCI_ORER | SCI_FER | SCI_PER), + sci_device[minor].addr + SCI_SSR); + temp8 = read8(sci_device[minor].addr + SCI_SSR); /* check if everything is OK */ + } /* Clear RDRF flag */ - temp8= read8(sci_device[minor].addr + SCI_SSR) & ~SCI_RDRF; - write8(temp8, sci_device[minor].addr + SCI_SSR); write8(0x00, sci_device[minor].addr + SCI_TDR); /* force output */ /* Clear the TDRE bit */ temp8 = read8(sci_device[minor].addr + SCI_SSR) & ~SCI_TDRE; @@ -369,8 +403,7 @@ rtems_device_driver sh_sci_open( /* add interrupt setup if required */ - } - + sci_device[minor].opened++ ; return RTEMS_SUCCESSFUL ; @@ -471,3 +504,79 @@ rtems_device_driver sh_sci_control( /* Not yet supported */ return RTEMS_SUCCESSFUL ; } + +/* + * Termios polled first open + */ +static int _sh_sci_poll_first_open(int major, int minor, void *arg) +{ + return sh_sci_open(major, minor, arg); +} + +/* + * Termios general last close + */ +static int _sh_sci_last_close(int major, int minor, void *arg) +{ + return sh_sci_close(major, minor, arg); +} + +/* + * Termios polled read + */ +static int _sh_sci_poll_read(int minor) +{ + int value = -1; + char ch; + + if( minor == 0 ){ + if( rdSCI0( &ch ) ) + value = (int) ch; + }else if( minor == 1 ){ + if( rdSCI1( &ch ) ) + value = (int) ch; + } + return value; +} + +/* + * Termios polled write + */ +static int _sh_sci_poll_write(int minor, const char *buf, int len) +{ + int count; + + for(count = 0; count < len; count++) + outbyte( minor, buf[count] ); + return count; +} + +/* + * Termios set attributes + */ +static int _sh_sci_set_attributes( int minor, const struct termios *t) +{ + return _sci_set_cflags( &sci_device[ minor ], t->c_cflag); +} + + +const rtems_termios_callbacks sci_poll_callbacks = { + _sh_sci_poll_first_open, /* FirstOpen*/ + _sh_sci_last_close, /* LastClose*/ + _sh_sci_poll_read, /* PollRead */ + _sh_sci_poll_write, /* Write */ + _sh_sci_set_attributes, /* setAttributes */ + NULL, /* stopRemoteTX */ + NULL, /* StartRemoteTX */ + 0 /* outputUsesInterrupts */ +}; + +/* FIXME: not yet supported */ +const rtems_termios_callbacks sci_interrupt_callbacks; + +const rtems_termios_callbacks* sh_sci_get_termios_handlers( rtems_boolean poll ) +{ + return poll ? + &sci_poll_callbacks : + &sci_interrupt_callbacks; +} diff --git a/c/src/lib/libcpu/sh/sh7045/score/cpu_asm.c b/c/src/lib/libcpu/sh/sh7045/score/cpu_asm.c index 6453105bdb..2b5fc6d71d 100644 --- a/c/src/lib/libcpu/sh/sh7045/score/cpu_asm.c +++ b/c/src/lib/libcpu/sh/sh7045/score/cpu_asm.c @@ -81,7 +81,7 @@ unsigned int sh_set_irq_priority( /* * first check for valid interrupt */ - if(( irq > 113) || (_Hardware_isr_Table[irq] == _dummy_isp)) + if(( irq > 156) || (irq < 64) || (_Hardware_isr_Table[irq] == _dummy_isp)) return -1; /* * check for valid irq priority @@ -102,6 +102,9 @@ unsigned int sh_set_irq_priority( case 0: { prioreg = INTC_IPRC; break;} case 1: { prioreg = INTC_IPRD; break;} case 2: { prioreg = INTC_IPRE; break;} + case 3: { prioreg = INTC_IPRF; break;} + case 4: { prioreg = INTC_IPRG; break;} + case 5: { prioreg = INTC_IPRH; break;} default: return -1; } } diff --git a/c/src/lib/libcpu/sh/sh7045/score/ispsh7045.c b/c/src/lib/libcpu/sh/sh7045/score/ispsh7045.c index 44aeaff8f1..85aa9d20e6 100644 --- a/c/src/lib/libcpu/sh/sh7045/score/ispsh7045.c +++ b/c/src/lib/libcpu/sh/sh7045/score/ispsh7045.c @@ -123,9 +123,10 @@ asm (".global _"Str(name)"\n\t" \ " sts.l mach,@-r15 \n\t" \ " sts.l macl,@-r15 \n\t" \ " mov r15,r14 \n\t" \ + " mov.l "Str(name)"_v, r2 \n\t" \ " mov.l "Str(name)"_k, r1\n\t" \ " jsr @r1 \n\t" \ - " mov #"Str(number)", r4\n\t" \ + " mov r2,r4 \n\t" \ " mov r14,r15 \n\t" \ " lds.l @r15+,macl \n\t" \ " lds.l @r15+,mach \n\t" \ @@ -143,7 +144,9 @@ asm (".global _"Str(name)"\n\t" \ " nop \n\t" \ " .align 2 \n\t" \ #name"_k: \n\t" \ - ".long "Str(func)); + ".long "Str(func)"\n\t" \ + #name"_v: \n\t" \ + ".long "Str(number)); /************************************************ * Dummy interrupt service procedure for -- cgit v1.2.3