/* * Copyright (C) 2004 by Jan Dubiec. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JAN DUBIEC AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JAN DUBIEC * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * $Log$ * Revision 1.2 2005/08/02 17:46:46 haraldkipp * Major API documentation update. * * Revision 1.1 2005/07/26 18:02:40 haraldkipp * Moved from dev. * * Revision 1.1 2004/03/16 16:48:27 haraldkipp * Added Jan Dubiec's H8/300 port. * */ #include /*! * \addtogroup xgNutArchH8300hDevDebug */ /*@{*/ #include #include #include #define SSR_TDRE 0x80 #define SSR_RDRF 0x40 #define SSR_ORER 0x20 #define SSR_FER 0x10 #define SSR_PER 0x08 #define SSR_TEND 0x04 static NUTFILE dbgfile; /* * Returns apropriate H8/300H SCI structure pointer. */ #define GET_SCI(p) ( ((p) == 0) ? &SCI0 : ( ((p) == 1) ? &SCI1 : &SCI2 ) ) /*! * \brief Handle I/O controls for debug device. * * The debug device doesn't support any. * * \return Always -1. */ static int DebugIOCtl(NUTDEVICE * dev, int req, void *conf) { return -1; } /*! * \brief Initialize debug device. * * Simply enable the device. Baudrate divisor set to 7 for * 115.2 kBaud at 22.1184 MHz. * * \return Always 0. */ static int DebugInit(NUTDEVICE * dev) { unsigned short i; volatile struct st_sci *sci = GET_SCI(dev->dev_base); /* serial port initialisation */ sci->SCR.BYTE = 0x00; sci->SMR.BYTE = 0x00; // sci->BRR = 0x47; /* 9600 bps with 22.1184MHz crystal */ sci->BRR = 0x05; /* 115200 bps with 22.1184MHz crystal */ for (i = 0; i < 500; i++); /* wait for a while */ sci->SCR.BYTE = 0x30; sci->SSR.BYTE &= 0x84; return 0; } /*! * \brief Send a single character to debug device. * * A carriage return character will be automatically appended * to any linefeed. */ static void DebugPut(volatile struct st_sci *sci, char ch) { while (!(sci->SSR.BYTE & SSR_TDRE)); /* Wait until TDRE = 1 */ sci->TDR = ch; /* Set transmit data */ sci->SSR.BYTE &= ~SSR_TDRE; if (ch == '\n') DebugPut(sci, '\r'); } /*! * \brief Read a single character from debug device. * * This function waits until a character is received. */ //static int DebugGet(volatile struct st_sci* sci) //{ // unsigned char c; /* clear any detected errors */ // sci->SSR.BYTE &= ~(SSR_ORER | SSR_FER | SSR_PER); /* Clear error bits */ /* wait for a byte */ // while(!( sci->SSR.BYTE & SSR_RDRF)); /* got one-- return it */ // c = sci->RDR; // sci->SSR.BYTE &= ~SSR_RDRF; // return (int) c; //} /*! * \brief Read a single character from debug device. * * Non blocking version of DebugGet(). If I/O operation is pending * this function returns -1. */ static int DebugGetNB(volatile struct st_sci *sci) { unsigned char c; /* clear any detected errors */ if ((sci->SSR.BYTE & (SSR_ORER | SSR_FER | SSR_PER))) { sci->SSR.BYTE &= ~(SSR_ORER | SSR_FER | SSR_PER); /* Clear error bits */ return -1; } /* wait for a byte */ if (!(sci->SSR.BYTE & SSR_RDRF)) return -1; /* got one-- return it */ c = sci->RDR; sci->SSR.BYTE &= ~SSR_RDRF; return (int) c; } /*! * \brief Read one character from debug device. * * This function doesn't wait for a character. If I/O operation is pending, * it returns -1 * \return Number of characters read. */ static int DebugRead(NUTFILE * fp, void *buffer, int len) { int c, l = 0; char *cp = buffer; volatile struct st_sci *sci = GET_SCI(fp->nf_dev->dev_base); while (l < len) { c = DebugGetNB(sci); if (c == -1) { *cp++ = '\0'; return 0; } cp[l++] = (unsigned char) c; } return l; } /*! * \brief Send characters to debug device. * * A carriage return character will be automatically appended * to any linefeed. * * \return Number of characters sent. */ static int DebugWrite(NUTFILE * fp, CONST void *buffer, int len) { int c = len; CONST char *cp = buffer; volatile struct st_sci *sci = GET_SCI(fp->nf_dev->dev_base); while (c--) DebugPut(sci, *cp++); return len; } /*! * \brief Open debug device. * * \return Pointer to a static NUTFILE structure. */ static NUTFILE *DebugOpen(NUTDEVICE * dev, CONST char *name, int mode, int acc) { dbgfile.nf_dev = dev; dbgfile.nf_fcb = NULL; return &dbgfile; } /*! * \brief Close debug device. * * \return Always 0. */ static int DebugClose(NUTFILE * fp) { return 0; } /*! * \brief Debug device information structure. */ NUTDEVICE devDebug0 = { 0, /*!< Pointer to next device. */ {'s', 'c', 'i', '0', 'd', 'b', 'g', 0, 0} , /*!< Unique device name. */ 0, /*!< Type of device. */ 0, /*!< Base address. */ 0, /*!< First interrupt number. */ 0, /*!< Interface control block. */ 0, /*!< Driver control block. */ DebugInit, /*!< Driver initialization routine. */ DebugIOCtl, /*!< Driver specific control function. */ DebugRead, DebugWrite, /* Write from program space data to device. */ DebugOpen, DebugClose, 0, 0, /*!< Select function, optional, not yet implemented */ }; NUTDEVICE devDebug1 = { 0, /*!< Pointer to next device. */ {'s', 'c', 'i', '1', 'd', 'b', 'g', 0, 0} , /*!< Unique device name. */ 0, /*!< Type of device. */ 1, /*!< Base address. */ 0, /*!< First interrupt number. */ 0, /*!< Interface control block. */ 0, /*!< Driver control block. */ DebugInit, /*!< Driver initialization routine. */ DebugIOCtl, /*!< Driver specific control function. */ DebugRead, DebugWrite, /* Write from program space data to device. */ DebugOpen, DebugClose, 0, 0, /*!< Select function, optional, not yet implemented */ }; NUTDEVICE devDebug2 = { 0, /*!< Pointer to next device. */ {'s', 'c', 'i', '2', 'd', 'b', 'g', 0, 0} , /*!< Unique device name. */ 0, /*!< Type of device. */ 2, /*!< Base address. */ 0, /*!< First interrupt number. */ 0, /*!< Interface control block. */ 0, /*!< Driver control block. */ DebugInit, /*!< Driver initialization routine. */ DebugIOCtl, /*!< Driver specific control function. */ DebugRead, DebugWrite, /* Write from program space data to device. */ DebugOpen, DebugClose, 0, 0, /*!< Select function, optional, not yet implemented */ }; /*@}*/