/** ###################################################################
 **     THIS COMPONENT MODULE IS GENERATED BY THE TOOL. DO NOT MODIFY IT.
 **     Filename  : uart0.C
 **     Project   : ProcessorExpert
 **     Processor : MCF52233CAF60
 **     Component : AsynchroSerial
 **     Version   : Component 02.482, Driver 01.02, CPU db: 3.00.000
 **     Compiler  : CodeWarrior MCF C Compiler
 **     Date/Time : 26. 3. 2010, 17:30
 **     Abstract  :
 **         This component "AsynchroSerial" implements an asynchronous serial
 **         communication. The component supports different settings of
 **         parity, word width, stop-bit and communication speed,
 **         user can select interrupt or polling handler.
 **         Communication speed can be changed also in runtime.
 **         The component requires one on-chip asynchronous serial channel.
 **     Settings  :
 **         Serial channel              : UART0
 **
 **         Protocol
 **             Init baud rate          : 36000_0baud
 **             Width                   : 8 bits
 **             Stop bits               : 1.000
 **             Parity                  : none
 **             Breaks                  : Disabled
 **             Input buffer size       : 25
 **             Output buffer size      : 25
 **
 **         Registers
 **             Input buffer            : URB1      [0x020C]
 **             Output buffer           : UTB1      [0x020C]
 **             Control register        : UMR10     [0x0200]
 **             Mode register           : UMR20     [0x0200]
 **             Baud setting reg.       : UCSR0     [0x0204]
 **
 **         Input interrupt
 **             Vector name             : INT_UART0
 **             Priority                : 430
 **
 **         Output interrupt
 **             Vector name             : INT_UART0
 **             Priority                : 430
 **
 **         Used pins:
 **         ----------------------------------------------------------
 **           Function | On package           |    Name
 **         ----------------------------------------------------------
 **            Input   |     21               |  URXD0_FEC_RXD0_PUA1
 **            Output  |     22               |  UTXD0_FEC_CRS_PUA0
 **         ----------------------------------------------------------
 **
 **
 **
 **     Contents  :
 **         RecvChar - byte uart0_RecvChar(uart0_TComData *Chr);
 **         SendChar - byte uart0_SendChar(uart0_TComData Chr);
 **
 **     Copyright : 1997 - 2010 Freescale Semiconductor, Inc. All Rights Reserved.
 **
 **     http      : www.freescale.com
 **     mail      : support@freescale.com
 ** ###################################################################*/

/* MODULE uart1. */

#include "uart1.h"

#define OVERRUN_ERR      0x01          /* Overrun error flag bit    */
#define FRAMING_ERR      0x02          /* Framing error flag bit    */
#define PARITY_ERR       0x04          /* Parity error flag bit     */
#define CHAR_IN_RX       0x08          /* Char is in RX buffer      */
#define FULL_TX          0x10          /* Full transmit buffer      */
#define RUNINT_FROM_TX   0x20          /* Interrupt is in progress  */
#define FULL_RX          0x40          /* Full receive buffer       */
#define ENABLED_TX_INT   0x80          /* TX interrupt enabled      */
#define BREAK_ERR        0x0200        /* Break detect              */
#define COMMON_ERR       0x0800        /* Common error of RX       */

static volatile word SerFlag; /* Flags for serial communication */
/* Bits: 0 - OverRun error */
/*       1 - Framing error */
/*       2 - Parity error */
/*       3 - Char in RX buffer */
/*       4 - Full TX buffer */
/*       5 - Running int from TX */
/*       6 - Full RX buffer */
/*       7 - TX interrupt enabled */
/*       8 - Unused  */
/*       9 - Break detected  */
/*      10 - Unused */
/*      11 - Unused */
volatile word uart1_InpLen; /* Length of input buffer's content */
static volatile uart1_TComData *InpPtrR; /* Pointer for reading from input buffer */
static volatile uart1_TComData *InpPtrW; /* Pointer for writing to input buffer */
static volatile uart1_TComData InpBuffer[uart1_INP_BUF_SIZE]; /* Input buffer for serial commmunication */
volatile word uart1_OutLen; /* Length of output bufer's content */
static volatile uart1_TComData *OutPtrR; /* Pointer for reading from output buffer */
static volatile uart1_TComData *OutPtrW; /* Pointer for writing to output buffer */
static volatile uart1_TComData OutBuffer[uart1_OUT_BUF_SIZE]; /* Output buffer for serial commmunication */

