⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sh-sci.c

📁 this is ipl loader for hitachi SH4 processor.
💻 C
字号:
/* sh-sci.c: SCIF functions for SH7750 * *  Copyright (C) 2001 KOMORIYA Takeru * * 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 file "GPL" for more details. * * Contact to author: *   KOMORIYA Takeru, AAF Sendai Lab., Japan *   E-mail: komoriya@chmodx.dyndns.org *      URL: http://chmodx.dyndns.org/aaf/ */#include "sh7750.h"#include "sh-intr.h"/* Ring buffer size */#define RING_SIZE 1024 /* must be 2^n *//* Tramsmit trigger     note: value must be 8/4/2/1          SCFSR2.TTRG must be set correctly. */#define TX_TRIGGER  4struct ring_buffer{  volatile unsigned char buf[RING_SIZE];  volatile unsigned int head;  volatile unsigned int tail;};static struct ring_buffer ring_tx, ring_rx;/* send data to SCIF FIFO */static voidscif_tx (void){  unsigned short fifo_num;  int i;  /* Check if tx-fifo is empty */  if (!(SCFSR2 & 0x0020)) /* SCFSR2.TDFE */    return; /* not empty */  if (ring_tx.head == ring_tx.tail) /* no data in ring buffer */    {      SCSCR2 = SCSCR2 & ~0x0080;    /* Clear SCSCR2.TIE */      return;    }  /* send to FIFO */  for (i=0; i< 16 - TX_TRIGGER; i++)    {      if (ring_tx.head == ring_tx.tail)	break;      SCFTDR2 = ring_tx.buf[ring_tx.head];      ring_tx.head++;      ring_tx.head &= RING_SIZE - 1;    }  /* Clear SCFSR2.TEND */  SCFSR2 = SCFSR2 & ~0x0040;  /* How many data in Tx-FIFO? */  fifo_num = SCFDR2 & 0x1f00;  fifo_num >>= 8;  if (fifo_num > TX_TRIGGER)    SCFSR2 = SCFSR2 & ~0x0020;    /* Clear SCFSR2.TDFE */}/* receive data from SCIF FIFO */static voidscif_rx (void){  int i, is_err;  unsigned int p;  unsigned short scfsr;  unsigned short fifo_num;  unsigned char fifo_data;  is_err = 0;  if (SCLSR2 & 0x0001) /* SCLSR2.ORER */    {      /* SCI-FIFO overrun error */      is_err = 1;    }  scfsr = SCFSR2;  if (scfsr & 0x0080) /* SCFSR2.ER */    {      /* Framing error / Parity error */      is_err = 1;    }  if (scfsr & 0x0010) /* SCFSR2.BRK */    {      /* break detect */      is_err = 1;    }    if (scfsr & 0x0003) /* SCFSR2.RDF | SCFSR2.DR */    {      /* receive from FIFO */      fifo_num = SCFDR2 & 0x001f;      for (i=0; i<fifo_num; i++)	{	  fifo_data = SCFRDR2;	  p = ring_rx.tail + 1;	  p &= RING_SIZE - 1;	  if (p == ring_rx.head) /* ring buffer overflow! */	    continue;	  ring_rx.buf[ring_rx.tail] = fifo_data;	  ring_rx.tail = p;	}      if (scfsr & 0x0002) /* SCFSR2.RDF */	SCFSR2 = SCFSR2 & ~0x0002; /* RDF = 0 */      if (scfsr & 0x0001) /* SCFSR2.DR */	is_err = 1;    }  if (is_err)    {      SCLSR2 = SCLSR2 & ~0x0001; /* ORER = 0 */      SCFSR2 = SCFSR2 & ~0x0091; /* DR = ER = BRK = 0 */    }}/* handle receive error interrupt */static voidscif_error (void){  if (SCFSR2 & 0x0080) /* SCFSR2.ER */    {      /* Framing error / Parity error */      SCFSR2 = SCFSR2 & ~0x0080;    }}/* handle break interrupt */static voidscif_break (void){  if (SCFSR2 & 0x0010) /* SCFSR2.BRK */    {      /* break detect */      SCFSR2 = SCFSR2 & ~0x0010;    }  if (SCLSR2 & 0x0001) /* SCLSR2.ORER */    {      /* SCI-FIFO overrun error */      SCLSR2 = SCLSR2 & ~0x0001;    }}/* SCIF initialize */voidscif_init(void){  intr_disable();  /* Initialize ring buffer */  ring_tx.head = 0;  ring_tx.tail = 0;  ring_rx.head = 0;  ring_rx.tail = 0;  SCSCR2 = 0x0000;	/* TE=0, RE=0, CKE1=0 */  SCFCR2 = 0x0006;	/* TFRST=1, RFRST=1 */  SCSMR2 = 0x0000;	/* CHR=0, PE=0, STOP=0, CKS=00 */  			/* 8-bit, non-parity, 1 stop bit, pf/1 clock */  SCBRR2 = 6;           /* Baudrate setting			   6: 115200 bps */  RFCR = 0xa400;	/* Refresh counter clear */  while(RFCR < 500)    ;  SCSPTR2 = 0x0080;     /* Set RTS = 1 */  SCFCR2 = 0x0090;	/* RTRG=10,TTRG=01,MCE=0,TFRST=0,RFRST=0,LOOP=0			   Note: 'TX_TRIGGER' depends on TTRG */  /* register interrupt handler */  intr_register (INTR_SCIF_TXI, scif_tx);  intr_register (INTR_SCIF_RXI, scif_rx);  intr_register (INTR_SCIF_ERI, scif_error);  intr_register (INTR_SCIF_BRI, scif_break);  /* set interrupt priority for SCIF */  intr_set_priority (MOD_SCIF, 8);  SCSCR2 = 0x0078;     /* TIE=0,RIE=1,REIE=1,TE=1,RE=1 */  intr_enable();}/* Get char (non-blocking) */intscif_getc (void){  unsigned char d;    if (ring_rx.head == ring_rx.tail)    return -1;  intr_disable();  d = ring_rx.buf[ring_rx.head];  ring_rx.head++;  ring_rx.head &= RING_SIZE - 1;  intr_enable();  return (int)d;}/* Get char with waiting */intscif_getcw (void){  unsigned char d;    while (ring_rx.head == ring_rx.tail)    ;  intr_disable();  d = ring_rx.buf[ring_rx.head];  ring_rx.head++;  ring_rx.head &= RING_SIZE - 1;  intr_enable();  return (int)d;}/* Put char */intscif_putc (unsigned char ch){  unsigned int p;    intr_disable();  p = ring_tx.tail + 1;  p &= RING_SIZE - 1;  if (p == ring_tx.head)    {      intr_enable();      return -1;    }  ring_tx.buf[ring_tx.tail] = ch;  ring_tx.tail = p;  SCSCR2 = SCSCR2 | 0x0080;    /* Set SCSCR2.TIE				  to invoke scif_tx */  intr_enable();  return 0;}/* Put string */intscif_puts (const char *s){  unsigned int p;  intr_disable();  while(*s)    {      p = ring_tx.tail + 1;      p &= RING_SIZE - 1;      if (p == ring_tx.head)	{	  SCSCR2 = SCSCR2 | 0x0080;    /* Set SCSCR2.TIE					  to invoke scif_tx */	  intr_enable();	  return -1;	}      ring_tx.buf[ring_tx.tail] = *s;      ring_tx.tail = p;      s++;    }  SCSCR2 = SCSCR2 | 0x0080;    /* Set SCSCR2.TIE 				  to invoke scif_tx */  intr_enable();  return 0;}/* Flush transmit ring buffer */voidscif_flush (void){  while (ring_tx.head != ring_tx.tail)    ;  /* Check SCFSR2.TEND */  while (!(SCFSR2 & 0x0040))    ;}/* Disable SCIF */voidscif_disable (void){  scif_flush();  SCSCR2 = 0x0000;	/* TE=0, RE=0, CKE1=0 */  intr_unregister (INTR_SCIF_TXI);  intr_unregister (INTR_SCIF_RXI);  intr_unregister (INTR_SCIF_ERI);  intr_unregister (INTR_SCIF_BRI);}/* Put decimal digit to SCI */voidscif_put_decimal (long a){  char c[12];  int i, j, pm;    i = 0;  pm = 0;    if (a < 0)    {      pm = 1;      a = -a;    }  if (a == 0)    {      c[0] = '0';      i = 1;    }  while (a > 0)    {      c[i] = '0' + a % 10;      a /= 10;      i++;    }    if (pm)    c[i] = '-';  else    i--;  for (j=i; j>=0; j--)    scif_putc (c[j]);}/* Put hex to SCI */voidscif_put_hex (unsigned long a, int digit){  char c[8];  int b, i, j;    i = 0;    for (i=0; i<digit; i++)    {      b = a & 0x0f;      if (b < 0x0a)        c[i] = '0' + b;      else        c[i] = 'a' + b - 0x0a;      a >>= 4;    }    for (j=digit-1; j>=0; j--)    scif_putc (c[j]);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -