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

📄 dapa.c

📁 用于传感器网络的节点操作系统 TinyOS 结构设计非常有意思
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	DAPA.C	Direct AVR Parallel Access (c) 1999		Originally written by Sergey Larin.	Corrected by 	  Denis Chertykov, 	  Uros Platise and 	  Marek Michalkiewicz*/#ifndef NO_DAPA//#define DEBUG#include <stdio.h>#include <stdlib.h>#include <errno.h>#ifndef NO_DIRECT_IO/* Linux and FreeBSD differ in the order of outb() arguments.   XXX any other OS/architectures with PC-style parallel ports?   XXX how about the other *BSDs?  */#if defined(__linux__) && defined(__i386__)#include <sys/io.h>#define ioport_read(port)         inb(port)#define ioport_write(port, val)   outb(val, port)#define ioport_enable(port, num)  ioperm(port, num, 1)#define ioport_disable(port, num) ioperm(port, num, 0)#elif defined(__CYGWIN__)#include "cygwinp.h"#define ioport_read(port)         inb(port)#define ioport_write(port, val)   outb(val, port)#define ioport_enable(port, num)  ioperm(port, num, 1)#define ioport_disable(port, num) ioperm(port, num, 0)#elif defined(__FreeBSD__) && defined(__i386__)#include <sys/fcntl.h>#include <machine/cpufunc.h>#include <machine/sysarch.h>#define ioport_read(port)         inb(port)#define ioport_write(port, val)   outb(port, val)#define ioport_enable(port, num)  i386_set_ioperm(port, num, 1)#define ioport_disable(port, num) i386_set_ioperm(port, num, 0)#else/* Direct I/O port access not supported - ppdev/ppi kernel driver   required for parallel port support to work at all.  Only likely to   work on PC-style parallel ports (all signals implemented) anyway.   The only lines believed to be implemented in all parallel ports are:	D0-D6 outputs	(long long ago I heard of some non-PC machine with			D7 hardwired to GND - don't remember what it was)	BUSY input   So far, only the dt006 interface happens to use a subset of the above.	STROBE output might be pulsed by hardware and not be writable	ACK input might only trigger an interrupt and not be readable   Future designers of these "dongles" might want to keep this in mind. */#define ioport_read(port)         (0xFF)#define ioport_write(port, val)#define ioport_enable(port, num)  (-1)#define ioport_disable(port, num) (0)#endif#endif /* NO_DIRECT_IO */#include <unistd.h>#include <signal.h>#include "timeradd.h"#include <sys/ioctl.h>#include <fcntl.h>#include "parport.h"/* These should work on any architecture, not just i386.  */#if defined(__linux__)#include "ppdev.h"#define par_claim(fd)            ioctl(fd, PPCLAIM, 0)#define par_read_status(fd, ptr) ioctl(fd, PPRSTATUS, ptr)#define par_write_data(fd, ptr)  ioctl(fd, PPWDATA, ptr)#define par_write_ctrl(fd, ptr)  ioctl(fd, PPWCONTROL, ptr)#define par_set_dir(fd, ptr)     ioctl(fd, PPDATADIR, ptr)#define par_release(fd)          ioctl(fd, PPRELEASE, 0)#elif defined(__FreeBSD__)#include </sys/dev/ppbus/ppi.h>#define par_claim(fd)            (0)#define par_read_status(fd, ptr) ioctl(fd, PPIGSTATUS, ptr)#define par_write_data(fd, ptr)  ioctl(fd, PPISDATA, ptr)#define par_write_ctrl(fd, ptr)  ioctl(fd, PPISCTRL, ptr)/* par_set_dir not defined, par_write_ctrl used instead */#define par_release(fd)          (0)#else/* Dummy defines if ppdev/ppi not supported by the kernel.  */#define par_claim(fd)            (-1)#define par_read_status(fd, ptr)#define par_write_data(fd, ptr)#define par_write_ctrl(fd, ptr)#define par_release(fd)          #endif#include "Global.h"#include "Error.h"#include "DAPA.h"#include "Avr.h"/* Parallel Port Base Address*/#define IOBASE parport_base#define IOSIZE 3/* FIXME: rewrite using tables to define new interface types.   For each of the logical outputs (SCK, MOSI, RESET, ENA1, ENA2,   power, XTAL1) there should be two bit masks that define which   physical bits (from the parallel port output data or control   registers, or serial port DTR/RTS/TXD) are affected, and if   they should be inverted.  More than one output may be changed.   For each of the inputs (MISO, maybe TEST?), define which bit   (only one, from parallel port status or CTS/DCD/DSR/RI) should   be tested and if it should be inverted.   One struct as described above should be initialized for each   of the supported hardware interfaces. *//* Alex's Direct Avr Parallel Access */#define DAPA_SCK    PARPORT_CONTROL_STROBE	/* base + 2 */#define DAPA_RESET  PARPORT_CONTROL_INIT	/* base + 2 */#define DAPA_DIN    PARPORT_STATUS_BUSY		/* base + 1 */#define DAPA_DOUT   0x1		/* base *//* STK200 Direct Parallel Access */#define STK2_TEST1  0x01	/* D0 (base) - may be connected to POUT input */#define STK2_TEST2  0x02	/* D1 (base) - may be connected to BUSY input */#define STK2_ENA1   0x04    	/* D2 (base) - ENABLE# for RESET#, MISO */#define STK2_ENA2   0x08    	/* D3 (base) - ENABLE# for SCK, MOSI, LED# */#define STK2_SCK    0x10    	/* D4 (base) - SCK */#define STK2_DOUT   0x20    	/* D5 (base) - MOSI */#define STK2_LED    0x40	/* D6 (base) - LED# (optional) */#define STK2_RESET  0x80    	/* D7 (base) - RESET# */#define STK2_DIN    PARPORT_STATUS_ACK    	/* ACK (base + 1) - MISO *//* Altera Byte Blaster Port Configuration*/#define ABB_EN      PARPORT_CONTROL_AUTOFD	/* low active */#define ABB_LPAD    0x80	/* D7: loop back throught enable auto-detect */#define ABB_SCK	    0x01	/* D0: TCK */#define ABB_RESET   0x02	/* D1: TMS */#define ABB_DOUT    0x40	/* D6: TDI */#define ABB_DIN	    PARPORT_STATUS_BUSY	/* BUSY: TDO *//* D5 (pin 7) connected to ACK (pin 10) directly *//* D7 (pin 9) connected to POUT (pin 12) via 74HC244 buffer *//* optional modification for AVREAL: D3 (pin 5) = XTAL1 */#define ABB_XTAL1   0x08/* "Atmel AVR ISP" cable (?) */#define AISP_TSTOUT 0x08	/* D3 (base) - dongle test output */#define AISP_SCK    0x10	/* D4 (base) - SCK */#define AISP_DOUT   0x20	/* D5 (base) - MOSI */#define AISP_ENA    0x40	/* D6 (base) - ENABLE# for MISO, MOSI, SCK */#define AISP_RESET  0x80	/* D7 (base) - RESET# */#define AISP_DIN    PARPORT_STATUS_ACK /* ACK (base + 1) - MISO *//* BUSY and POUT used as inputs to test for the dongle *//* Yet another AVR ISP cable from http://www.bsdhome.com/avrprog/ */#define BSD_POWER   0x0F	/* D0-D3 (base) - power */#define BSD_ENA     0x10	/* D4 (base) - ENABLE# */#define BSD_RESET   0x20	/* D5 (base) - RESET# */#define BSD_SCK     0x40	/* D6 (base) - SCK */#define BSD_DOUT    0x80	/* D7 (base) - MOSI */#define BSD_DIN     PARPORT_STATUS_ACK /* ACK (base + 1) - MISO *//* optional status LEDs, active low, not yet supported (base + 2) */#define BSD_LED_ERR PARPORT_CONTROL_STROBE  /* error */#define BSD_LED_RDY PARPORT_CONTROL_AUTOFD  /* ready */#define BSD_LED_PGM PARPORT_CONTROL_INIT    /* programming */#define BSD_LED_VFY PARPORT_CONTROL_SELECT  /* verifying *//*   FBPRG - http://ln.com.ua/~real/avreal/adapters.html*/#define FBPRG_POW    0x07	/* D0,D1,D2 (base) - power supply (XXX D7 too?) */#define FBPRG_XTAL1  0x08	/* D3 (base) (not supported) */#define FBPRG_RESET  0x10	/* D4 (base) */#define FBPRG_DOUT   0x20	/* D5 (base) */#define FBPRG_SCK    0x40	/* D6 (base) */#define FBPRG_DIN    PARPORT_STATUS_ACK /* ACK (base + 1) - MISO *//* DT006/Sample Electronics Parallel Cable   http://www.dontronics.com/dt006.html*//* all at base, except for DT006_DIN at base + 1 */#define DT006_SCK    0x08#define DT006_RESET  0x04#define DT006_DIN    PARPORT_STATUS_BUSY#define DT006_DOUT   0x01/* Default value for minimum SCK high/low time in microseconds.  */#ifndef SCK_DELAY#define SCK_DELAY 5#endif/* Minimum RESET# high time in microseconds.   Should be enough to charge a capacitor between RESET# and GND   (it is recommended to use a voltage detector with open collector   output, and only something like 100 nF for noise immunity).  */#ifndef RESET_HIGH_TIME#define RESET_HIGH_TIME 1000#endif/* Delay from RESET# low to sending program enable command   (the datasheet says it must be at least 20 ms).  Also wait time   for crystal oscillator to start after possible power down mode.  */#ifndef RESET_LOW_TIME#define RESET_LOW_TIME 30000#endifvoidTDAPA::SckDelay(){  Delay_usec(t_sck);}#ifndef MIN_SLEEP_USEC#define MIN_SLEEP_USEC 20000#endifvoidTDAPA::Delay_usec(long t){#if defined(__CYGWIN__)  if (cygwinp_delay_usec(t)){    return;  }#endif  struct timeval t1, t2;  if (t <= 0)    return;  /* very short delay for slow machines */  gettimeofday(&t1, NULL);  if (t > MIN_SLEEP_USEC)    usleep(t - MIN_SLEEP_USEC);  /* loop for the remaining time */  t2.tv_sec = t / 1000000UL;  t2.tv_usec = t % 1000000UL;  timeradd(&t1, &t2, &t1);  do {    gettimeofday(&t2, NULL);  } while (timercmp(&t2, &t1, <));}voidTDAPA::ParportSetDir(int dir){  if (dir)    par_ctrl |= PARPORT_CONTROL_DIRECTION;  else    par_ctrl &= ~PARPORT_CONTROL_DIRECTION;  if (ppdev_fd != -1) {#ifdef par_set_dir    par_set_dir(ppdev_fd, &dir);#else    par_write_ctrl(ppdev_fd, &par_ctrl);#endif  } else    ioport_write(IOBASE+2, par_ctrl);}voidTDAPA::ParportWriteCtrl(){  if (ppdev_fd != -1)    par_write_ctrl(ppdev_fd, &par_ctrl);  else    ioport_write(IOBASE+2, par_ctrl);}voidTDAPA::ParportWriteData(){  if (ppdev_fd != -1)    par_write_data(ppdev_fd, &par_data);  else    ioport_write(IOBASE, par_data);}voidTDAPA::ParportReadStatus(){  if (ppdev_fd != -1)    par_read_status(ppdev_fd, &par_status);  else    par_status = ioport_read(IOBASE+1);}voidTDAPA::SerialReadCtrl(){#ifdef TIOCMGET  ioctl(ppdev_fd, TIOCMGET, &ser_ctrl);#else  ser_ctrl = 0;#endif}voidTDAPA::SerialWriteCtrl(){#ifdef TIOCMGET  ioctl(ppdev_fd, TIOCMSET, &ser_ctrl);#endif}voidTDAPA::OutReset(int b){  switch (pa_type) {  case PAT_DAPA:  case PAT_DAPA_2:    if (b) par_ctrl |= DAPA_RESET; else par_ctrl &= ~DAPA_RESET;    ParportWriteCtrl();    break;  case PAT_STK200:    if (b) par_data |= STK2_RESET; else par_data &= ~STK2_RESET;    ParportWriteData();    break;  case PAT_ABB:    if (b) par_data |= ABB_RESET; else par_data &= ~ABB_RESET;    ParportWriteData();    break;  case PAT_AVRISP:    if (b) par_data |= AISP_RESET; else par_data &= ~AISP_RESET;    ParportWriteData();    break;  case PAT_BSD:    if (b) par_data |= BSD_RESET; else par_data &= BSD_RESET;    ParportWriteData();    break;  case PAT_FBPRG:    if (b) par_data |= FBPRG_RESET; else par_data &= ~FBPRG_RESET;    ParportWriteData();    break;  case PAT_DT006:    if (b) par_data |= DT006_RESET; else par_data &= ~DT006_RESET;    ParportWriteData();    break;#ifdef TIOCMGET  case PAT_DASA:    SerialReadCtrl();    if (b) ser_ctrl |= TIOCM_RTS; else ser_ctrl &= ~TIOCM_RTS;    SerialWriteCtrl();    break;  case PAT_DASA2:    ioctl(ppdev_fd, b ? TIOCSBRK : TIOCCBRK, 0);    break;#else  case PAT_DASA:  case PAT_DASA2:    break;#endif /* TIOCMGET */  }  Delay_usec(b ? RESET_HIGH_TIME : RESET_LOW_TIME);}voidTDAPA::OutSck(int b){  switch (pa_type) {  case PAT_DAPA:  case PAT_DAPA_2:    if (b) par_ctrl &= ~DAPA_SCK; else par_ctrl |= DAPA_SCK;    ParportWriteCtrl();    break;  case PAT_STK200:    if (b) par_data |= STK2_SCK; else par_data &= ~STK2_SCK;    ParportWriteData();    break;  case PAT_ABB:    if (b) par_data |= ABB_SCK; else par_data &= ~ABB_SCK;    ParportWriteData();    break;  case PAT_AVRISP:    if (b) par_data |= AISP_SCK; else par_data &= ~AISP_SCK;    ParportWriteData();    break;  case PAT_BSD:    if (b) par_data |= BSD_SCK; else par_data &= ~BSD_SCK;    ParportWriteData();    break;  case PAT_FBPRG:    if (b) par_data |= FBPRG_SCK; else par_data &= ~FBPRG_SCK;    ParportWriteData();    break;  case PAT_DT006:    if (b) par_data |= DT006_SCK; else par_data &= ~DT006_SCK;    ParportWriteData();    break;#ifdef TIOCMGET  case PAT_DASA:    SerialReadCtrl();    if (b) ser_ctrl |= TIOCM_DTR; else ser_ctrl &= ~TIOCM_DTR;    SerialWriteCtrl();    break;  case PAT_DASA2:    SerialReadCtrl();    if (b) ser_ctrl |= TIOCM_RTS; else ser_ctrl &= ~TIOCM_RTS;    SerialWriteCtrl();    break;#else  case PAT_DASA:  case PAT_DASA2:    break;#endif /* TIOCMGET */  }}voidTDAPA::OutEnaReset(int b){  bool no_ps2_hack = GetCmdParam("-dno-ps2-hack", false);  switch (pa_type) {  case PAT_DAPA:  case PAT_DAPA_2:  case PAT_FBPRG:  case PAT_DT006:    if (b) {      ParportSetDir(0);    } else if (!no_ps2_hack) {      /* No special enable line on these interfaces, for PAT_DAPA         this only disables the data line (MOSI) and not SCK.  */

⌨️ 快捷键说明

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