/*
 ** ===================================================================
 **     Method      :  HWEnDi (component AsynchroSerial)
 **
 **     Description :
 **         Enables or disables the peripheral(s) associated with the
 **         component. The method is called automatically as a part of the
 **         Enable and Disable methods and several internal methods.
 **         This method is internal. It is used by Processor Expert only.
 ** ===================================================================
 */
static void HWEnDi_uart1(void) {
	  setReg8(UCR1, (UCR1_TC0_BITMASK | UCR1_RC0_BITMASK)); /* Enable receiver and transmitter */
	  setReg8(UIMR1, 0x02);                /* Enable receiver interrupt */
}

/*
 ** ===================================================================
 **     Method      :  uart1_RecvChar (component AsynchroSerial)
 **
 **     Description :
 **         If any data is received, this method returns one character,
 **         otherwise it returns an error code (it does not wait for
 **         data). This method is enabled only if the receiver property
 **         is enabled.
 **         [Note:] Because the preferred method to handle error and
 **         break exception in the interrupt mode is to use events
 **         <OnError> and <OnBreak> the return value ERR_RXEMPTY has
 **         higher priority than other error codes. As a consequence the
 **         information about an exception in interrupt mode is returned
 **         only if there is a valid character ready to be read.
 **     Parameters  :
 **         NAME            - DESCRIPTION
 **       * Chr             - Pointer to a received character
 **     Returns     :
 **         ---             - Error code, possible codes:
 **                           ERR_OK - OK
 **                           ERR_SPEED - This device does not work in
 **                           the active speed mode
 **                           ERR_RXEMPTY - No data in receiver
 **                           ERR_BREAK - Break character is detected
 **                           (only when the <Interrupt service> property
 **                           is disabled and the <Break signal> property
 **                           is enabled)
 **                           ERR_COMMON - common error occurred (the
 **                           <GetError> method can be used for error
 **                           specification)
 ** ===================================================================
 */
byte uart1_RecvChar(uart1_TComData *Chr) {
	register byte Result = ERR_OK; /* Return error code */

	if (uart1_InpLen > 0x00) { /* Is number of received chars greater than 0? */
		EnterCritical(); /* Disable global interrupts */
		uart1_InpLen--; /* Decrease number of received chars */
		*Chr = *(InpPtrR++); /* Received char */
		if (InpPtrR >= (InpBuffer + uart1_INP_BUF_SIZE)) { /* Is the pointer out of the receive buffer? */
			InpPtrR = InpBuffer; /* Set pointer to the first item into the receive buffer */
		}
		Result
				= (byte) ((SerFlag & (OVERRUN_ERR | COMMON_ERR | FULL_RX)) ? ERR_COMMON
						: ERR_OK);
		SerFlag &= ~(OVERRUN_ERR | COMMON_ERR | FULL_RX | CHAR_IN_RX); /* Clear all errors in the status variable */
		ExitCritical(); /* Enable global interrupts */
	} else {
		return ERR_RXEMPTY; /* Receiver is empty */
	}
	return Result; /* Return error code */
}
/*
 ** ===================================================================
 **     Method      :  uart1_RecvBlock (component AsynchroSerial)
 **
 **     Description :
 **         If any data is received, this method returns the block of
 **         the data and its length (and incidental error), otherwise it
 **         returns an error code (it does not wait for data).
 **         This method is available only if non-zero length of the
 **         input buffer is defined and the receiver property is enabled.
 **         If less than requested number of characters is received only
 **         the available data is copied from the receive buffer to the
 **         user specified destination. The value ERR_EXEMPTY is
 **         returned and the value of variable pointed by the Rcv
 **         parameter is set to the number of received characters.
 **     Parameters  :
 **         NAME            - DESCRIPTION
 **       * Ptr             - Pointer to the block of received data
 **         Size            - Size of the block
 **       * Rcv             - Pointer to real number of the received data
 **     Returns     :
 **         ---             - Error code, possible codes:
 **                           ERR_OK - OK
 **                           ERR_SPEED - This device does not work in
 **                           the active speed mode
 **                           ERR_RXEMPTY - The receive buffer didn't
 **                           contain the requested number of data. Only
 **                           available data has been returned.
 **                           ERR_COMMON - common error occurred (the
 **                           GetError method can be used for error
 **                           specification)
 ** ===================================================================
 */
