Microchip C32 UART library example (modified)

I’ve modified the original UART example that comes with the Microchip C32 compiler to easily handle different UART’s along with adding a compare function that compares what is recieved over the UART to a pre-defined set of characters. See the description in the source below for more.

Download the source as a text file here: UART_Library_Interface_Example

/*********************************************************************
  UART Library Interface Example

  Summary:
    This file contains the interface definition for the UART peripheral
    library.
    
  Description:
    This library provides a low-level abstraction of the UART (Universal 
    Asynchronous Receiver/Transmtter) module on Microchip PIC32MX family 
    microcontrollers with a convenient C language interface.  It can be
    used to simplify low-level access to the module without the
    necessity of interacting directly with the module's registers, thus
    hiding differences from one microcontroller variant to another.

 Modifications:
    This version has been modified from the original by Trevor
    (http://electronics.trev.id.au) to allow use of the functions with
    multiple UART's. The three functions
        * SendDataBuffer,
        * GetMenuChoice,
        * GetDataBuffer
    now reqiure the UART id to be the first variable passed to
    the function (eg: GetMenuChoice(UART1);)
    Also added a buffer compare function to allow comparison of what is
    recieved. Key point to note with the compare, the buffer is not 
    a \0 terminated string.
 Testing modifications:
    This has been tested on the chipKIT Max32 from Digilent using 
    UART1 -> FTDI chip -> PC. The source is compiled using
    MPLAB X IDE v1.10 and programmed into the device using an MPLAB
    ICD3. Compiler was the Microchip C32 v2.02.

**********************************************************************/
//DOM-IGNORE-BEGIN
/*********************************************************************
FileName:       main.c
Dependencies:   See includes
Processor:      PIC32MX

Complier:       Microchip MPLAB C32 v1.06 or higher
Company:        Microchip Technology Inc.

Copyright © 2008-2009 released Microchip Technology Inc.  All
rights reserved.
Modifications as described above are Copyright © 2012 released
by Trevor van der Linden. All rights reserved.

The modifications have the same license terms as the original
Microchip license, with the exception that where it states Microchip,
it should be read as Trevor van der Linden.

Microchip licenses to you the right to use, modify, copy and distribute
Software only when embedded on a Microchip microcontroller or digital
signal controller that is integrated into your product or third party
product (pursuant to the sublicense terms in the accompanying license
agreement).

You should refer to the license agreement accompanying this Software
for additional information regarding your rights and obligations.

SOFTWARE AND DOCUMENTATION ARE PROVIDED ?AS IS? WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION,
ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS
FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROCHIP, TREVOR VAN DER
LINDEN, OR THEIR LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR
OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR
EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL,
INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST
DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES,
OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY
DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
*********************************************************************/
//DOM-IGNORE-END

// ******************************************************************
// ******************************************************************
// Section: Includes
// ******************************************************************
// ******************************************************************
#include <GenericTypeDefs.h>
#include <plib.h>

// ******************************************************************
// ******************************************************************
// Section: Configuration bits
// ******************************************************************
// ******************************************************************
#pragma config FPLLODIV = DIV_1, FPLLMUL = MUL_20, FPLLIDIV = DIV_2,\
                FWDTEN = OFF, FCKSM = CSECME, FPBDIV = DIV_1
#pragma config OSCIOFNC = ON, POSCMOD = XT, FSOSCEN = ON,\
                FNOSC = PRIPLL
#pragma config CP = OFF, BWP = OFF, PWP = OFF

// ******************************************************************
// ******************************************************************
// Section: System Macros
// ******************************************************************
// ******************************************************************
#define	GetSystemClock()      (80000000ul)
#define	GetPeripheralClock()  (GetSystemClock()/(1 << OSCCONbits.PBDIV))
#define	GetInstructionClock() (GetSystemClock())

// ******************************************************************
// ******************************************************************
// Section: Function Prototypes
// ******************************************************************
// ******************************************************************
BOOL BufferCompare(char *buffer, UINT32 size,\
                    const unsigned char *compareto,\
                    UINT32 expectedSize);
