• Main Page
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

mComm.c

Go to the documentation of this file.
00001 /*************************************************************************
00002  *  © 2012 Microchip Technology Inc.                                       
00003  *  
00004  *  Project Name:    mTouch Framework v2.1
00005  *  FileName:        mComm.c
00006  *  Dependencies:    mComm.h
00007  *  Processor:       See documentation for supported PIC® microcontrollers 
00008  *  Compiler:        HI-TECH Ver. 9.81 or later
00009  *  IDE:             MPLAB® IDE v8.50 (or later) or MPLAB® X                        
00010  *  Hardware:         
00011  *  Company:         
00012  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00013  *  Description:     
00014  *************************************************************************/
00015 /**************************************************************************
00016  * MICROCHIP SOFTWARE NOTICE AND DISCLAIMER: You may use this software, and 
00017  * any derivatives created by any person or entity by or on your behalf, 
00018  * exclusively with Microchip's products in accordance with applicable
00019  * software license terms and conditions, a copy of which is provided for
00020  * your referencein accompanying documentation. Microchip and its licensors 
00021  * retain all ownership and intellectual property rights in the 
00022  * accompanying software and in all derivatives hereto. 
00023  * 
00024  * This software and any accompanying information is for suggestion only. 
00025  * It does not modify Microchip's standard warranty for its products. You 
00026  * agree that you are solely responsible for testing the software and 
00027  * determining its suitability. Microchip has no obligation to modify, 
00028  * test, certify, or support the software. 
00029  * 
00030  * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER 
00031  * EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED 
00032  * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A 
00033  * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE, ITS INTERACTION WITH 
00034  * MICROCHIP'S PRODUCTS, COMBINATION WITH ANY OTHER PRODUCTS, OR USE IN ANY 
00035  * APPLICATION. 
00036  * 
00037  * IN NO EVENT, WILL MICROCHIP BE LIABLE, WHETHER IN CONTRACT, WARRANTY, 
00038  * TORT (INCLUDING NEGLIGENCE OR BREACH OF STATUTORY DUTY), STRICT 
00039  * LIABILITY, INDEMNITY, CONTRIBUTION, OR OTHERWISE, FOR ANY INDIRECT, 
00040  * SPECIAL, PUNITIVE, EXEMPLARY, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, 
00041  * FOR COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, 
00042  * HOWSOEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY 
00043  * OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT ALLOWABLE BY LAW, 
00044  * MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS 
00045  * SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID 
00046  * DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. 
00047  * 
00048  * MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF 
00049  * THESE TERMS. 
00050  *************************************************************************/
00054 #include "mTouch.h"
00055 #include "mComm.h"
00056 
00057 #if defined(MCOMM_ENABLED)
00058 
00059     //========================================================================
00060     // GLOBAL VARIABLES
00061     //========================================================================
00062     #if defined(MCOMM_TWO_WAY_ENABLED)
00063     mComm_OutputVector  mComm_output;
00064     mComm_InputBuffer   mComm_input;
00065     #endif
00066     
00067     #if defined(MCOMM_ONE_WAY_ENABLED)
00068     #if (MCOMM_UART_1WAY_MODULE == MCOMM_UART_SOFTWARE_IMPLEMENTATION)
00069     bank0 uint8_t       mComm_shiftReg;
00070     bank0 uint8_t       mComm_bitCount;
00071     bank0 uint8_t       mComm_delayCount;
00072     #endif
00073     #endif
00074     
00075     //========================================================================
00076     // FUNCTION PROTOTYPES
00077     //========================================================================
00078         void    mComm_Init              (void);
00079     
00080     #if defined(MCOMM_TWO_WAY_ENABLED)
00081         void    mComm_Receive           (void);
00082         void    mComm_Process           (uint8_t);
00083     #endif
00084     
00085     #if defined(MCOMM_UART_IMPLEMENTED)
00086         void    mComm_Service           (void);
00087         void    mComm_UART_PutChar      (uint8_t);
00088     #if defined(MCOMM_ONE_WAY_ENABLED)
00089         void    mComm_UART_Char2ASCII   (uint8_t);
00090         void    mComm_UART_Int2ASCII    (uint16_t);
00091     #else
00092         void    mComm_UART_SendACKorNACK(uint8_t);
00093     #endif
00094     #endif
00095     
00096     
00097     /*********************************************************************************
00098     *             ____                              ___       _ _   
00099     *  _ __ ___  / ___|___  _ __ ___  _ __ ___     |_ _|_ __ (_) |_ 
00100     * | '_ ` _ \| |   / _ \| '_ ` _ \| '_ ` _ \     | || '_ \| | __|
00101     * | | | | | | |__| (_) | | | | | | | | | | |    | || | | | | |_ 
00102     * |_| |_| |_|\____\___/|_| |_| |_|_| |_| |_|___|___|_| |_|_|\__|
00103     *                                         |_____|  
00104     *
00105     *   Initializes the variables and communication module registers to prepare for 
00106     *   the first packet to be sent/received.
00107     *********************************************************************************/
00108     void mComm_Init()
00109     {    
00110         //===========================
00111         // Variable Initialization
00112         //===========================
00113         #if defined(MCOMM_TWO_WAY_ENABLED)
00114             mComm_input.index           = 0;                //===========================
00115             mComm_input.counter         = 0;                // Initialize input buffer
00116             mComm_input.checksum        = 0;                //===========================
00117             #if defined(MCOMM_UART_IMPLEMENTED) || defined(MCOMM_SPI_IMPLEMENTED)
00118             mComm_input.state           = 0;
00119             #endif
00120             mComm_input.flags.all       = 0x00;
00121             
00122             for (int8_t i = MCOMM_INPUTBUFFER_SIZE-1; i >= 0; i--)
00123             {
00124                 mComm_input.buffer[i]   = 0;
00125             }
00126         
00127             mComm_output.flags.all      = 0x00;             //===========================
00128             mComm_output.counter        = 0;                // Initialize output buffer
00129             mComm_output.latch          = 0;                //===========================
00130             mComm_output.iterator       = 0x0000;
00131             mComm_output.vector.pointer = 0x0000;
00132             mComm_output.vector.length  = 0;
00133             
00134             
00135             #if defined(MCOMM_ENABLE_STREAM)
00136             #if defined(MCOMM_STREAM_EN_ON_POR)
00137             mComm_streamConfig.enabled  = 1;                //===========================
00138             #else                                           // Initialize stream feature
00139             mComm_streamConfig.enabled  = 0;                //===========================
00140             #endif
00141             mComm_streamConfig.go       = 0;                
00142             mComm_streamConfig.index    = 0;                
00143             #endif
00144         #endif
00145         
00146         //===========================
00147         // Hardware Initialization
00148         //===========================
00149         #if defined(MCOMM_UART_IMPLEMENTED)
00150         
00151             #if (MCOMM_TYPE == MCOMM_UART_ONE_WAY) && (MCOMM_UART_1WAY_MODULE == MCOMM_UART_SOFTWARE_IMPLEMENTATION)
00152             
00153                 //==============================
00154                 // Software UART Initialization
00155                 //==============================
00156             
00157             asm("BANKSEL    "   ___mkstr(       __paste(_,MCOMM_UART_SOFT_TXPORT)));
00158             asm("bsf        "   ___mkstr(NOBANK(__paste(_,MCOMM_UART_SOFT_TXPORT))) ", " ___mkstr(MCOMM_UART_SOFT_TXPIN));
00159             
00160             asm("BANKSEL    "   ___mkstr(       __paste(_,MCOMM_UART_SOFT_TXTRIS)));
00161             asm("bcf        "   ___mkstr(NOBANK(__paste(_,MCOMM_UART_SOFT_TXTRIS))) ", " ___mkstr(MCOMM_UART_SOFT_TXPIN));
00162             
00163             #else
00164             
00165                 //==============================
00166                 // Hardware UART Initialization
00167                 //==============================
00168                 
00169             MCOMM_UART_TXSTA    = 0;   
00170             MCOMM_UART_RCSTA    = 0;    
00171             MCOMM_UART_BAUDCON  = 0;    
00172                 
00173             MCOMM_UART_SPBRGL   = MCOMM_UART_SPBRGL_VALUE;
00174             #if defined(MCOMM_UART_SPBRGH_AVAILABLE)
00175             MCOMM_UART_SPBRGH   = MCOMM_UART_SPBRGH_VALUE;
00176             MCOMM_UART_BRG16    = MCOMM_UART_BRG16_VALUE;
00177             #endif
00178             MCOMM_UART_BRGH     = MCOMM_UART_BRGH_VALUE;
00179                         
00180             MCOMM_UART_TXEN     = 1;            // Enable transmission
00181             MCOMM_UART_SPEN     = 1;            // Enable serial port
00182             #if (MCOMM_TYPE != MCOMM_UART_ONE_WAY)
00183             MCOMM_UART_CREN     = 1;            // Enable continuous reception            
00184             MCOMM_UART_RCIE     = 1;            // Turn on UART Receive interrupts
00185             #endif
00186             MCOMM_UART_PEIE     = 1;            // Turn on peripheral interrupts
00187             
00188             #endif
00189             
00190         #elif defined(MCOMM_I2C_IMPLEMENTED)
00191     
00192                 //=============================
00193                 // Hardware I2C Initialization
00194                 //=============================
00195                 
00196             MCOMM_I2C_SSPSTAT = 0b10000000;     // SMP: Slew rate control disabled for standard speed mode.
00197                                                 // CKE: Disable SMBus specific inputs
00198             MCOMM_I2C_SSPCON1 = 0b00110110;     // WCOL: Write Collision bit cleared
00199                                                 // SSPOV: Receive Overflow bit cleared
00200                                                 // SSPEN: Serial Port enabled
00201                                                 // CKP: Clock line released
00202                                                 // SSPM: I2C Slave mode, 7-bit address
00203             MCOMM_I2C_SSPCON2 = 0b00000001;     // GCEN: General call disabled
00204                                                 // SEN: Clock stretching is enabled for both slave transmit and slave receive
00205             MCOMM_I2C_SSPCON3 = 0b00000011;     // SCIE: Start condition interrupt is disabled
00206                                                 // BOEN: Buffer overwrite is disabled
00207                                                 // SDAHT: Minimum of 100ns hold time on SDA after the falling edge of SCL
00208                                                 // SBCDE: Slave mode bus collision detection interrupts are disabled
00209                                                 // AHEN: Address holding enabled   - CLOCK STRETCHING
00210                                                 // DHEN: Data holding enabled      - CLOCK STRETCHING
00211                                                 
00212             MCOMM_I2C_SSPMSK  = 0b11111110;     // Address Mask
00213             MCOMM_I2C_SSPADD  = MCOMM_I2C_ADDRESS;
00214             
00215             MCOMM_I2C_SSPIE   = 1;              // Turn on I2C slave interrupts
00216             MCOMM_I2C_PEIE    = 1;              // Turn on peripheral interrupts
00217         
00218             // NOTE:
00219             // SDA pin must be input
00220             // SCL pin must be input
00221         
00222         #elif defined(MCOMM_SPI_IMPLEMENTED)
00223         
00224             MCOMM_SPI_SSPSTAT = 0b00000000;     // SMP: Cleared for slave mode
00225                                                 // CKE: Tramsmit occurs on transition from idle to active clock state
00226                                                 // BF: Buffer full bit cleared
00227             MCOMM_SPI_SSPCON1 = 0b00100100;     // WCOL: Write Collection bit cleared
00228                                                 // SSPOV: Receive overflow bit cleared
00229                                                 // SSPEN: Serial Port enabled
00230                                                 // CKP: Idle state for clock is low
00231                                                 // SSPM: SPI Slave mode, nSS pin enabled
00232             MCOMM_SPI_SSPCON3 = 0b00000000;     // BOEN: Buffer overwrite disabled
00233             
00234             MCOMM_SPI_SSPIE   = 1;              // Turn on SPI slave interrupts
00235             MCOMM_SPI_PEIE    = 1;              // Turn on peripheral interrupts
00236             
00237             // NOTE:
00238             // SDI pin must be input
00239             // SDO pin must be output
00240             // SCK pin must be input (slave)
00241             // nSS pin must be input
00242     
00243         #endif
00244     }
00245 
00246     
00247     
00248     
00249     #if defined(MCOMM_TWO_WAY_ENABLED)
00250     /*********************************************************************************
00251     *
00252     *             ____                              ____               _           
00253     *  _ __ ___  / ___|___  _ __ ___  _ __ ___     |  _ \ ___  ___ ___(_)_   _____ 
00254     * | '_ ` _ \| |   / _ \| '_ ` _ \| '_ ` _ \    | |_) / _ \/ __/ _ \ \ \ / / _ \
00255     * | | | | | | |__| (_) | | | | | | | | | | |   |  _ <  __/ (_|  __/ |\ V /  __/
00256     * |_| |_| |_|\____\___/|_| |_| |_|_| |_| |_|___|_| \_\___|\___\___|_| \_/ \___|
00257     *                                         |_____|   
00258     *
00259     *   This is the common function across all communication types that receives a
00260     *   new byte from the hardware module. The received bytes are stored in the
00261     *   input buffer and provided to the application only after a correct checksum
00262     *   has been evaluated.
00263     *********************************************************************************/
00264     void mComm_Receive()
00265     {
00266         uint8_t data;                                   // Stores the received byte
00267         
00268         
00269         
00270     #if defined(MCOMM_UART_IMPLEMENTED)
00271     
00272         //===========================
00273         //  _   _   _    ____ _____ 
00274         // | | | | / \  |  _ \_   _|
00275         // | | | |/ _ \ | |_) || |  
00276         // | |_| / ___ \|  _ < | |  
00277         //  \___/_/   \_\_| \_\|_|  
00278         //
00279         //===========================
00280         
00281         data = MCOMM_UART_RCREG;
00282         
00283         if ((data == 0x00) && (FERR == 1))
00284         {
00285             /**************************************************************
00286             * 1. 'Break' character received. Start of new packet.
00287             **************************************************************/
00288             mComm_input.state     = MCOMM_START;
00289             return;
00290         }       
00291        
00292         if (MCOMM_UART_OERR)
00293         {
00294             /**************************************************************
00295             * UART overrun error has occurred. Reset the state machine and
00296             * the hardware module and then exit.
00297             **************************************************************/
00298             MCOMM_UART_CREN = 0;
00299             asm("NOP");
00300             asm("NOP");
00301             MCOMM_UART_CREN = 1;
00302             mComm_input.state     = MCOMM_IDLE;
00303             return;
00304         }
00305         else if (mComm_input.state == MCOMM_START)
00306         {
00307             /**************************************************************
00308             * 2. Get the byte count to determine the expected packet length
00309             *    and initialize the counter and index variables.
00310             **************************************************************/
00311             mComm_input.counter     = data;             // Store packet length
00312             mComm_input.index       = 0;                // Reset buffer index
00313             mComm_input.checksum    = 0;                // Reset checksum value
00314             mComm_input.state       = MCOMM_BUFFER;
00315             return;
00316         } 
00317         else if (mComm_input.state == MCOMM_BUFFER)
00318         {
00319             /**************************************************************
00320             * 3. Knowing the packet length, buffer all incoming data. Also,
00321             *    keep a running calculation of the checksum.
00322             **************************************************************/
00323             mComm_input.buffer[mComm_input.index] = data;
00324 
00325             if (--mComm_input.counter == 0)
00326             {
00327                 mComm_input.state       = MCOMM_PROCESS_DATA;
00328             } 
00329             else
00330             {  
00331                 mComm_input.index++;
00332             }
00333             mComm_input.checksum ^= data;
00334         }
00335         else
00336         {
00337             /**************************************************************
00338             * Invalid packet received. Reset the state machine.
00339             **************************************************************/
00340             mComm_input.state         = MCOMM_IDLE;
00341             return;
00342         }
00343 
00344         
00345         if (mComm_input.state == MCOMM_PROCESS_DATA)
00346         {
00347             /**************************************************************
00348             * 4. Complete packet received. Reset the state machine and set
00349             *    a flag to process the buffer's data.
00350             **************************************************************/
00351             if (mComm_input.checksum == 0)
00352             {
00353                 mComm_input.flags.bits.full = 1;
00354             }
00355             else
00356             {
00357                 mComm_input.flags.bits.invalid = 1;
00358             }
00359             mComm_input.state = MCOMM_IDLE;
00360         }
00361         
00362     // end - defined(MCOMM_UART_IMPLEMENTED)
00363     #elif defined(MCOMM_I2C_IMPLEMENTED)
00364     
00365    
00366         //===========================
00367         //  ___ ____   ____ 
00368         // |_ _|___ \ / ___|
00369         //  | |  __) | |    
00370         //  | | / __/| |___ 
00371         // |___|_____|\____|
00372         //
00373         //===========================
00374 
00375         MCOMM_I2C_SSPIF = 0;
00376         
00377         
00378         if (MCOMM_I2C_RnW)          // Read or Write?
00379         {   
00380         
00381             mComm_input.flags.bits.write = 0;       // Set 'read' flag.    
00382             
00383             if (mComm_input.checksum == 0)          // Respond only if 'write' request
00384             {                                       //  checksum is valid.
00385             
00386                 if (!MCOMM_I2C_DnA)                 // Special case: Address Byte
00387                 {
00388                     /**************************************************************
00389                     * Read Address
00390                     *   This code is executed if the master sent a read address
00391                     *   in the last byte of the communication. Using this to
00392                     *   initialize variables for the new output stream.
00393                     **************************************************************/
00394                     mComm_output.checksum   = 0;
00395                     mComm_Process(mComm_input.buffer[0]);
00396                 }
00397                 
00398                 /**************************************************************
00399                 * Read 
00400                 *   This code is executed to output the requested data to the
00401                 *   master. The pointer has already been set up, so this code
00402                 *   simply outputs it until the byteCounter reaches zero.
00403                 **************************************************************/
00404                 if (mComm_output.flags.bits.hasNext)  
00405                 {
00406                     data = mComm_output.iterator();     // Get next output value
00407                     mComm_output.checksum ^= data;      // Update checksum calculation
00408                 } else {
00409                     data = mComm_output.checksum;       // Last byte sent is checksum
00410                 }
00411                 
00412                 do {
00413                     MCOMM_I2C_WCOL = 0;     // Clear write-collision flag
00414                     
00415                     // Output data to I2C bus
00416                     if (!MCOMM_I2C_CKP)     
00417                         MCOMM_I2C_SSPBUF = data;
00418                         
00419                 } while (MCOMM_I2C_WCOL);   // Retry if failed until successful
00420 
00421                 MCOMM_I2C_SSPOV = 0;        // Clearing overflow flag
00422                 MCOMM_I2C_CKP = 1;          // Stop clock stretching and allow
00423                                             //    the master to begin clocking
00424                                             //    out the new data in SSPBUF.
00425             } // end: Valid Checksum
00426         }
00427         else        // Read or Write?   Write.
00428         {         
00429 
00430             mComm_input.flags.bits.write = 1;
00431         
00432             if (MCOMM_I2C_DnA)              
00433             {                           
00434                 
00435                 /**************************************************************
00436                 * Write Data
00437                 *   This state is called when we are receiving data from the
00438                 *   master. This might be an opcode, an address, a payload
00439                 *   value, or a checksum.
00440                 **************************************************************/
00441                 data = MCOMM_I2C_SSPBUF;                        // Store the received data
00442                 mComm_input.buffer[mComm_input.index] = data;   // Insert into buffer
00443                 mComm_input.checksum ^= data;                   // Update checksum
00444                 mComm_input.index++;                            // Increment index
00445                 
00446             }
00447             else                            
00448             {                           
00449             
00450                 /**************************************************************
00451                 * Write Address
00452                 *   This state is called when a new packet is being received.
00453                 **************************************************************/
00454                 mComm_input.index       = 0;    // Reset the packet's byte counter
00455                 mComm_input.checksum    = 0;    // Reset the packet's checksum value
00456                 data = MCOMM_I2C_SSPBUF;        // Store the received I2C address to clear SSPBUF
00457                 
00458             }   // end DnA
00459             
00460             if (MCOMM_I2C_SSPOV)        // If an overflow condition was detected.
00461             {                           //    If this has affected the integrity
00462                 MCOMM_I2C_SSPOV = 0;    //    of the message, we will see from the
00463             }                           //    checksum and length of the packet.
00464         }   // end RnW
00465         
00466         
00467         if (MCOMM_I2C_STOP && mComm_input.flags.bits.write) // If we've stopped after a write
00468         {                                                   //  request, execute the write.
00469             /**************************************************************
00470             * Packet complete. Validate checksum, then provide the data 
00471             * to the application layer.
00472             **************************************************************/
00473             if (mComm_input.checksum == 0)
00474             {
00475                 MCOMM_I2C_SSPADD = MCOMM_I2C_ADDRESS_BUSY;  // Change I2C Address to stop writes
00476                 
00477                 mComm_Process(mComm_input.buffer[0]);       // Write Response
00478                 while (mComm_output.iterator());            // Execute writes
00479                 
00480                 MCOMM_I2C_SSPADD = MCOMM_I2C_ADDRESS;       // Change I2C Address back on
00481             }
00482         }
00483         
00484     // end - defined(MCOMM_I2C_IMPLEMENTED)
00485     #elif defined(MCOMM_SPI_IMPLEMENTED)
00486     
00487         //===========================
00488         //  ____  ____ ___ 
00489         // / ___||  _ \_ _|
00490         // \___ \| |_) | | 
00491         //  ___) |  __/| | 
00492         // |____/|_|  |___|
00493         // 
00494         //===========================    
00495         
00496         MCOMM_SPI_SSPIF = 0;
00497         data = MCOMM_SPI_SSPBUF;
00498         
00499         if (mComm_input.state == MCOMM_SPI_START)
00500         {
00501             /**************************************************************
00502             * 1. 'CS' pin just activated. Start of new packet.
00503             **************************************************************/
00504             if (data == MCOMM_SPI_ADDRESS)  {   mComm_input.state == MCOMM_SPI_PACKET_LENGTH;   MCOMM_SPI_SSPBUF = MCOMM_OP_ACK;    }
00505             else                            {   mComm_input.state == MCOMM_SPI_IDLE;            MCOMM_SPI_SSPBUF = data;            }
00506             return;
00507         }
00508         else if (mComm_input.state == MCOMM_SPI_PACKET_LENGTH)
00509         {
00510             /**************************************************************
00511             * 2. Store the length of the packet and initialize the packet data.
00512             **************************************************************/
00513             mComm_input.state       = MCOMM_SPI_BUFFER;
00514             mComm_input.counter     = data;             // Store packet length
00515             mComm_input.index       = 0;                // Reset buffer index
00516             mComm_input.checksum    = 0;                // Reset checksum value
00517             MCOMM_SPI_SSPBUF        = 0x00;
00518             return;
00519         }
00520         else if (mComm_input.state == MCOMM_SPI_BUFFER)
00521         {
00522             /**************************************************************
00523             * 3. Knowing the packet length, buffer all incoming data. Also,
00524             *    keep a running calculation of the checksum.
00525             **************************************************************/
00526             mComm_input.buffer[mComm_input.index] = data;
00527 
00528             if (--mComm_input.counter == 0)
00529             {
00530                 mComm_input.state   = MCOMM_SPI_PROCESS_DATA;
00531             } 
00532             else
00533             {  
00534                 mComm_input.index++;
00535             }
00536             mComm_input.checksum ^= data;
00537         }
00538         else if (mComm_input.state == MCOMM_SPI_IDLE)
00539         {
00540             /**************************************************************
00541             * Invalid packet. 
00542             **************************************************************/
00543             MCOMM_SPI_SSPBUF    = data;
00544             return;
00545         }
00546 
00547         
00548         if (mComm_input.state == MCOMM_SPI_PROCESS_DATA)
00549         {
00550             /**************************************************************
00551             * 4. Complete packet received. Reset the state machine and 
00552             *    process the buffer's data.
00553             **************************************************************/
00554             if (mComm_input.checksum == 0)
00555             {
00556                 mComm_Process(mComm_input.buffer[0]);
00557                 
00558                 if (!(mComm_input.buffer[0] & 0x01))        // If 'write' command
00559                 {
00560                     while (mComm_output.iterator());        // Execute writes    
00561                     MCOMM_SPI_SSPBUF    = MCOMM_OP_ACK;     // Output 0xAA
00562                     mComm_input.state   = MCOMM_SPI_IDLE;   // Reset state machine
00563                     return;
00564                 }
00565                 mComm_input.state = MCOMM_SPI_OUTPUT;       // If 'read' command, output data
00566             }
00567         }
00568         
00569         if (mComm_input.state == MCOMM_SPI_OUTPUT)
00570         {
00571             /**************************************************************
00572             * 5. Master is expecting data. Find the next byte to output
00573             *    and place it in the SSP module's buffer register.
00574             **************************************************************/
00575 
00576             if (mComm_output.flags.bits.hasNext)  
00577             {
00578                 data = mComm_output.iterator();
00579                 mComm_output.checksum ^= data;
00580             } else {
00581                 data = mComm_output.checksum;
00582             }
00583             
00584             do {
00585                 MCOMM_SPI_WCOL = 0;         // Clear write-collision flag
00586                 MCOMM_SPI_SSPBUF = data;    // Output data to SPI bus
00587             } while (MCOMM_SPI_WCOL);       // Retry if failed until successful
00588 
00589             MCOMM_SPI_SSPOV = 0;            // Clearing overflow flag
00590             return;
00591         }
00592         
00593         MCOMM_SPI_SSPBUF    = 0x00;
00594         
00595     #endif // end - defined(MCOMM_SPI_IMPLEMENTED)
00596     }
00597     
00598     
00599     #if defined(MCOMM_SPI_IMPLEMENTED)
00600     void mComm_SPI_ServiceSS(void)
00601     {
00602         if (MCOMM_SPI_IOCIF)
00603         {
00604             MCOMM_SPI_IOCIF  = 0;
00605             if (mComm_input.flags.bits.ssLatch != MCOMM_SPI_SS_PIN)     // Latch does not match actual value
00606             {
00607                 if (mComm_input.flags.bits.ssLatch == 1)                // If we were not selected, but now are
00608                     mComm_input.state = MCOMM_SPI_START;                // Begin a new packet
00609                     
00610                 mComm_input.flags.bits.ssLatch = MCOMM_SPI_SS_PIN;      // Reset latch value
00611             }
00612         }
00613     }
00614     #endif // end - defined(MCOMM_SPI_IMPLEMENTED)
00615     
00616     #endif // end - defined(MCOMM_TWO_WAY_ENABLED)
00617     
00618 
00619     /*********************************************************************************
00620     *
00621     *             ____                              ____                  _          
00622     *  _ __ ___  / ___|___  _ __ ___  _ __ ___     / ___|  ___ _ ____   _(_) ___ ___ 
00623     * | '_ ` _ \| |   / _ \| '_ ` _ \| '_ ` _ \    \___ \ / _ \ '__\ \ / / |/ __/ _ \
00624     * | | | | | | |__| (_) | | | | | | | | | | |    ___) |  __/ |   \ V /| | (_|  __/
00625     * |_| |_| |_|\____\___/|_| |_| |_|_| |_| |_|___|____/ \___|_|    \_/ |_|\___\___|
00626     *                                         |_____| 
00627     *
00628     *   When implementing the mComm module through the UART, this
00629     *   service function should be called to process any fully-
00630     *   received packets and output the stream if the 'enabled'
00631     *   and 'go' bits are set in its configuration register.
00632     *********************************************************************************/
00633     #if defined(MCOMM_UART_IMPLEMENTED)
00634     void mComm_Service()
00635     {
00636     
00637         //===========================
00638         //  _   _   _    ____ _____ 
00639         // | | | | / \  |  _ \_   _|
00640         // | | | |/ _ \ | |_) || |  
00641         // | |_| / ___ \|  _ < | |  
00642         //  \___/_/   \_\_| \_\|_|  
00643         //
00644         //===========================
00645         #if defined(MCOMM_TWO_WAY_ENABLED)
00646         union
00647         {
00648             uint8_t     all;
00649             
00650             struct 
00651             {
00652                 unsigned R_nW           :1;
00653                 unsigned processInput   :1;
00654                 unsigned invalidInput   :1;
00655                 unsigned run            :1;
00656                 #if defined(MCOMM_ENABLE_CUSTOM_OPCODE)
00657                 unsigned processCustom  :1;
00658                 #endif
00659             } flags;
00660         } mode;                         // This temporary structure holds all
00661                                         //  flags for this function in 8-bits.
00662 
00663         uint8_t data;        
00664         mode.all = 0;                   // Clear all flags.
00665         
00666         if (mComm_input.flags.bits.invalid == 1)                    //===========================
00667         {                                                           // Invalid Packet
00668             mComm_input.flags.all = 0;                              //===========================
00669             mComm_UART_SendACKorNACK(MCOMM_OP_NACK);                // NACK
00670         }
00671       
00672         #if defined(MCOMM_ENABLE_STREAM)
00673         if (mComm_streamConfig.go && mComm_streamConfig.enabled)    //===========================
00674         {                                                           // Stream ready for output
00675             mode.flags.run              = 1;                        //===========================
00676             mode.flags.R_nW             = 1;  
00677         }
00678         #endif
00679         
00680         #if defined(MCOMM_ENABLE_CUSTOM_OPCODE)                     
00681         if (MCOMM_CUSTOM_CALLBACK())                                //================================
00682         {                                                           // Custom packet ready for output
00683             mode.flags.run              = 1;                        //================================
00684             mode.flags.R_nW             = 1;
00685             mode.flags.processCustom    = 1;
00686         }
00687         #endif
00688         
00689         if (mComm_input.flags.bits.full)                            //================================
00690         {                                                           // Input ready for processing
00691             mode.flags.run              = 1;                        //================================
00692             mode.flags.R_nW             = mComm_input.buffer[0] & 0x01;
00693             mode.flags.processInput     = 1;
00694             #if defined(MCOMM_ENABLE_CUSTOM_OPCODE)
00695             mode.flags.processCustom    = 0;
00696             #endif
00697         }
00698       
00699         if (mode.flags.run)     // If there is something to be output by the UART...
00700         {
00701             //=============================
00702             // Initialize the Iterator
00703             //=============================
00704             #if defined(MCOMM_ENABLE_STREAM) || defined(MCOMM_ENABLE_CUSTOM_OPCODE)
00705             if (mode.flags.processInput)
00706             {
00707             #endif
00708                 mComm_Process(mComm_input.buffer[0]);
00709             #if defined(MCOMM_ENABLE_STREAM) || defined(MCOMM_ENABLE_CUSTOM_OPCODE)
00710             }
00711             else
00712             {
00713                 #if defined(MCOMM_ENABLE_STREAM) && defined(MCOMM_ENABLE_CUSTOM_OPCODE)
00714                 if (mode.flags.processCustom)
00715                 {
00716                     mComm_Process(MCOMM_OP_CUSTOM_READ);
00717                 } else {
00718                     mComm_Process(MCOMM_OP_STREAM_READ);
00719                 }
00720                 #else
00721                     #if defined(MCOMM_ENABLE_STREAM)
00722                     mComm_Process(MCOMM_OP_STREAM_READ);
00723                     #else
00724                     mComm_Process(MCOMM_OP_CUSTOM_READ);
00725                     #endif
00726                 #endif
00727             }
00728             #endif
00729         
00730             //=============================
00731             // Execute
00732             //=============================
00733             if (mode.flags.R_nW)    // Read
00734             {
00735                 mComm_output.checksum = 0;
00736             
00737                 if (mComm_output.flags.bits.hasNext)        // Send BREAK character
00738                 {
00739                     TXSTAbits.SENDB = 1;
00740                     TXREG           = 0x00;
00741                     while(TXSTAbits.SENDB);
00742                 }
00743                 
00744                 while (mComm_output.flags.bits.hasNext)     // Execute reads. Send data.
00745                 {
00746                     data = mComm_output.iterator();             
00747                     mComm_UART_PutChar(data);
00748                     if (mComm_output.flags.bits.second == 0)
00749                     {
00750                         mComm_output.checksum ^= data;
00751                     }
00752                 }
00753                 mComm_UART_PutChar(mComm_output.checksum);  // Send checksum.
00754             }
00755             else    // Write
00756             {
00757                 while (mComm_output.iterator());            // Execute writes.
00758                 mComm_UART_SendACKorNACK(MCOMM_OP_ACK);     // Send ACK.
00759             }
00760             
00761             //=============================
00762             // Clean-Up
00763             //=============================
00764             #if defined(MCOMM_ENABLE_STREAM)
00765             if (mode.flags.processInput)
00766             {
00767             #endif
00768                 mComm_input.flags.bits.full = 0;            // Reset 'full' input buffer flag
00769             #if defined(MCOMM_ENABLE_STREAM)
00770             }
00771             else
00772             {
00773                 #if defined(MCOMM_ENABLE_STREAM) && defined(MCOMM_ENABLE_CUSTOM_OPCODE)
00774                 if (!mode.flags.processCustom)
00775                 {
00776                     mComm_streamConfig.go = 0;              // Reset 'go' stream flag
00777                 }
00778                 #else
00779                     #if defined(MCOMM_ENABLE_STREAM)
00780                     mComm_streamConfig.go = 0;
00781                     #endif
00782                 #endif
00783             }
00784             #endif
00785         }
00786         #endif // end - defined(MCOMM_TWO_WAY_ENABLED)
00787         
00788         #if defined(MCOMM_ONE_WAY_ENABLED)
00789         
00790             
00791             // OUTPUT LOGIC FOR ONE-WAY COMMUNICATIONS.
00792             
00793             // mComm_UART_Int2ASCII()  converts a 16-bit value to ASCII and outputs it using mComm_UART_PutChar()
00794             // mComm_UART_Char2ASCII() converts an 8-bit value to ASCII and outputs it using mComm_UART_PutChar()
00795             
00796             #if defined(MCOMM_UART_1WAY_OUT_STATE)
00797             mComm_UART_Int2ASCII((uint16_t)mTouch_stateMask);
00798             #else
00799             mComm_UART_Int2ASCII(0);
00800             #endif
00801             
00802             #if defined(MCOMM_UART_1WAY_OUT_TOGGLE) && defined(MTOUCH_TOGGLE_ENABLED)
00803             mComm_UART_Int2ASCII((uint16_t)mTouch_toggle);
00804             #else
00805             mComm_UART_Int2ASCII(0);
00806             #endif
00807             
00808             #if defined(MCOMM_UART_1WAY_OUT_SLIDER) && defined(MTOUCH_NUMBER_OF_SLIDERS) && (MTOUCH_NUMBER_OF_SLIDERS > 0)
00809             mComm_UART_Char2ASCII(mTouch_slider[0]);            
00810             #else
00811             mComm_UART_Char2ASCII(0);
00812             #endif
00813 
00814             #if defined(MCOMM_UART_1WAY_OUT_MATRIX) && defined(MTOUCH_MATRIX_ENABLED)
00815             mComm_UART_PutChar('(');
00816             if (mTouch_Matrix_isPressed())
00817             {
00818                 mComm_UART_PutChar((uint8_t)(mTouch_Matrix_getColumn()) + 0x30);
00819                 mComm_UART_PutChar(':');
00820                 mComm_UART_PutChar((uint8_t)(mTouch_Matrix_getRow())    + 0x30);
00821             }
00822             else
00823             {
00824                 mComm_UART_PutChar('x');
00825                 mComm_UART_PutChar(':');
00826                 mComm_UART_PutChar('x');
00827             }
00828             mComm_UART_PutChar(')');
00829             mComm_UART_PutChar(MCOMM_UART_1WAY_DELIMITER);
00830             #endif
00831             
00832             #if defined(MCOMM_UART_1WAY_OUT_READING) || defined(MCOMM_UART_1WAY_OUT_BASELINE)
00833             for (uint8_t i = 0; i < MTOUCH_NUMBER_SENSORS; i++)
00834             {
00835                 #if defined(MCOMM_UART_1WAY_OUT_READING)
00836                 mComm_UART_Int2ASCII(mTouch_GetSensor(i));      
00837                 #endif                                          
00838                 #if defined(MCOMM_UART_1WAY_OUT_BASELINE)
00839                 mComm_UART_Int2ASCII(mTouch_GetAverage(i));     
00840                 #endif
00841             }
00842             #endif
00843             
00844             mComm_UART_PutChar(0x0D);   // CR                   
00845             mComm_UART_PutChar(0x0A);   // LF
00846         
00847         #endif
00848     }
00849     #endif // end - defined(MCOMM_UART_IMPLEMENTED)
00850 
00851     
00852     #if defined(MCOMM_TWO_WAY_ENABLED)
00853     /*********************************************************************************
00854     *             ____                              ____                              
00855     *  _ __ ___  / ___|___  _ __ ___  _ __ ___     |  _ \ _ __ ___   ___ ___  ___ ___ 
00856     * | '_ ` _ \| |   / _ \| '_ ` _ \| '_ ` _ \    | |_) | '__/ _ \ / __/ _ \/ __/ __|
00857     * | | | | | | |__| (_) | | | | | | | | | | |   |  __/| | | (_) | (_|  __/\__ \__ \
00858     * |_| |_| |_|\____\___/|_| |_| |_|_| |_| |_|___|_|   |_|  \___/ \___\___||___/___/
00859     *                                         |_____|            
00860     *
00861     *   Interprets the master's request (stored in the input buffer), initializes 
00862     *   the output structure, and iterator variables.
00863     *
00864     *   This is performed using a lookup table of function pointers with the opcode
00865     *   parameter behaving as the index of the lookup. 
00866     *********************************************************************************/
00867     void mComm_Process(uint8_t opcode)
00868     {    
00869         //=============================
00870         // Valid Opcode
00871         //=============================
00872         if (opcode < MCOMM_NUMBER_OPCODES)              
00873         {
00874             mComm_output.flags.all          = 0x00;     // Reset output vector's flags
00875             mComm_output.flags.bits.first   = 1;
00876             mComm_output.flags.bits.hasNext = 1;
00877             
00878             mComm_output.counter    = 0;                // Reset output vector's variables
00879             mComm_output.latch      = 0;
00880             mComm_output.opcode     = opcode;
00881             mComm_output.iterator   = mComm_opcode[opcode].iterator;
00882             
00883             mComm_opcode[opcode].initialize();          // Initialize the iterator
00884             return;
00885         }
00886         
00887         //=============================
00888         // Invalid Opcode
00889         //=============================
00890         mComm_output.iterator = &mComm_ErrorIterator;   
00891     }
00892     #endif // end - defined(MCOMM_TWO_WAY_ENABLED)
00893     
00894     
00895     /*********************************************************************************
00896     *  _   _      _                   _____                 _   _                 
00897     * | | | | ___| |_ __   ___ _ __  |  ___|   _ _ __   ___| |_(_) ___  _ __  ___ 
00898     * | |_| |/ _ \ | '_ \ / _ \ '__| | |_ | | | | '_ \ / __| __| |/ _ \| '_ \/ __|
00899     * |  _  |  __/ | |_) |  __/ |    |  _|| |_| | | | | (__| |_| | (_) | | | \__ \
00900     * |_| |_|\___|_| .__/ \___|_|    |_|   \__,_|_| |_|\___|\__|_|\___/|_| |_|___/
00901     *              |_|                                              
00902     *********************************************************************************/
00903     #if defined(MCOMM_UART_IMPLEMENTED)
00904     
00905         #if defined(MCOMM_TWO_WAY_ENABLED)
00906         void mComm_UART_SendACKorNACK(uint8_t opcode)
00907         {
00908             while(MCOMM_UART_TXIF == 0);  
00909             TXSTAbits.SENDB = 1;
00910             TXREG           = 0x00;
00911             while(TXSTAbits.SENDB);         // BREAK
00912             mComm_UART_PutChar(0x02);       // Packet Length
00913             mComm_UART_PutChar(opcode);     // Acknowledge
00914             mComm_UART_PutChar(opcode);     // Checksum
00915         }    
00916         #endif
00917         
00918         // Performs the steps required to output 8-bits of data to the Tx pin of the
00919         //  microcontroller. If a UART hardware module is being used, this is simple.
00920         //  If the software will be bit-banging the data, the timing is critical so
00921         //  an assembly-coded list of instructions will run the output.
00922         void mComm_UART_PutChar(uint8_t data)
00923         {
00924             #if defined(MCOMM_TWO_WAY_ENABLED) || (MCOMM_UART_1WAY_MODULE == MCOMM_UART_HARDWARE_MODULE)
00925             
00926                 while(MCOMM_UART_TXIF == 0);     
00927                 MCOMM_UART_TXREG = data;
00928                 
00929             #else
00930                 
00931                 #pragma regsused mComm_UART_PutChar wreg status fsr0
00932                 
00933                 mComm_shiftReg = data;   
00934                 
00935                 #if defined(_PIC14E)        // Implementation if using an enhanced-core PIC16F1 device
00936                 asm("   movlw LOW  " ___mkstr(NOBANK(__paste(_,MCOMM_UART_SOFT_TXPORT))));
00937                 asm("   movwf      " ___mkstr(_FSR0L)                );
00938                 asm("   movlw HIGH " ___mkstr(NOBANK(__paste(_,MCOMM_UART_SOFT_TXPORT))));
00939                 asm("   movwf      " ___mkstr(_FSR0H)                ); 
00940                 asm("   BANKSEL    _mComm_bitCount                  "); 
00941                 asm("   movlw      0x08                             "); 
00942                 asm("   movwf      _mComm_bitCount                  "); 
00943                 asm("   bcf        " ___mkstr(_INDF0) ", " ___mkstr(MCOMM_UART_SOFT_TXPIN));                                 
00944                 asm("   fcall      MCOMM_UART_BITDELAY              "); 
00945                 asm("   ljmp       $+1                              "); 
00946                 asm("   nop                                         "); 
00947                 asm("MCOMM_UART_TXNEXTBIT:                          "); 
00948                 asm("   rrf        _mComm_shiftReg, F               "); 
00949                 asm("   btfss      " ___mkstr(NOBANK(_STATUS))  ", 0"); 
00950                 asm("   ljmp       MCOMM_UART_TXZERO                "); 
00951                 asm("MCOMM_UART_TXONE:                              "); 
00952                 asm("   nop                                         "); 
00953                 asm("   bsf        " ___mkstr(_INDF0) ", " ___mkstr(MCOMM_UART_SOFT_TXPIN));
00954                 asm("   fcall      MCOMM_UART_BITDELAY              "); 
00955                 asm("   decfsz     _mComm_bitCount, F               "); 
00956                 asm("   ljmp       MCOMM_UART_TXNEXTBIT             "); 
00957                 asm("   ljmp       MCOMM_UART_TXSTOP                "); 
00958                 asm("MCOMM_UART_TXZERO:                             "); 
00959                 asm("   bcf        " ___mkstr(_INDF0) ", " ___mkstr(MCOMM_UART_SOFT_TXPIN));                    
00960                 asm("   fcall      MCOMM_UART_BITDELAY              "); 
00961                 asm("   decfsz     _mComm_bitCount, F               "); 
00962                 asm("   ljmp       MCOMM_UART_TXNEXTBIT             "); 
00963                 asm("   ljmp       MCOMM_UART_TXSTOP                "); 
00964                 asm("MCOMM_UART_TXSTOP:                             "); 
00965                 asm("   ljmp       $+1                              "); 
00966                 asm("   nop                                         "); 
00967                 asm("   bsf        " ___mkstr(_INDF0) ", " ___mkstr(MCOMM_UART_SOFT_TXPIN));
00968                 asm("   fcall      MCOMM_UART_BITDELAY              "); 
00969                 asm("   return                                      "); 
00970                 asm("MCOMM_UART_BITDELAY:                           "); 
00971                 asm("   movlw      0x04                             "); 
00972                 asm("   sublw      " ___mkstr(MCOMM_UART_FWBRG_VALUE)); 
00973                 asm("   movwf      _mComm_delayCount                "); 
00974                 asm("MCOMM_UART_BITWAITLOOP:                        "); 
00975                 asm("   nop                                         "); 
00976                 asm("MCOMM_UART_BITWAIT:                            "); 
00977                 asm("   decfsz     _mComm_delayCount, F             "); 
00978                 asm("   ljmp       MCOMM_UART_BITWAITLOOP           "); 
00979                 asm("   ljmp       $+1                              "); 
00980                 asm("   return                                      "); 
00981                 #elif defined(_PIC14)       // Implementation if using a non-enhanced core PIC12/16F device                                          
00982                 asm("   movlw LOW  "   ___mkstr(NOBANK(__paste(_,MCOMM_UART_SOFT_TXPORT)))); 
00983                 asm("   movwf      "   ___mkstr(_FSR)                ); 
00984                 asm("   BANKSEL    _mComm_shiftReg                  "); 
00985                 asm("   movlw      8                                "); 
00986                 asm("   movwf      _mComm_bitCount                  "); 
00987                 asm("   bcf " ___mkstr(_INDF) ", " ___mkstr(MCOMM_UART_SOFT_TXPIN));                                          
00988                 asm("   fcall      MCOMM_UART_BITDELAY              "); 
00989                 asm("   ljmp       $+1                              "); 
00990                 asm("   nop                                         "); 
00991                 asm("MCOMM_UART_TXNEXTBIT:                          "); 
00992                 asm("   rrf    _mComm_shiftReg, F                   "); 
00993                 asm("   btfss  "   ___mkstr(NOBANK(_STATUS))    ", 0"); 
00994                 asm("   ljmp       MCOMM_UART_TXZERO                "); 
00995                 asm("MCOMM_UART_TXONE:                              "); 
00996                 asm("   nop                                         "); 
00997                 asm("   bsf " ___mkstr(_INDF) ", " ___mkstr(MCOMM_UART_SOFT_TXPIN));                      
00998                 asm("   fcall      MCOMM_UART_BITDELAY              "); 
00999                 asm("   decfsz     _mComm_bitCount, F        "); 
01000                 asm("   ljmp       MCOMM_UART_TXNEXTBIT             "); 
01001                 asm("   ljmp       MCOMM_UART_TXSTOP                "); 
01002                 asm("MCOMM_UART_TXZERO:                             "); 
01003                 asm("   bcf " ___mkstr(_INDF) ", " ___mkstr(MCOMM_UART_SOFT_TXPIN));                          
01004                 asm("   fcall      MCOMM_UART_BITDELAY              "); 
01005                 asm("   decfsz     _mComm_bitCount, F        "); 
01006                 asm("   ljmp       MCOMM_UART_TXNEXTBIT             "); 
01007                 asm("   ljmp       MCOMM_UART_TXSTOP                "); 
01008                 asm("MCOMM_UART_TXSTOP:                             "); 
01009                 asm("   ljmp       $+1                              "); 
01010                 asm("   nop                                         "); 
01011                 asm("   bsf " ___mkstr(_INDF) ", " ___mkstr(MCOMM_UART_SOFT_TXPIN));                            
01012                 asm("   fcall      MCOMM_UART_BITDELAY              "); 
01013                 asm("   return                                      "); 
01014                 asm("MCOMM_UART_BITDELAY:                           "); 
01015                 asm("   movlw      4                                "); 
01016                 asm("   sublw  "   ___mkstr(MCOMM_UART_FWBRG_VALUE)  ); 
01017                 asm("   movwf      _mComm_delayCount                "); 
01018                 asm("MCOMM_UART_BITWAITLOOP:                        "); 
01019                 asm("   nop                                         "); 
01020                 asm("MCOMM_UART_BITWAIT:                            "); 
01021                 asm("   decfsz     _mComm_delayCount, F             "); 
01022                 asm("   ljmp       MCOMM_UART_BITWAITLOOP           "); 
01023                 asm("   ljmp       $+1                              "); 
01024                 asm("   return                                      "); 
01025                 #endif
01026                 
01027             #endif
01028         }
01029         
01030         #if (MCOMM_TYPE == MCOMM_UART_ONE_WAY)
01031         // Converts an 8-bit value into ASCII and then uses the mComm_UART_PutChar() 
01032         //  function to transmit it to the master. A delimiter character is added to
01033         //  the end automatically.
01034         void mComm_UART_Char2ASCII(uint8_t output)
01035         {
01036             #if (MCOMM_UART_1WAY_OUTPUT == MCOMM_UART_1WAY_HEX)
01037             
01038                 uint8_t nibble;
01039             
01040                 #define MCOMM_UART_OUTPUT_NIBBLE(value, shift)                      \
01041                     nibble = (uint8_t) value >> shift;                              \
01042                     if (nibble <= 9) { nibble += 0x30; } else { nibble += 0x37; }   \
01043                     mComm_UART_PutChar(nibble);
01044                     
01045                 MCOMM_UART_OUTPUT_NIBBLE(output, 4);
01046                 MCOMM_UART_OUTPUT_NIBBLE(output, 0);
01047                 
01048                 #undef MCOMM_UART_OUTPUT_NIBBLE
01049                 
01050             #else
01051             
01052                 uint8_t digit = 0;
01053                 while (output >= 100)  { output -= 100; digit++; } mComm_UART_PutChar(digit + 0x30); digit = 0;
01054                 while (output >=  10)  { output -=  10; digit++; } mComm_UART_PutChar(digit + 0x30); digit = 0;
01055                 while (output >=   1)  { output -=   1; digit++; } mComm_UART_PutChar(digit + 0x30);
01056                 
01057             #endif
01058             
01059             #if defined(MCOMM_UART_1WAY_OUT_GUIv1_1)
01060             mComm_UART_PutChar(',');
01061             #else
01062             mComm_UART_PutChar(MCOMM_UART_1WAY_DELIMITER);
01063             #endif
01064         }
01065         
01066         
01067         // Converts a 16-bit value into ASCII and then uses the mComm_UART_PutChar() 
01068         //  function to transmit it to the master. A delimiter character is added to
01069         //  the end automatically.
01070         void mComm_UART_Int2ASCII(uint16_t output)
01071         {
01072             
01073             #if (MCOMM_UART_1WAY_OUTPUT == MCOMM_UART_1WAY_HEX)
01074                 
01075                 uint8_t nibble;
01076             
01077                 #define MCOMM_UART_OUTPUT_NIBBLE(value, shift)                      \
01078                     nibble = (uint8_t) value >> shift;                              \
01079                     if (nibble <= 9) { nibble += 0x30; } else { nibble += 0x37; }   \
01080                     mComm_UART_PutChar(nibble);
01081             
01082                 MCOMM_UART_OUTPUT_NIBBLE(output, 12);
01083                 MCOMM_UART_OUTPUT_NIBBLE(output, 8);
01084                 MCOMM_UART_OUTPUT_NIBBLE(output, 4);
01085                 MCOMM_UART_OUTPUT_NIBBLE(output, 0);
01086                 
01087                 #undef MCOMM_UART_OUTPUT_NIBBLE
01088                 
01089             #else
01090             
01091                 uint8_t digit = 0;
01092                 while (output >= 10000) { output -= 10000; digit++; } mComm_UART_PutChar(digit + 0x30); digit = 0;
01093                 while (output >=  1000) { output -=  1000; digit++; } mComm_UART_PutChar(digit + 0x30); digit = 0;
01094                 while (output >=   100) { output -=   100; digit++; } mComm_UART_PutChar(digit + 0x30); digit = 0;
01095                 while (output >=    10) { output -=    10; digit++; } mComm_UART_PutChar(digit + 0x30); digit = 0;
01096                 while (output >=     1) { output -=     1; digit++; } mComm_UART_PutChar(digit + 0x30);
01097                 
01098             #endif
01099             
01100             mComm_UART_PutChar(MCOMM_UART_1WAY_DELIMITER);
01101         }
01102         
01103         #endif
01104         
01105         
01106     #endif
01107     
01108 #endif

mTouch Framework v2.1 documentation by  Click here to visit our website at www.microchip.com