/*
    FreeRTOS MCF5235 port - Copyright (C) 2006 Christian Walter.

    This file is part of the FreeRTOS distribution.

    FreeRTOS is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License** as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    FreeRTOS is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with FreeRTOS; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    A special exception to the GPL can be applied should you wish to distribute
    a combined work that includes FreeRTOS, without being obliged to provide
    the source code for any proprietary components.  See the licensing section
    of http://www.FreeRTOS.org for full details of how and when the exception
    can be applied.

    ***************************************************************************
    ***************************************************************************
    *                                                                         *
    * Get the FreeRTOS eBook!  See http://www.FreeRTOS.org/Documentation      *
	*                                                                         *
	* This is a concise, step by step, 'hands on' guide that describes both   *
	* general multitasking concepts and FreeRTOS specifics. It presents and   *
	* explains numerous examples that are written using the FreeRTOS API.     *
	* Full source code for all the examples is provided in an accompanying    *
	* .zip file.                                                              *
    *                                                                         *
    ***************************************************************************
    ***************************************************************************

	Please ensure to read the configuration and relevant port sections of the
	online documentation.

	http://www.FreeRTOS.org - Documentation, latest information, license and 
	contact details.

	http://www.SafeRTOS.com - A version that is certified for use in safety 
	critical systems.

	http://www.OpenRTOS.com - Commercial support, development, porting, 
	licensing and training services.
*/

/* ------------------------ MCF523x includes ------------------------------ */
#include "mcf5xxx.h"
#include "mcf523x.h"

/* ------------------------ FreeRTOS includes ----------------------------- */
#include "FreeRTOS.h"
#include "queue.h"
#include "task.h"

#include "serial.h"

/* ----------------------- Defines ----------------------------------------- */
#define BAUDRATE_VALUE(fsys, baud)      ( ( fsys )/(32UL * baud) )
#define MCF_UART_VECTOR                 ( 64 + 13 )
#define COM_NIFACE                      1
#define COM_BLOCK_RETRYTIME             10

/* ------------------------ Static functions ------------------------------ */
static void     prvSerialISR( void );

/* ------------------------ Static variables ------------------------------ */
typedef struct
{
    portBASE_TYPE xInitialized;
    xQueueHandle xRXChars;
    xQueueHandle xTXChars;
} xComPortIF_t;

static xComPortIF_t xComPortIF[ COM_NIFACE ];