void SendDataBuffer(UART_MODULE id, const char *buffer, UINT32 size);
UINT32 GetMenuChoice(UART_MODULE id);
UINT32 GetDataBuffer(UART_MODULE id, char *buffer, UINT32 max_size);
// ******************************************************************
// ******************************************************************
// Section: Constant Data
// ******************************************************************
// ******************************************************************
const char mainMenu[] =
{
    "Welcome to PIC32 UART Peripheral Library Demo! (Trevor's mods)\r\n"\
    "Here are the main menu choices\r\n"\
    "1. View Actual BAUD rate\r\n"\
    "2. Use AUTOBAUD\r\n"\
    "3. Set Line Control\r\n"\
    "4. ECHO\r\n"
    "\r\n\r\nPlease Choose a number\r\n"
};
const char lineMenu[] =
{
  "Line Control Menu\r\n"\
  "You may need to change the line control on the terminal to see data\r\n"\
  "1. 8-N-1\r\n"\
  "2. 8-E-1\r\n"\
  "3. 8-O-1\r\n"\
  "4. 8-N-2\r\n"\
  "5. 8-E-2\r\n"\
  "6. 8-O-2\r\n"\
  "\r\n\r\nPlease Choose a number\r\n"
};
const UINT32 lineControl[] =
{
    (UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1),
    (UART_DATA_SIZE_8_BITS | UART_PARITY_EVEN | UART_STOP_BITS_1),
    (UART_DATA_SIZE_8_BITS | UART_PARITY_ODD | UART_STOP_BITS_1),
    (UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_2),
    (UART_DATA_SIZE_8_BITS | UART_PARITY_EVEN | UART_STOP_BITS_2),
    (UART_DATA_SIZE_8_BITS | UART_PARITY_ODD | UART_STOP_BITS_2)
};
const unsigned char response[] = {"AOK"};

const UART_MODULE monitorUART = UART1;
const UART_MODULE WiFlyUART = UART2;
const UART_MODULE gpsUART = UART3;


// ******************************************************************
// Section: Code
// ******************************************************************
// ******************************************************************

// ******************************************************************
// int main(void)
// ******************************************************************
int main(void)
{
    UINT32  menu_choice;
    UINT8   buf[1024];

    UARTConfigure(monitorUART, UART_ENABLE_PINS_TX_RX_ONLY);
    UARTSetFifoMode(monitorUART, UART_INTERRUPT_ON_TX_NOT_FULL\
            | UART_INTERRUPT_ON_RX_NOT_EMPTY);
    UARTSetLineControl(monitorUART, UART_DATA_SIZE_8_BITS\
            | UART_PARITY_NONE\
            | UART_STOP_BITS_1);
    UARTSetDataRate(monitorUART, GetPeripheralClock(), 115200);
    UARTEnable(monitorUART, UART_ENABLE_FLAGS(UART_PERIPHERAL\
            | UART_RX |\
            UART_TX));

    SendDataBuffer(monitorUART, mainMenu, sizeof(mainMenu));

    while(1)
    {
        menu_choice = GetMenuChoice(monitorUART);

        switch(menu_choice)
        {
        case 1:
            sprintf(buf, "Actual Baud Rate: %ld\r\n\r\n",\
                 UARTGetDataRate(monitorUART, GetPeripheralClock()));
            SendDataBuffer(monitorUART, buf, strlen(buf));
            break;
        
        case 2:
            SendDataBuffer(monitorUART,\
               "Press 'U' to allow AUTO BAUD to sync\r\n",\
               strlen("Press 'U' to allow AUTO BAUD to sync\r\n"));
            
            UARTStartAutoDataRateDetect(monitorUART);

            while(!UARTDataRateDetected(monitorUART))
                ;

            sprintf(buf, "Actual Baud Rate: %ld\r\n\r\n",\
                 UARTGetDataRate(monitorUART, GetPeripheralClock()));
            SendDataBuffer(monitorUART, buf, strlen(buf));
            break;

        case 3:
            SendDataBuffer(monitorUART, lineMenu, sizeof(lineMenu));
            menu_choice = GetMenuChoice(monitorUART);
            menu_choice--;

            if(menu_choice >= 6)
            {
                SendDataBuffer(monitorUART, "Invalid Choice",\
                        sizeof("Invalid Choice"));
                SendDataBuffer(monitorUART, mainMenu,\
                        sizeof(mainMenu));
                break;
            }

            SendDataBuffer(monitorUART,\
  "Press Any Character after re-configuring you terminal\r\n",\
  strlen("Press Any Character after re-configuring you terminal\r\n"));
            UARTSetLineControl(monitorUART, lineControl[menu_choice]);

            menu_choice = GetMenuChoice(monitorUART);
            SendDataBuffer(monitorUART, mainMenu, sizeof(mainMenu));
           break;
            
        case 4:
            {
                UINT32 rx_size;
                unsigned char s[1024];
                BOOL strcorrect;
                SendDataBuffer(monitorUART,\
"Type a message (less than 100 characters) and press return\r\n",\
strlen("Type a message (less than 100 characters) and press return\r\n"));
                
                rx_size = GetDataBuffer(monitorUART, buf, 1024);
                strcorrect = BufferCompare(buf, rx_size,\
                        "AOK", sizeof("AOK") - 1);  // dont count the \0
                if(strcorrect == TRUE)
                {
                    SendDataBuffer(monitorUART,\
                        "recieved expected response\r\n\r\n",\
                        strlen("recieved expected response\r\n\r\n"));
                }
                else
                {
                    SendDataBuffer(monitorUART,\
                            "You Typed:\r\n\r\n",\
                            strlen("You Typed:\r\n\r\n"));
                    SendDataBuffer(monitorUART, buf, rx_size);
                }
                SendDataBuffer(monitorUART,\
                   "\r\n\r\nPress any key to continue\r\n\r\n",\
                   strlen("\r\n\r\nPress any key to continue\r\n\r\n"));
                GetMenuChoice(monitorUART);
            }
            break;

        default:
            SendDataBuffer(monitorUART, mainMenu, sizeof(mainMenu));

        }
    }

    return -1;
}