byte uart1_RecvBlock(uart1_TComData *Ptr, word Size, word *Rcv, portLONG blockTime) {
	register word count; /* Number of received chars */
	register byte result = ERR_OK; /* Last error */

	for (count = 0; count < Size; count++) {

		xSemaphoreTake(uart1_Mutex.getCharMutex,blockTime);
		switch (uart1_RecvChar(Ptr++)) {
		case ERR_RXEMPTY:
			if (result == ERR_OK) {
				result = ERR_RXEMPTY;
			}
			*Rcv = count; /* Return number of received chars */
			return result;
			break;
		case ERR_COMMON:
			result = ERR_COMMON; /* Return the info that an error was detected */
			break;
		default:
			break;
		}
	}
	*Rcv = count; /* Return number of received chars */
	return result; /* Return last error code */
}
/*
 ** ===================================================================
 **     Method      :  uart1_ClearRxBuf (component AsynchroSerial)
 **
 **     Description :
 **         Clears the receive buffer.
 **         This method is available only if non-zero length of the
 **         input buffer is defined and the receiver property is enabled.
 **     Parameters  : None
 **     Returns     :
 **         ---             - Error code, possible codes:
 **                           ERR_OK - OK
 **                           ERR_SPEED - This device does not work in
 **                           the active speed mode
 ** ===================================================================
 */
byte uart1_ClearRxBuf(void) {
	EnterCritical(); /* Disable global interrupts */
	uart1_InpLen = 0x00; /* Set number of chars in the transmit buffer to 0 */
	InpPtrR = InpPtrW = InpBuffer; /* Set pointers on the first item in the transmit buffer */
	ExitCritical(); /* Enable global interrupts */
	return ERR_OK; /* OK */
}

/*
 ** ===================================================================
 **     Method      :  uart1_ClearTxBuf (component AsynchroSerial)
 **
 **     Description :
 **         Clears the transmit buffer.
 **         This method is available only if non-zero length of the
 **         output buffer is defined and the receiver property is
 **         enabled.
 **     Parameters  : None
 **     Returns     :
 **         ---             - Error code, possible codes:
 **                           ERR_OK - OK
 **                           ERR_SPEED - This device does not work in
 **                           the active speed mode
 ** ===================================================================
 */
byte uart1_ClearTxBuf(void) {
	EnterCritical(); /* Disable global interrupts */
	uart1_OutLen = 0x00; /* Set number of chars in the receive buffer to 0 */
	OutPtrR = OutPtrW = OutBuffer; /* Set pointers on the first item in the receive buffer */
	ExitCritical(); /* Enable global interrupts */
	return ERR_OK; /* OK */
}
/*
 ** ===================================================================
 **     Method      :  uart1_SendChar (component AsynchroSerial)
 **
 **     Description :
 **         Sends one character to the channel. If the component is
 **         temporarily disabled (Disable method) SendChar method only
 **         stores data into an output buffer. In case of a zero output
 **         buffer size, only one character can be stored. Enabling the
 **         component (Enable method) starts the transmission of the
 **         stored data. This method is available only if the
 **         transmitter property is enabled.
 **     Parameters  :
 **         NAME            - DESCRIPTION
 **         Chr             - Character to send
 **     Returns     :
 **         ---             - Error code, possible codes:
 **                           ERR_OK - OK
 **                           ERR_SPEED - This device does not work in
 **                           the active speed mode
 **                           ERR_TXFULL - Transmitter is full
 ** ===================================================================
 */