/* ------------------------ Begin implementation -------------------------- */
xComPortHandle
xSerialPortInitMinimal( unsigned portLONG ulWantedBaud,
                        unsigned portBASE_TYPE uxQueueLength )
{
    extern void     ( *__RAMVEC[] ) (  );
    xComPortHandle xReturn;
    portBASE_TYPE xOldIPL;

    /* Create the queues used to hold Rx and Tx characters. */
    xComPortIF[ 0 ].xRXChars =
        xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE )sizeof( signed portCHAR ) );
    xComPortIF[ 0 ].xTXChars =
        xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE )sizeof( signed portCHAR ) );

    /* If the queues were created correctly then setup the serial port hardware. */
    if( ( xComPortIF[ 0 ].xRXChars != 0 ) && ( xComPortIF[ 0 ].xTXChars != 0 ) )
    {
        xOldIPL = portSET_IPL( portIPL_MAX );

        /* UART 0: Reset transmitter, receiver and mode register pointer */
        MCF_UART_UCR0 = MCF_UART_UCR_MISC( 0x3 );
        MCF_UART_UCR0 = MCF_UART_UCR_MISC( 0x2 );
        MCF_UART_UCR0 = MCF_UART_UCR_MISC( 0x1 );

        /* Enable receive interrupts. */
        MCF_UART_UIMR0 = MCF_UART_UIMR_RXRDY_FU;

        /* 8 Databits, 1 Stopbit and no parity */
        MCF_UART_UMR0 = MCF_UART_UMR_PM( 0x3 ) | MCF_UART_UMR_SB( 0x7 ) | MCF_UART_UMR_BC( 0x3 );

        /* UART 0 Clocking */
        MCF_UART_UCSR0 = MCF_UART_UCSR_RCS( 0xd ) | MCF_UART_UCSR_TCS( 0xd );
        MCF_UART_UBG10 = BAUDRATE_VALUE( FSYS_2, ulWantedBaud ) >> 8U;
        MCF_UART_UBG20 = BAUDRATE_VALUE( FSYS_2, ulWantedBaud ) & 0xFFU;

        /* UART 0: Enable interrupts */
        __RAMVEC[MCF_UART_VECTOR] = prvSerialISR;
        MCF_INTC0_ICR13 = MCF_INTC0_ICRn_IL( 0x2 ) | MCF_INTC0_ICRn_IP( 0x1 );
        MCF_INTC0_IMRL &= ~MCF_INTC0_IMRL_INT_MASK13;

        /* UART 0 Miscellaneous */
        MCF_UART_UACR0 = 0;

        /* UART 0: Enable pins */
        MCF_GPIO_PAR_UART = MCF_GPIO_PAR_UART_PAR_U0RXD | MCF_GPIO_PAR_UART_PAR_U0TXD;

        /* Enable the UART. */
        MCF_UART_UCR0 = MCF_UART_UCR_RXC( 0x1 ) | MCF_UART_UCR_TXC( 0x1 );

        xComPortIF[ 0 ].xInitialized = TRUE;
        xReturn = ( xComPortHandle ) &xComPortIF[ 0 ];

        ( void )portSET_IPL( xOldIPL );
    }
    else
    {
        xReturn = ( xComPortHandle ) 0;
    }

    return xReturn;
}

signed          portBASE_TYPE
xSerialGetChar( xComPortHandle pxPort, signed portCHAR * pcRxedChar,
                portTickType xBlockTime )
{
    int i;
    portBASE_TYPE xResult = pdFALSE;
    /* Lookup the correct interface. */
    for( i = 0; i < COM_NIFACE; i++ )
    {
        if( pxPort == ( xComPortHandle ) &xComPortIF[ i ] )
        {
            break;
        }
    }
    /* This COM port is available. */
    if( ( i != COM_NIFACE ) && xComPortIF[ i ].xInitialized )
    {
        /* Get the next character from the buffer.  Return false if no characters
         * are available, or arrive before xBlockTime expires.
         */
        if( xQueueReceive( xComPortIF[ i ].xRXChars, pcRxedChar, xBlockTime ) )
        {
            xResult = pdTRUE;
        }
    }
    return xResult;
}

void
vSerialPutString( xComPortHandle pxPort, const signed portCHAR *
                  const pcString, unsigned portSHORT usStringLength )
{
    int i;
    signed portCHAR *pChNext;

    /* Send each character in the string, one at a time. */
    pChNext = ( signed portCHAR * )pcString;
    for( i = 0; i < usStringLength; i++ )
    {
        /* Block until character has been transmitted. */
        while( xSerialPutChar( pxPort, *pChNext, COM_BLOCK_RETRYTIME ) != pdTRUE ); pChNext++;
    }
}

signed          portBASE_TYPE
xSerialPutChar( xComPortHandle pxPort, signed portCHAR cOutChar,
                portTickType xBlockTime )
{
    int i;
    portBASE_TYPE xResult = pdFALSE;
    portBASE_TYPE xOldIPL;
    /* Lookup the correct interface. */
    for( i = 0; i < COM_NIFACE; i++ )
    {
        if( pxPort == ( xComPortHandle ) &xComPortIF[ i ] )
        {
            break;
        }
    }
    /* This COM port is available. */
    if( ( i != COM_NIFACE ) && xComPortIF[ i ].xInitialized )
    {
        /* Place the character in the queue of characters to be transmitted. */
        if( xQueueSend( xComPortIF[ i ].xTXChars, &cOutChar, xBlockTime ) == pdPASS )
        {
            /* Turn on the Tx interrupt so the ISR will remove the character from the
             * queue and send it. */
            MCF_UART_UIMR0 = MCF_UART_UIMR_TXRDY | MCF_UART_UIMR_RXRDY_FU;
            xResult = pdTRUE;
        }
    }
    return xResult;
}

