Main Page | Modules | File List | Globals | Related Pages

host.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004 by egnite Software GmbH. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00021  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  */
00032 
00033 /*
00034  * $Log$
00035  */
00036 
00037 #include <stdio.h>
00038 #include <io.h>
00039 #include <fcntl.h>
00040 
00041 #ifdef ETHERNUT2
00042 
00043 #include <sys/atom.h>
00044 #include <sys/timer.h>
00045 #include <sys/version.h>
00046 
00047 #include <dev/debug.h>
00048 #include <dev/urom.h>
00049 
00050 #elif defined(_MSC_VER)
00051 
00052 #include <winsock2.h>
00053 
00054 #endif
00055 
00056 #include "xsvf.h"
00057 #include "tapsm.h"
00058 #include "host.h"
00059 
00060 /*!
00061  * \file host.c
00062  * \brief Platform dependant routines..
00063  */
00064 
00065 /*!
00066  * \addtogroup xgHost
00067  */
00068 /*@{*/
00069 
00070 
00071 #ifdef XSVF_DEBUG
00072 
00073 /*!
00074  * \brief XSVF command names.
00075  *
00076  * Used for debugging output.
00077  */
00078 static char *cmd_names[] = {
00079     "XCOMPLETE",
00080     "XTDOMASK",
00081     "XSIR",
00082     "XSDR",
00083     "XRUNTEST",
00084     "UNKNOWN",
00085     "UNKNOWN",
00086     "XREPEAT",
00087     "XSDRSIZE",
00088     "XSDRTDO",
00089     "XSETSDRMASKS",
00090     "XSDRINC",
00091     "XSDRB",
00092     "XSDRC",
00093     "XSDRE",
00094     "XSDRTDOB",
00095     "XSDRTDOC",
00096     "XSDRTDOE",
00097     "XSTATE",
00098     "XENDIR",
00099     "XENDDR",
00100     "XSIR2",
00101     "XCOMMENT",
00102     "XWAIT",
00103     "UNKNOWN"
00104 };
00105 
00106 /*!
00107  * \brief TAP state names.
00108  *
00109  * Used for debugging output.
00110  */
00111 static char *tap_names[] = {
00112     "Test-Logic-Reset",
00113     "Run-Test-Idle",
00114     "Select-DR-Scan",
00115     "Capture-DR",
00116     "Shift-DR",
00117     "Exit1-DR",
00118     "Pause-DR",
00119     "Exit2-DR",
00120     "Update-DR",
00121     "Select-IR-Scan",
00122     "Capute-IR",
00123     "Shift-IR",
00124     "Exit1-IR",
00125     "Pause-IR",
00126     "Exit2-IR",
00127     "Update-IR",
00128     "Unknown"
00129 };
00130 
00131 #endif
00132 
00133 /*!
00134  * \brief Handle of XSVF file.
00135  */
00136 static int fh;
00137 
00138 /*!
00139  * \brief Last error occured in this module.
00140  */
00141 static int xsvf_err;
00142 
00143 /*!
00144  * \brief Initialize the platform dependant interface.
00145  *
00146  * All required hardware initializations should be done in this
00147  * routine. We may also initiate debug output. If the XSVF date
00148  * is located in a file system, then the file will be opened
00149  * here as well.
00150  *
00151  * \return Zero on success, otherwise an error code is returned.
00152  */
00153 int XsvfInit(void)
00154 {
00155 #ifdef ETHERNUT2
00156     u_long baud = 115200;
00157 
00158     /*
00159      * Prepare standard output and display a banner.
00160      */
00161     NutRegisterDevice(&devDebug0, 0, 0);
00162     freopen("uart0", "w", stdout);
00163     _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
00164     printf("\n100 XSVF-Executor " XSVFEXEC_VERSION " on Nut/OS %s", NutVersionString());
00165 
00166     /*
00167      * Register our device for the file system.
00168      */
00169     NutRegisterDevice(&devUrom, 0, 0);
00170 
00171     /*
00172      * Disable JTAG. Ethernut 2 is using
00173      *
00174      * PF4 for target TCK.
00175      * PF5 for target TMS.
00176      * PF6 for target TDI.
00177      * PF7 for target TDO.
00178      */
00179     NutEnterCritical();
00180     outb(MCUCSR, _BV(JTD));
00181     outb(MCUCSR, _BV(JTD));
00182     NutExitCritical();
00183     outb(DDRF, 0x70);
00184 
00185 #elif defined(_WIN32)
00186 
00187     printf("\n100 XSVF-Executor " XSVFEXEC_VERSION " on WIN32");
00188 
00189 #endif
00190 
00191     /* The XSVF file is expected in the UROM file system. */
00192     fh = _open(XSVFNAME, _O_BINARY | _O_RDONLY);
00193 
00194     return (fh == -1) ? XE_DATAUNDERFLOW : 0;
00195 }
00196 
00197 /*!
00198  * \brief Shutdown the platform dependant interface.
00199  *
00200  * On most embedded platforms this routine will never return.
00201  *
00202  * \param rc Programming result code.
00203  */
00204 void XsvfExit(int rc)
00205 {
00206     /* Close XSVF file. */
00207     if(fh != -1) {
00208         _close(fh);
00209     }
00210 
00211     /* Display programming result. */
00212     if(rc) {
00213         printf("\n4%02d ERROR\n", rc);
00214     }
00215     else {
00216         puts("\n199 OK");
00217     }
00218 
00219 #ifdef ETHERNUT2
00220     /* Nut/OS applications never return. */
00221     for (;;);
00222 #endif
00223 }
00224 
00225 /*!
00226  * \brief Retrieve the last error occured in this module.
00227  *
00228  * \return Error code or 0 if no error occured.
00229  */
00230 int XsvfGetError(void)
00231 {
00232     return xsvf_err;
00233 }
00234 
00235 /*!
00236  * \brief Get next byte from XSVF buffer.
00237  *
00238  * Call XsvfGetError() to check for errors,
00239  *
00240  * \return Byte value.
00241  */
00242 u_char XsvfGetByte(void)
00243 {
00244     u_char rc;
00245 
00246     if(_read(fh, &rc, sizeof(rc)) != sizeof(rc)) {
00247         xsvf_err = XE_DATAUNDERFLOW;
00248     }
00249 #ifdef XSVF_DEBUG
00250     printf("[%u]", rc);
00251 #endif
00252 
00253     return rc;
00254 }
00255 
00256 /*!
00257  * \brief Get next command byte from XSVF buffer.
00258  *
00259  * \return XSVF command or XUNKNOWN if an error occured.
00260  */
00261 u_char XsvfGetCmd(void)
00262 {
00263     u_char rc;
00264 
00265     if(_read(fh, &rc, sizeof(rc)) != sizeof(rc) || rc >= XUNKNOWN) {
00266         rc = XUNKNOWN;
00267     }
00268 
00269 #ifdef XSVF_DEBUG
00270     printf("\n2%02d %s", rc, cmd_names[rc]);
00271 #endif
00272 
00273     return rc;
00274 }
00275 
00276 /*!
00277  * \brief Get next byte from XSVF buffer and select a TAP state.
00278  *
00279  * \param state0 Returned state, if the byte value is zero.
00280  * \param state1 Returned state, if the byte value is one.
00281  * 
00282  * \return TAP state or UNKNOWN_STATE if an error occured.
00283  */
00284 u_char XsvfGetState(u_char state0, u_char state1)
00285 {
00286     u_char rc;
00287 
00288     if(_read(fh, &rc, sizeof(rc)) != sizeof(rc) || rc > 1) {
00289         rc = UNKNOWN_STATE;
00290     }
00291     else if(rc) {
00292         rc = state1;
00293     }
00294     else {
00295         rc = state0;
00296     }
00297 
00298 #ifdef XSVF_DEBUG
00299     printf("{%s}", tap_names[rc]);
00300 #endif
00301 
00302     return rc;
00303 }
00304 
00305 /*!
00306  * \brief Get next short value from XSVF buffer.
00307  *
00308  * Call XsvfGetError() to check for errors,
00309  *
00310  * \return Short value.
00311  */
00312 short XsvfGetShort(void)
00313 {
00314     short rc;
00315 
00316     if(_read(fh, &rc, sizeof(rc)) != sizeof(rc)) {
00317         xsvf_err = XE_DATAUNDERFLOW;
00318         return -1;
00319     }
00320     rc = ntohs(rc);
00321 
00322 #ifdef XSVF_DEBUG
00323     printf("[%d]", rc);
00324 #endif
00325 
00326     return rc;
00327 }
00328 
00329 /*!
00330  * \brief Get next long value from XSVF buffer.
00331  *
00332  * Call XsvfGetError() to check for errors,
00333  *
00334  * \return Long value.
00335  */
00336 long XsvfGetLong(void)
00337 {
00338     long rc;
00339 
00340     if(_read(fh, &rc, sizeof(rc)) != sizeof(rc)) {
00341         xsvf_err = XE_DATAUNDERFLOW;
00342         rc = 0;
00343     }
00344     else {
00345         rc = ntohl(rc);
00346     }
00347 
00348 #ifdef XSVF_DEBUG
00349     printf("[%ld]", rc);
00350 #endif
00351 
00352     return rc;
00353 }
00354 
00355 /*!
00356  * \brief Read a specified number of bits from XSVF buffer.
00357  *
00358  * \param buf Pointer to the buffer which receives the bit string.
00359  * \param num Number of bits to read.
00360  *
00361  * \return Error code or 0 if no error occured.
00362  */
00363 int XsvfReadBitString(void *buf, int num)
00364 {
00365     int len = (num + 7) / 8;
00366 
00367     if (len > MAX_BITVEC_BYTES) {
00368         xsvf_err = len = XE_DATAOVERFLOW;
00369     }
00370     else if(_read(fh, buf, len) < len) {
00371         xsvf_err = len = XE_DATAUNDERFLOW;
00372     }
00373 
00374 #ifdef XSVF_DEBUG
00375     else {
00376         u_char *cp = buf;
00377 
00378         printf("[%u:", num);
00379         while(len-- > 0) {
00380             printf("%02X", *cp);
00381             cp++;
00382         }
00383         printf("]");
00384     }
00385 #endif
00386 
00387     return len;
00388 }
00389 
00390 /*!
00391  * \brief Skip comment in the XSVF buffer.
00392  *
00393  * \return Error code or 0 if no error occured.
00394  */
00395 int XsvfSkipComment(void)
00396 {
00397     u_char ch;
00398 
00399     for(;;) {
00400         if(_read(fh, &ch, sizeof(ch)) != sizeof(ch)) {
00401             return (xsvf_err = XE_DATAUNDERFLOW);
00402         }
00403         if(ch == 0) {
00404             break;
00405         }
00406 #ifdef XSVF_DEBUG
00407         putchar(ch);
00408 #endif
00409     }
00410     return 0;
00411 }
00412 
00413 /*!
00414  * \brief Microsecond delay.
00415  *
00416  * \param usecs Number of microseconds.
00417  */
00418 void XsvfDelay(long usecs)
00419 {
00420 #ifdef ETHERNUT2
00421 
00422     usecs = (usecs + 500L) / 1000L;
00423     if(usecs > 63L) {
00424         NutSleep(usecs);
00425     }
00426     else if(usecs) {
00427         NutDelay((u_char)usecs);
00428     }
00429 
00430 #elif defined(_MSC_VER)
00431 
00432     Sleep((usecs + 500L) / 1000L);
00433 
00434 #endif
00435 }
00436 
00437 /*@}*/

© 2004 by egnite Software GmbH - visit http://www.ethernut.de/