byte uart1_SendChar(uart1_TComData Chr) {
	if (uart1_OutLen == uart1_OUT_BUF_SIZE) { /* Is number of chars in buffer is the same as a size of the transmit buffer */
		//xSemaphoreTake(uart1_Mutex.fullTxBuffer,portMAX_DELAY);
		return ERR_TXFULL; /* If yes then error */
	}
	EnterCritical(); /* Disable global interrupts */
	uart1_OutLen++; /* Increase number of bytes in the transmit buffer */
	*(OutPtrW++) = Chr; /* Store char to buffer */
	if (OutPtrW >= (OutBuffer + uart1_OUT_BUF_SIZE)) { /* Is the pointer out of the transmit buffer */
		OutPtrW = OutBuffer; /* Set pointer to first item in the transmit buffer */
	}
	SerFlag |= ENABLED_TX_INT; /* Set the flag ENABLED_TX_INT */
	setReg8(UIMR1, 0x03); /* Enable transmit interrupt */
	ExitCritical(); /* Enable global interrupts */
	return ERR_OK; /* OK */
}

/*
 ** ===================================================================
 **     Method      :  uart1_InterruptRx (component AsynchroSerial)
 **
 **     Description :
 **         The method services the receive interrupt of the selected
 **         peripheral(s) and eventually invokes the component's event(s).
 **         This method is internal. It is used by Processor Expert only.
 ** ===================================================================
 */
#define ON_ERROR    1
#define ON_FULL_RX  2
#define ON_RX_CHAR  4
static void uart1_InterruptRx(void) {
	register uart1_TComData Data; /* Temporary variable for data */
	register byte OnFlags = 0x00; /* Temporary variable for flags */

	Data = (uart1_TComData) getReg8(URB1); /* Read data from the receiver */
	if (uart1_InpLen < uart1_INP_BUF_SIZE) { /* Is number of bytes in the receive buffer lower than size of buffer? */
		uart1_InpLen++; /* Increse number of chars in the receive buffer */
		*(InpPtrW++) = Data; /* Save received char to the receive buffer */
		if (InpPtrW >= (InpBuffer + uart1_INP_BUF_SIZE)) { /* Is the pointer out of the receive buffer? */
			InpPtrW = InpBuffer; /* Set pointer on the first item into the receive buffer */
		}
		OnFlags |= ON_RX_CHAR; /* Set flag "OnRXChar" */
	} else {
		SerFlag |= FULL_RX; /* If yes then set flag buffer overflow */
	}
	if (OnFlags & ON_RX_CHAR) { /* Is OnRxChar flag set? */
		uart1_OnRxChar(); /* If yes then invoke user event */
	}
}

/*
 ** ===================================================================
 **     Method      :  uart1_InterruptTx (component AsynchroSerial)
 **
 **     Description :
 **         The method services the receive interrupt of the selected
 **         peripheral(s) and eventually invokes the component's event(s).
 **         This method is internal. It is used by Processor Expert only.
 ** ===================================================================
 */
#define ON_FREE_TX  1
#define ON_TX_CHAR  2
static void uart1_InterruptTx(void) {
	register byte OnFlags = 0x00; /* Temporary variable for flags */

	if (SerFlag & RUNINT_FROM_TX) { /* Is flag "running int from TX" set? */
		OnFlags |= ON_TX_CHAR; /* Set flag "OnTxChar" */
	}
	SerFlag &= ~RUNINT_FROM_TX; /* Reset flag "running int from TX" */
	if (uart1_OutLen) { /* Is number of bytes in the transmit buffer greater then 0? */
		uart1_OutLen--; /* Decrease number of chars in the transmit buffer */
		SerFlag |= RUNINT_FROM_TX; /* Set flag "running int from TX"? */
		setReg8(UTB1, (uart1_TComData) * (OutPtrR++)); /* Store char to transmitter register */
		if (OutPtrR >= (OutBuffer + uart1_OUT_BUF_SIZE)) { /* Is the pointer out of the transmit buffer? */
			OutPtrR = OutBuffer; /* Set pointer on the first item into the transmit buffer */
		}
	} else {
		OnFlags |= ON_FREE_TX; /* Set flag "OnFreeTxBuf" */
		SerFlag &= ~ENABLED_TX_INT; /* Clear the flag ENABLED_TX_INT */
		setReg8(UIMR1, 0x02); /* Disable transmit interrupt */
	}
	if (OnFlags & ON_TX_CHAR) { /* Is flag "OnTxChar" set? */
		uart1_OnTxChar(); /* If yes then invoke user event */
	}
	if (OnFlags & ON_FREE_TX) { /* Is flag "OnFreeTxBuf" set? */
		uart1_OnFreeTxBuf(); /* If yes then invoke user event */
	}
}