signed          portBASE_TYPE
xSerialPutCharNOISR( xComPortHandle pxPort, signed portCHAR cOutChar )
{
    int i;
    portBASE_TYPE xResult = pdFALSE;
    portBASE_TYPE xOldIPL = portSET_IPL( portIPL_MAX );
    /* Lookup the correct interface. */
    for( i = 0; i < COM_NIFACE; i++ )
    {
        if( pxPort == ( xComPortHandle ) &xComPortIF[ i ] )
        {
            break;
        }
    }
    /* This COM port is available. Support for this only available for COM1 right now. */
    if( ( i != COM_NIFACE ) && ( i == 0 ) )
    {
        /* Wait until the transmit buffer is ready. */
        while( !( MCF_UART_USR0 & MCF_UART_USR_TXRDY ) );
        /* Place the character in the transmit buffer. */
        MCF_UART_UTB0 = cOutChar;
        xResult = pdTRUE;
    }
    ( void )portSET_IPL( xOldIPL );
    return xResult;
}

void
vSerialPutStringNOISR( xComPortHandle pxPort, const signed portCHAR *
                       const pcString, unsigned portSHORT usStringLength )
{
    int i;
    signed portCHAR *pChNext;
    portBASE_TYPE xOldIPL = portSET_IPL( portIPL_MAX );

    /* Send each character in the string, one at a time. */
    pChNext = ( signed portCHAR * )pcString;
    for( i = 0; i < usStringLength; i++ )
    {
        /* Block until character has been transmitted. */
        while( xSerialPutCharNOISR( pxPort, *pChNext ) != pdTRUE );
        pChNext++;
    }
    ( void )portSET_IPL( xOldIPL );
}

void
vSerialClose( xComPortHandle xPort )
{
    /* Not supported as not required by the demo application. */
}

void
prvSerialISR( void )
{
    static signed portCHAR cChar;
    static portBASE_TYPE xHigherPriorityTaskWoken;

    /* We have to remvoe the effect of the GCC. Please note that the
     * __attribute__ ((interrupt_handler)) does not work here because we
     * have to do the storing of the registers ourself. Another problem
     * is the usage of a frame pointer which is unlinked on entry.
     */
#if _GCC_USES_FP == 1
    asm volatile ( "unlk %fp\n\t" );
#endif
    /* This ISR can cause a context switch, so the first statement must be
     * a call to the portENTER_SWITCHING_ISR() macro. This must be BEFORE any
     * variable declarations.
     */
    portENTER_SWITCHING_ISR();
	xHigherPriorityTaskWoken = pdFALSE;

    /* Ready to send a character from the buffer. */
    if( MCF_UART_USR0 & MCF_UART_USR_TXRDY )
    {
        /* Transmit buffer is ready. Test if there are characters available. */
        if( xQueueReceiveFromISR( xComPortIF[ 0 ].xTXChars, &cChar, &xHigherPriorityTaskWoken ) ==
            pdTRUE )
        {
            /* A character was retrieved from the queue so can be sent. */
            MCF_UART_UTB0 = cChar;
        }
        else
        {
            /* Leave only receiver enabled. */
            MCF_UART_UIMR0 = MCF_UART_UIMR_RXRDY_FU;
        }
    }
    if( MCF_UART_USR0 & MCF_UART_USR_RXRDY )
    {
        cChar = MCF_UART_URB0;
        xQueueSendFromISR( xComPortIF[ 0].xRXChars, &cChar, &xHigherPriorityTaskWoken );
    }
    /* Exit the ISR.  If a task was woken by either a character being
     * or transmitted then a context switch will occur.
     */
    portEXIT_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