/********************************************************************
BOOL BufferCompare(\
        char *buffer,UINT32 size,\
        char *compareto,\
        UINT32 expectedSize)
 Inputs:
 * buffer - the buffer containing the data returned from the UART
 * size - the number of charachters that the UART returned in buffer
 * compareto - char array of the characters to compare buffer to
 * expected size - the number of characters in compareto excluding
        any \0 chars
 Returns:
 * Boolean - True if the two are the same, otherwise false.
 SPECIAL NOTE:
 * The contents of the buffer coming from the UART is not a 
    traditional null terminated string (does not have a \0 as
    a terminating char. For this reason you need to provide the
    size and expectedSize variables so the function knows how
    many characters from the start of buffer to compare.

********************************************************************/
BOOL BufferCompare(char *buffer,\
        UINT32 size,\
        const unsigned char *compareto,\
        UINT32 expectedSize)
{
    UINT8 i;
    BOOL same;
    same = FALSE;                   // 1st default to false
    if(size == expectedSize)   // check to see if the size is the same
    {
        same = TRUE;                // default to true
        for (i=0;i<=size-1;i++)
        {
            if(buffer[i] != compareto[i])   // compare
            {
                same = FALSE;       // if not the same, set to false
            }
        }
    }
    return same;                    // return result.
}
// ******************************************************************
// void UARTTxBuffer(UART_MODULE id, char *buffer, UINT32 size)
// ******************************************************************
void SendDataBuffer(UART_MODULE id, const char *buffer, UINT32 size)
{
    while(size)
    {
        while(!UARTTransmitterIsReady(id))
            ;
        UARTSendDataByte(id, *buffer);
        buffer++;
        size--;
    }
    while(!UARTTransmissionHasCompleted(id))
        ;
}
// *******************************************************************
// UINT32 GetDataBuffer(UART_MODULE id, char *buffer, UINT32 max_size)
// *******************************************************************
UINT32 GetDataBuffer(UART_MODULE id, char *buffer, UINT32 max_size)
{
    UINT32 num_char;

    num_char = 0;

    while(num_char < max_size)
    {
        UINT8 character;

        while(!UARTReceivedDataIsAvailable(id))
            ;
        character = UARTGetDataByte(id);
        if(character == '\r')
            break;
        *buffer = character;
        buffer++;
        num_char++;
    }

    return num_char;
}
// *******************************************************************
// UINT32 GetMenuChoice(UART_MODULE id)
// *******************************************************************
UINT32 GetMenuChoice(UART_MODULE id)
{
    UINT8  menu_item;

    while(!UARTReceivedDataIsAvailable(id))
        ;
    menu_item = UARTGetDataByte(id);
    menu_item -= '0';

    return (UINT32)menu_item;
}