/*
 ** ===================================================================
 **     Method      :  uart1_Interrupt (component AsynchroSerial)
 **
 **     Description :
 **         This method is internal. It is used by Processor Expert only.
 ** ===================================================================
 */

void __attribute__ ((interrupt)) __cs3_isr_interrupt_78(void) {
	register word StatReg = getReg8(USR1); /* Read status register */

	if (StatReg & (USR1_RB_BITMASK | USR1_OE_BITMASK | USR1_FE_BITMASK
			| USR1_PE_BITMASK)) { /* Is any error flag set? */
		setReg8(UCR1, 0x40); /* Reset error request flags */
		if (StatReg & USR1_RB_BITMASK) { /* Is break detected? */
			SerFlag |= FRAMING_ERR; /* If yes then set the flag */
		}
		if (StatReg & (USR1_OE_BITMASK | USR1_FE_BITMASK | USR1_PE_BITMASK)) { /* Is an error detected? */
			SerFlag |= COMMON_ERR; /* If yes then set an internal flag */
		}
		(void) getReg8(URB1); /* Dummy read of data register - clear RXRDY bit */
		StatReg &= ~USR1_RXRDY_BITMASK; /* Clear the receive data flag to discard the errorneous data */
	}
	if (StatReg & USR1_RXRDY_BITMASK) { /* Is the receiver interrupt flag set? */
		uart1_InterruptRx(); /* If yes, then invoke the internal service routine. This routine is inlined. */
	}
	if (SerFlag & ENABLED_TX_INT) { /* Is the transmitter interrupt enabled? */
		if (StatReg & USR1_TXRDY_BITMASK) { /* Is the transmitter ready? */
			uart1_InterruptTx(); /* If yes, then invoke the internal service routine. This routine is inlined. */
		}
	}
}

/*
 ** ===================================================================
 **     Method      :  uart1_Init (component AsynchroSerial)
 **
 **     Description :
 **         Initializes the associated peripheral(s) and the component
 **         internal variables. The method is called automatically as a
 **         part of the application initialization code.
 **         This method is internal. It is used by Processor Expert only.
 ** ===================================================================
 */
void uart1_Init(void) {
	SerFlag = 0x00; /* Reset flags */
	/* UCR1: ??=0,MISC=3,TC=0,RC=0 */
	setReg8(UCR1, 0x30); /* Reset UART transmitter */
	/* UCR1: ??=0,MISC=2,TC=0,RC=0 */
	setReg8(UCR1, 0x20); /* Reset UART receiver */
	/* UMR11: RXRTS=0,RXIRQ=0,ERR=0,PM=2,PT=0,BC=3 */
	setReg8(UMR11, 0x13); /*  Set the UMR1 register */
	/* UMR21: CM=0,TXRTS=0,TXCTS=0,SB=7 */
	setReg8(UMR21, 0x07); /*  Set the UMR2 register */
	/* UCSR1: RCS=0x0D,TCS=0x0D */
	setReg8(UCSR1, 0xDD);
	uart1_InpLen = 0x00; /* No char in the receive buffer */
	InpPtrW = InpPtrR = InpBuffer; /* Set pointer on the first item in the receive buffer */
	uart1_OutLen = 0x00; /* No char in the transmit buffer */
	OutPtrW = OutPtrR = OutBuffer; /* Set pointer on the first item in the transmit buffer */
	/* UBG11: Divider_MSB=0 */
	setReg8(UBG11, 0x00);
	/* UBG21: Divider_LSB=0x08 */
	setReg8(UBG21, 0x10);//8
	HWEnDi_uart1(); /* Enable/disable device according to status flags */

	uart1_Mutex.getCharMutex = xQueueCreateCountingSemaphore(
			uart1_OUT_BUF_SIZE, 0); /* Vytvorenie semaforu na blokovanie a odblokovanie getChar metod*/
	uart1_Mutex.printfMutex = xQueueCreateMutex();

	if (uart1_Mutex.getCharMutex == NULL)
		asm("halt");
	if (uart1_Mutex.printfMutex == NULL)
		asm("halt");
	/*
	 **>>>>>>>>>>>>>>>>>>>>>>>26.3.2010 21:51:20<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
	 ** TODO:Dorobyt test ci sa vytvoril mutex a a ohlasovanie chyb cez assert
	 **----------------------------------------------------------------------------------
	 */
}

