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

📄 spacewire.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  This file contains the TTY driver for the spacewire port on the LEON. * *  This driver uses the termios pseudo driver. * *  COPYRIGHT (c) 1989-1998. *  On-Line Applications Research Corporation (OAR). * *  Modified for LEON3 BSP. *  COPYRIGHT (c) 2005. *  Gaisler Research. * *  The license and distribution terms for this file may be *  found in the file LICENSE in this distribution or at *  http://www.rtems.com/license/LICENSE. * *  spacewire.c,v 1.1.2.1 2005/11/02 19:25:59 jiri Exp */#include <bsp.h>#include <rtems/libio.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <assert.h>#include <sched.h>#include <ctype.h>#include <rtems/bspIo.h>#define DBGSPW_IOCALLS 1#define DBGSPW_TX 2#define DBGSPW_RX 4#define DBGSPW_IOCTRL 8#define DBGSPW_DUMP 16#define DEBUG_SPACEWIRE_FLAGS -1/*#define DEBUG_SPACEWIRE_ONOFF*/ #ifdef DEBUG_SPACEWIRE_ONOFFint DEBUG_printf(const char *fmt, ...);#define SPACEWIRE_DBG(fmt, args...) \  do { \   { printf(" : %03d @ %18s()]:" fmt , __LINE__,__FUNCTION__,## args); } \  } while(0)#define SPACEWIRE_DBG2(fmt) \ do { \   { printf(" : %03d @ %18s()]:" fmt , __LINE__,__FUNCTION__); } \ } while(0)#define SPACEWIRE_DBGC(c,fmt, args...) \  do { \    if (DEBUG_SPACEWIRE_FLAGS&c) { \      printf(" : %03d @ %18s()]:" fmt , __LINE__,__FUNCTION__,## args); \    } \  } while(0)#else#define SPACEWIRE_DBG(fmt, args...)#define SPACEWIRE_DBG2(fmt, args...)#define SPACEWIRE_DBGC(fmt, args...)#endifint spacewire_hw_init(int minor);void spacewire_hw_send(int minor,unsigned char *b,int c);int spacewire_hw_receive(int minor,unsigned char *b,int c);int spacewire_hw_startup (int minor);int spacewire_hw_stop (int minor);void spacewire_hw_waitlink (int minor);void spacewire_rxnext(int minor);int _SPW_READ(void *addr) {        int tmp;                asm(" lda [%1]1, %0 "            : "=r"(tmp)            : "r"(addr)           );        return tmp;}rtems_device_driver spacewire_console_initialize(  rtems_device_major_number  major,  rtems_device_minor_number  minor,  void                      *arg);rtems_device_driver spacewire_console_open(  rtems_device_major_number major,  rtems_device_minor_number minor,  void                    * arg);rtems_device_driver spacewire_console_close(  rtems_device_major_number major,  rtems_device_minor_number minor,  void                    * arg);rtems_device_driver spacewire_console_read(  rtems_device_major_number major,  rtems_device_minor_number minor,  void                    * arg);rtems_device_driver spacewire_console_write(  rtems_device_major_number major,  rtems_device_minor_number minor,  void                    * arg);rtems_device_driver spacewire_console_control(  rtems_device_major_number major,  rtems_device_minor_number minor,  void                    * arg);#define SPWCEWIRE_CONSOLE_DRIVER_TABLE_ENTRY \  { spacewire_console_initialize, spacewire_console_open, \    spacewire_console_close, spacewire_console_read, \    spacewire_console_write, spacewire_console_control }static rtems_driver_address_table   spacewire_driver = SPWCEWIRE_CONSOLE_DRIVER_TABLE_ENTRY;void spacewire_register() {  rtems_status_code r;  rtems_device_major_number m;  SPACEWIRE_DBG2("register driver\n");  if ((r = rtems_io_register_driver(				    0,				    &spacewire_driver,				    &m)) == RTEMS_SUCCESSFUL) {    SPACEWIRE_DBG2("success\n");  } else {    switch(r) {    case RTEMS_TOO_MANY:      SPACEWIRE_DBG2("failed RTEMS_TOO_MANY\n"); break;    case RTEMS_INVALID_NUMBER:      SPACEWIRE_DBG2("failed RTEMS_INVALID_NUMBER\n"); break;    case RTEMS_RESOURCE_IN_USE:      SPACEWIRE_DBG2("failed RTEMS_RESOURCE_IN_USE\n"); break;    default:      SPACEWIRE_DBG("failed %i\n",r); break;    }  }}#ifdef SPW_BUFMALLOC  void spacewire_buffer_alloc(int minor) {  if (SPW_PARAM(minor).ptr_rxbuf0) {    free(SPW_PARAM(minor).ptr_rxbuf0);  }  if (SPW_PARAM(minor).ptr_txbuf0) {    free(SPW_PARAM(minor).ptr_txbuf0);  }  SPW_PARAM(minor).ptr_rxbuf0 =     (char *) malloc(SPW_PARAM(minor).rxbufsize * SPW_PARAM(minor).rxbufcnt);  SPW_PARAM(minor).ptr_txbuf0 =     (char *) malloc(SPW_PARAM(minor).txbufsize * SPW_PARAM(minor).txbufcnt);}#endif/* *  Console Device Driver Entry Points * */SPACEWIRE_PARAM LEON3_Spacewire[SPACEWIRE_MAX_CORENR];  rtems_device_driver spacewire_console_initialize(  rtems_device_major_number  major,  rtems_device_minor_number  minor,  void                      *arg){  rtems_status_code status;  unsigned int iobar, conf;  int i, uarts;  char *console_name = "/dev/spacewire_a";  SPACEWIRE_DBG2("spacewire driver inizialisation\n");  rtems_termios_initialize();  /* Find spacewire cores */  i = 0; uarts = 0;  while (i < amba_conf.apbslv.devnr && uarts < SPACEWIRE_MAX_CORENR)   {    conf = amba_get_confword(amba_conf.apbslv, i, 0);    if ((amba_vendor(conf) == VENDOR_GAISLER) &&         (amba_device(conf) == GAISLER_SPACEWIRE))    {      iobar = amba_apb_get_membar(amba_conf.apbslv, i);            LEON3_Spacewire[uarts].regs =         (LEON3_SPACEWIRE_Regs_Map *) amba_iobar_start(amba_conf.apbmst, iobar);      LEON3_Spacewire[uarts].irq = amba_irq(conf);      SPACEWIRE_DBG("spacewire code at [0x%x]\n",           (unsigned int)LEON3_Spacewire[uarts].regs);            /* initialize the code with some resonable values,	 actual initialization is done later using ioctl(fd)         on the opened device */      LEON3_Spacewire[uarts].nodeaddr = 0x14;      LEON3_Spacewire[uarts].destkey = 0xBF;      LEON3_Spacewire[uarts].maxfreq = 1;      LEON3_Spacewire[uarts].clkdiv = 0;      LEON3_Spacewire[uarts].rxmaxlen = SPACEWIRE_RXPCK_SIZE;      LEON3_Spacewire[uarts].txbufsize = SPACEWIRE_TXPCK_SIZE;      LEON3_Spacewire[uarts].rxbufsize = SPACEWIRE_RXPCK_SIZE;      LEON3_Spacewire[uarts].txbufcnt = SPACEWIRE_TXBUFS_NR;      LEON3_Spacewire[uarts].rxbufcnt = SPACEWIRE_RXBUFS_NR;#ifndef SPW_BUFMALLOC        LEON3_Spacewire[uarts].ptr_rxbuf0 = &LEON3_Spacewire[uarts]._rxbuf0;      LEON3_Spacewire[uarts].ptr_txbuf0 = &LEON3_Spacewire[uarts]._txbuf0;#else      LEON3_Spacewire[uarts].ptr_rxbuf0 = 0;      LEON3_Spacewire[uarts].ptr_txbuf0 = 0;      spacewire_buffer_alloc(uarts);#endif            uarts++;    }    i++;  }    /*  Register Device Names, /dev/spacewire, /dev/spacewire_b  ... */  if (uarts) {      SPACEWIRE_DBG2("registering minor 0 as /dev/spacewire\n");    status = rtems_io_register_name( "/dev/spacewire", major, 0 );    if (status != RTEMS_SUCCESSFUL)      rtems_fatal_error_occurred(status);    for (i = 1; i < uarts; i++) {      console_name[15]++;      SPACEWIRE_DBG("registering minor %i as %s\n",i,console_name);      status = rtems_io_register_name( console_name, major, i);    }  }    /* Initialize Hardware */  for (i = 0; i < uarts; i++) {    spacewire_hw_init(i);  }    return RTEMS_SUCCESSFUL;}int spacewire_setattibutes(int minor, int nodeaddr, int proto, int dest) {  if ( minor >= SPACEWIRE_MAX_CORENR ) {    printf("minor %i too big\n",minor);    return RTEMS_INVALID_NUMBER;  }  SPW_PARAM(minor).nodeaddr = nodeaddr;  SPW_PARAM(minor).proto = proto;  SPW_PARAM(minor).destnodeaddr = dest;  /*set node address*/  SPW_WRITE(&SPW_REG(minor,nodeaddr),SPW_PARAM(minor).nodeaddr);  return RTEMS_SUCCESSFUL;}rtems_device_driver spacewire_console_open(  rtems_device_major_number major,  rtems_device_minor_number minor,  void                    * arg){  SPACEWIRE_DBGC(DBGSPW_IOCALLS,"open [%i,%i]\n",major, minor);  if ( minor >= SPACEWIRE_MAX_CORENR ) {    SPACEWIRE_DBG("minor %i too big\n",minor);    return RTEMS_INVALID_NUMBER;  }  return spacewire_hw_startup(minor);} rtems_device_driver spacewire_console_close(  rtems_device_major_number major,  rtems_device_minor_number minor,  void                    * arg){  SPACEWIRE_DBGC(DBGSPW_IOCALLS,"close [%i,%i]\n",major, minor);  spacewire_hw_stop(minor);  return RTEMS_SUCCESSFUL;} rtems_device_driver spacewire_console_read(  rtems_device_major_number major,  rtems_device_minor_number minor,  void                    * arg){  rtems_libio_rw_args_t *rw_args;  unsigned32 count = 0;  rw_args = (rtems_libio_rw_args_t *) arg;  SPACEWIRE_DBGC(DBGSPW_IOCALLS,"read  [%i,%i]: buf:0x%x len:%i \n",       major, minor, (unsigned int)rw_args->buffer,rw_args->count);    count =  spacewire_hw_receive(minor,rw_args->buffer,rw_args->count);#ifdef DEBUG_SPACEWIRE_ONOFF    if (DEBUG_SPACEWIRE_FLAGS & DBGSPW_DUMP) {    int k;    for (k = 0;k < count;k++){      if (k % 16 == 0) {	printf ("\n");      }      printf ("%.2x(%c) ",rw_args->buffer[k] & 0xff,         isprint(rw_args->buffer[k] & 0xff) ? rw_args->buffer[k] & 0xff : ' ');    }    printf ("\n");  }#endif    rw_args->bytes_moved = count;  return RTEMS_SUCCESSFUL;  } rtems_device_driver spacewire_console_write(  rtems_device_major_number major,  rtems_device_minor_number minor,  void                    * arg){  rtems_libio_rw_args_t *rw_args;  int count = 0;  rw_args = (rtems_libio_rw_args_t *) arg;  SPACEWIRE_DBGC(DBGSPW_IOCALLS,"write [%i,%i]: buf:0x%x len:%i\n",         major, minor, (unsigned int)rw_args->buffer,rw_args->count);    while (rw_args->count > 0) {    int c = rw_args->count;    if (c > SPW_PARAM(minor).txbufsize-2) {      c = SPW_PARAM(minor).txbufsize-2;    }    spacewire_hw_send(minor,rw_args->buffer,c);    rw_args->count -= c;    rw_args->buffer += c;    count += c;  }    if (count >= 0) {    rw_args->bytes_moved = count;    return RTEMS_SUCCESSFUL;  }  return RTEMS_UNSATISFIED;

⌨️ 快捷键说明

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