/********************************************************************************************
 * Function: uart1_OnTxChar
 * Arguments: void
 * Return:  void
 * Comment: Event pri poslani jedneho znaku cez UART
 *******************************************************************************************/
void uart1_OnTxChar(void) {

}
/*--END OF FUNCTION: uart1_OnTxChar---------------------------------------------------*/

/*===========================================================================================
 ** Function: uart1_OnRxChar
 ** Arguments: void
 ** Return:  void
 ** Comment: Event pri nacitani jedneho znaku z UARTu
 ===========================================================================================
 */
void uart1_OnRxChar(void) {
	portBASE_TYPE jeZobudenaPrioritnaTaska = pdFALSE;
	//uart1_SendChar('X');
	xSemaphoreGiveFromISR(uart1_Mutex.getCharMutex, &jeZobudenaPrioritnaTaska);

	//if (jeZobudenaPrioritnaTaska == pdTRUE)
	//	vPortYieldHandler(); /* TOTO prepina kontext v ISR !!!!*/
	portEND_SWITCHING_ISR(jeZobudenaPrioritnaTaska);
}
/*--END OF FUNCTION: uart1_OnRxChar---------------------------------------------------*/

/*
 **==========================================================================================
 ** Function: uart1_OnFreeTxBuf
 ** Arguments: void
 ** Return:  void
 ** Comment: Event pri vyprazdneni TX buffra
 **===========================================================================================
 */
void uart1_OnFreeTxBuf(void) {
	//portBASE_TYPE jeZobudenaPrioritnaTaska = pdFALSE;
	//xSemaphoreGiveFromISR(uart1_Mutex.fullTxBuffer,&jeZobudenaPrioritnaTaska);
}
/*--END OF FUNCTION: uart1_OnFreeTxBuf-----------------------------------------------------*/

byte uart1_SendCharCritical(uart1_TComData Chr) {
	if (!testReg8Bit(USR1, TXRDY)) { /* Is the transmitter ready? */
		return ERR_TXFULL; /* If yes then error */
	}
	setReg8(UTB1, Chr); /* Store char to transmitter register */
	return ERR_OK; /* OK */
}

/*
 **==========================================================================================
 ** Function: critical_ERROR_WRITE
 ** Arguments: char*
 ** Return:  return_type
 ** Comment: Vypisanie textu na konzolu bez pouzitia delay_funkcii
 **===========================================================================================
 */
void critical_ERROR_WRITE_uart1(char *data) {
	portDISABLE_INTERRUPTS();
	for (; *data != '\0'; data++) {
		while (uart1_SendCharCritical(*data) != ERR_OK)
			;
	}
	portENABLE_INTERRUPTS();

}

/*--END OF FUNCTION: critical_ERROR_WRITE-----------------------------------------------------*/

/* END uart1. */

/*
 ** ###################################################################
 **
 **     This file was created by Processor Expert 4.00 Beta [04.39]
 **     for the Freescale MCF series of microcontrollers.
 **
 ** ###################################################################
 */
